]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/mcasp/example/src/aic31.c
mcasp-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / mcasp / example / src / aic31.c
1 /*
2  * Aic31.c
3  *
4  * This file contains Driver Layer Interface implementation for Aic3106 codec 
5  * Driver. Aic3106 Codec Driver provides Driver Layer Interface to do operations
6  * on the Aic3106 peripheral like device initialization, channel creation, 
7  * control commands for peripheral specific operations etc
8  *
9  * Copyright (C) 2009-2019 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 /** \file      Aic31.c
43  *
44  *  \brief     Implementation of the IOM for the AIC31 audio codec.
45  *
46  *  This file contains the implementation of the AIC31 audio codec driver for
47  *  DSP BIOS operating system.
48  *
49  *  (C) Copyright 2009, Texas Instruments, Inc
50  */
52 /* ========================================================================== */
53 /*                            INCLUDE FILES                                   */
54 /* ========================================================================== */
55 #define SW_I2C
56 #include <xdc/std.h>
57 #include <ti/sysbios/io/IOM.h>
58 #include <assert.h>
59 #include <string.h>
60 #include <ti/sysbios/knl/Semaphore.h>
61 #include <ti/sysbios/io/GIO.h>
63 #ifndef SW_I2C
64 #include <i2c/include/I2c.h>
65 #else
66 //#include <include/i2c.h>
67 #endif /* SW_I2C */
70 #include <Aic31.h>
71 #include <ICodec.h>
72 #include <Aic31Local.h>
74 #ifdef SW_I2C
75 #include <ti/csl/cslr_device.h>
76 #include <codec_if.h>
77 #include <mcasp_cfg.h>
78 #include <aic31_if.h>
79 #endif /* SW_I2C */
81 #ifdef SW_I2C
82 extern void I2CCodecIsr(void);
83 #endif /* SW_I2C */
85 /* -------- constants -------- */
86 const Aic31_Params Aic31_PARAMS = {
87     ICodec_CodecType_AIC31,         /* acType                 */
88     ICodec_ControlBusType_I2C,      /* acControlBusType       */
89     "NONE",                         /* acCtrlBusName          */
90 #if defined (MCASP_MASTER)
91         ICodec_OpMode_SLAVE,           /* acOpMode               */
92 #else // MCASP is slave
93         ICodec_OpMode_MASTER,           /* acOpMode               */
94 #endif
95 #if defined DSP_MODE
96         ICodec_DataType_DSP,
97         (uint32_t)ICodec_SlotWidth_16,    /* acSlotWidth            */
98 #else
99         ICodec_DataType_I2S,            /* acSerialDataType       */
100         (uint32_t)ICodec_SlotWidth_32,    /* acSlotWidth            */
101 #endif
102     ICodec_DataPath_TXRX,           /* acDataPath             */
103     0,                              /* isRxTxClockIndependent */
104 };
106 /* ========================================================================== */
107 /*                       GLOBAL MODULE STATE                                  */
108 /* ========================================================================== */
109 /**
110  *  \brief  Array which is part of Aic31 Module State
111  */
112 static Bool inUse[AIC31_NUM_INSTANCES];
113 /**
114  *  \brief  Aic31 Module State Object
115  */
116 static Aic31_Module_State Aic31_module = {&inUse[0]};
117 /**
118  *  \brief  Array of Aic31 instance State objects array
119  */
120 static Aic31_Object Aic31_Instances[AIC31_NUM_INSTANCES];
121 /**
122  *  \brief  Array for  per instance device information
123  */
124 Aic31_HwInfo Aic31_deviceInstInfo[AIC31_NUM_INSTANCES];
126 /* ========================================================================== */
127 /*                       Aic31 Local Functions Definitions                    */
128 /* ========================================================================== */
129 /* ========================================================================== */
130 /*                        LOCAL FUNCTION PROTOTYPES                           */
131 /* ========================================================================== */
132  Int aic31MdBindDev(Ptr *devp, Int devId, Ptr devParams);
133  Int aic31MdUnBindDev(Ptr devp);
134  Int aic31MdCreateChan(
135                     Ptr                 *chanp,
136                     Ptr                 devp,
137                     String              name,
138                     Int                 mode,
139                     Ptr                 chanParams,
140                     IOM_TiomCallback    cbFxn,
141                     Ptr                 cbArg
142                     );
143  Int aic31MdDeleteChan(Ptr chanp);
144  Int aic31MdSubmitChan(Ptr chanp, IOM_Packet *ioPacket);
145  Int aic31MdControlChan(Ptr chanp, Uns cmd, Ptr cmdArgs);
148 static Bool aic31I2cWrite(Aic31_Object   *instHandle,
149                           uint32_t          deviceId,
150                           ICodec_RegData *wrRegData);
152 static Bool aic31RegWrite(Aic31_Object *instHandle,
153                           uint8_t         regAddr,
154                           uint8_t         regData);
156 static Bool aic31I2cRead(Aic31_Object   *instHandle,
157                          uint32_t          deviceId,
158                          ICodec_RegData  *rdRegData);
160 static Bool aic31RegRead(Aic31_Object *instHandle,
161                          uint8_t         regAddr,
162                          uint8_t        *regData);
164 static Bool aic31CtrlBusWrite(Aic31_Object  *instHandle,
165                               ICodec_RegData *wrRegData);
167 static Bool aic31CtrlBusRead(Aic31_Object    *instHandle,
168                              ICodec_RegData  *rdRegData);
170 static int32_t aic31MuteConfig(Aic31_Object  *instHandle,
171                              ICodec_Channel  acChannel,
172                              Bool           muteConfig);
174 static int32_t aic31SetSamplingRate(Aic31_Object *instHandle,
175                                   ICodec_Channel acChannel,
176                                   uint32_t        sampleRate);
178 #ifndef SW_I2C
179 static int32_t aic31InitAdc  (Aic31_Object   *instHandle);
181 static int32_t aic31InitDac  (Aic31_Object   *instHandle);
183 static int32_t aic31DeinitAdc(Aic31_Object   *instHandle);
185 static int32_t aic31DeinitDac(Aic31_Object   *instHandle);
187 static Void aic31CallBack (Ptr semHandle, IOM_Packet * ioPacket);
188 #endif /* SW_I2C */
190 static Bool aic31RegWriteBf(Aic31_Object *instHandle,
191                             uint8_t         regAddr,
192                             uint8_t         bfPosition,
193                             uint8_t         bfSize,
194                             uint8_t         bfData);                             
196 static int32_t aic31SelectInputSource(Aic31_Object    *instHandle,
197                                     Ptr              srcOption);
199 static int32_t aic31SelectOutputDest(Aic31_Object    *instHandle,
200                                    Ptr              destOption);
203 /**
204  * \brief IOM function pointer table.
205  *
206  *        This variables is the array of function pointers of all the IOM
207  *        functions implemented by the codec driver.
208  *
209  */
211 const IOM_Fxns Aic31_IOMFXNS =
213     &aic31MdBindDev,
214     &aic31MdUnBindDev,
215     &aic31MdControlChan,
216     &aic31MdCreateChan,
217     &aic31MdDeleteChan,
218     &aic31MdSubmitChan,
219 };
223 /* ========================================================================== */
224 /*                          FUNCTION DEFINTIONS                               */
225 /* ========================================================================== */
226 /**
227  *  \brief  Function called by Bios during instance initialisation
228  *
229  */
230 Void Aic31_init(Void)
232     Int i;
234     for (i = 0; i < AIC31_NUM_INSTANCES; i++)
235     {
236         /* have to initialize statically */
237         Aic31_module.inUse[i] = FALSE;
238         memset((Void *)&Aic31_Instances[i], 0x0, sizeof(Aic31_Object));
239     }
241     Aic31_deviceInstInfo[0].deviceAddress = (uint32_t)AIC31_INST0_ADDRESS;
245 /**
246  *  \brief  Function called by Bios during instance initialisation
247  *
248  *  \param  devp      [OUT]  Pointer to the codec driver object
249  *  \param  devId     [IN]   instance number of the codec
250  *  \param  devParams [IN]   Device parameters passed by the user
251  *
252  *  \return IOM_COMPLETED    if success
253  *          Error ID                 in case of error
254  */
255  Int aic31MdBindDev(Ptr *devp, Int devId, Ptr devParams)
257     int32_t         retVal        = IOM_COMPLETED;
258     Aic31_Params *params        = NULL;
259     uint32_t        count         = 0;
260     Aic31_Object *instHandle    = NULL;
262 /* Begin parameter checking                                                   */
263 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
264     if ((NULL == devp)                  ||
265         (AIC31_NUM_INSTANCES <= devId)  ||
266         (TRUE == Aic31_module.inUse[devId]))
267     {
268         retVal = IOM_EBADARGS;
269     }
270 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
271 /* End parameter checking                                                     */
273     if (IOM_COMPLETED == retVal)
274     {
275         instHandle =  &Aic31_Instances[devId];
277         if (devParams == NULL) 
278         {
279             params = (Aic31_Params*)&Aic31_PARAMS;
280         }
281         else 
282         {
283             params = (Aic31_Params*) devParams;
284         }
286         Aic31_module.inUse[devId] = TRUE;
288         /* copy the initialization parameters                                 */
289         instHandle->acType           = params->acType;
290         instHandle->instNum          = (uint8_t)devId;
291         instHandle->acControlBusType = params->acControlBusType;
292         instHandle->acCtrlBusName    = params->acCtrlBusName;
293         instHandle->acOpMode         = params->acOpMode;
294         instHandle->acSerialDataType = params->acSerialDataType;
295         instHandle->acSlotWidth      = params->acSlotWidth;
296         instHandle->acDataPath       = params->acDataPath;
297         instHandle->isRxTxClockIndependent = params->isRxTxClockIndependent;
298         instHandle->acCodecId = Aic31_deviceInstInfo[devId].deviceAddress;
300 #ifdef SW_I2C
301         instHandle->acCtrlBusInstNum = params->acCtrlBusInstNum;
303         if (instHandle->acControlBusType == ICodec_ControlBusType_I2C)
304         {
305             if (instHandle->acCtrlBusInstNum == 0)
306             {
307                 instHandle->acBaseAddress = SOC_I2C_1_REGS;
308             }
309             else
310             {
311                 retVal = IOM_EBADARGS;
312             }
313         }
314         else
315         {
316             /* Only 'ICodec_ControlBusType_I2C' suppoted currently */
317             retVal = IOM_EBADARGS;
318         }
319 #endif /* SW_I2C */
321         for (count = 0; count < ICodec_Channel_MAX; count++)
322         {
323             /* Set the state of both the channels as closed                   */
324             instHandle->ChanObj[count].chanStatus = ICodec_DriverState_CLOSED;
325             instHandle->ChanObj[count].channelMode = ICodec_Channel_MAX;
326             instHandle->ChanObj[count].samplingRate = 0;
327             instHandle->ChanObj[count].chanGain  = 0;
328             instHandle->ChanObj[count].devHandle = NULL;
329         }
331         instHandle->hCtrlBus = NULL;
332         instHandle->acCtrlBusHandle = NULL;
334         /* set the state of the driver as created                             */
335         instHandle->devState = ICodec_DriverState_CREATED;
336         *devp = instHandle;
337     }
338     else
339     {
340         retVal = IOM_EBADIO;
342         if (NULL != devp)
343         {
344             *devp = NULL;
345         }
346     }
348     return (retVal);
351 /**
352  *  \brief  Function called by Bios during closing of the instance
353  *
354  *  \param  devp [IN] Pointer to the driver instance object.
355  *
356  *  \return None
357  */
359  Int aic31MdUnBindDev(Ptr devp)
361     Aic31_Object       *instHandle  = NULL;
362     int32_t               retVal      = IOM_COMPLETED;
364 /* Begin parameter checking                                                   */
365 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
366     if (NULL == devp)
367     {
368         retVal = IOM_EBADARGS;
369     }
370     else
371     {
372 #endif
373         instHandle = (Aic31_Object *)devp;
374 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
375         if ((NULL == instHandle)                                             ||
376             (AIC31_NUM_INSTANCES <= instHandle->instNum)                     ||
377            (ICodec_DriverState_CREATED != instHandle->devState)              ||
378             (instHandle->ChanObj[0].chanStatus != ICodec_DriverState_CLOSED) ||
379             (instHandle->ChanObj[1].chanStatus != ICodec_DriverState_CLOSED))
380         {
381             retVal = IOM_EBADARGS;
382         }
383     }
384 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
385 /* End parameter checking                                                     */
387     if (IOM_COMPLETED == retVal)
388     {
389         instHandle->devState = ICodec_DriverState_DELETED;
390         Aic31_module.inUse[instHandle->instNum] = FALSE;
391     }
393     return (retVal);
396 /* ========================================================================== */
397 /*                           IOM FUNCTIONS                                    */
398 /* ========================================================================== */
400 /**
401  * \brief     This function configures the RX or TX portion of the Aic31 codec
402  *
403  *  This function internally uses a control bus to configure the codec. The
404  *  control bus could be either SPI or I2c etc.The open function configures the
405  *  DAC and ADC sections of the codec accordingly
406  *
407  * \param     chanp        [OUT]    pointer to Aic31 driver channel handle
408  * \param     devp         [IN]     pointer to Aic31 driver object
409  * \param     name         [IN]     Aic31 Instance name
410  * \param     mode         [IN]     channel  mode -> input or output
411  * \param     chanParams   [IN]     channel parameters from user
412  * \param     cbFxn        [IN]     callback function pointer
413  * \param     cbArg        [IN]     callback function Arguments
414  *
415  * \return    Channel handle if successful
416  *            NULL in case of error
417  */
418  Int aic31MdCreateChan(Ptr             *chanp,
419                              Ptr              devp,
420                              String           name,
421                              Int              mode,
422                              Ptr              chanParams,
423                              IOM_TiomCallback cbFxn,
424                              Ptr              cbArg)
426     Aic31_Object           *instHandle   = NULL;
427     ICodec_ChannelConfig   *acChanConfig = NULL;
428     Aic31_Channel_Object   *chanHandle   = NULL;
429     int32_t                   result       = IOM_COMPLETED;
430 #ifndef SW_I2C
431     String                  remName      = NULL;
432     uint8_t                   tempData     = 0;
433     I2c_ChanParams          i2cChanPrms  = {0};
434     Bool                    retVal       = (Bool)Aic31_REG_WRITE_FAIL;
435     IOM_Fxns                *iomFxns;
436     Ptr                     devicepointer;
437 #endif /* SW_I2C */
440 /* Begin parameter checking                                                   */
441 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
442     if ((NULL == devp)                                          ||
443         (NULL == chanParams)                                    ||
444         ((IOM_INPUT != mode) && (IOM_OUTPUT != mode)))
445     {
446         result = IOM_EBADARGS;
447     }
448     else
449     {
450 #endif
451         instHandle = (Aic31_Object *)devp;
452 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
453         if ((NULL == instHandle) ||
454             (ICodec_DriverState_CREATED != instHandle->devState)    ||
455             (ICodec_DriverState_CLOSED != instHandle->ChanObj[mode-1].chanStatus))
456         {
457             result = IOM_EBADARGS;
458         }
459     }
460 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
461 /* End parameter checking                                                     */
463     /* mode is mode-1 because IOM.h defines input=1; output=2                 */
464     mode = mode -1;
466     /* validate the input parameters and return in case of error              */
467     if (IOM_COMPLETED == result)
468     {
469 #ifdef SW_I2C
471         acChanConfig = (ICodec_ChannelConfig *)chanParams;
473         /* To remove the compiler warning                                     */
474         if ((NULL != cbFxn) && (NULL != cbArg))
475         {
476             cbFxn = cbFxn;
477             cbArg = cbArg;
478         }
480         /* copy the initial parameters to the channel                         */
481         instHandle->ChanObj[mode].samplingRate = acChanConfig->samplingRate;
482         instHandle->ChanObj[mode].chanGain         = acChanConfig->chanGain;
484         /* Configure I2C interface for CODEC */
485         I2CCodecIfInit (instHandle->acBaseAddress, 2, instHandle->acCodecId);
487         /* Configure the Codec for I2S mode */
488         AIC31Reset(instHandle->acBaseAddress);
490         /* Configure the data format and sampling rate */
491         AIC31DataConfig(instHandle->acBaseAddress,
492                         instHandle->acSerialDataType,
493                         instHandle->acSlotWidth,
494                         0);
496         if (instHandle->acDataPath == ICodec_DataPath_TX)
497         {
498             if (ICodec_OpMode_MASTER == instHandle->acOpMode)
499             {
500                 AIC31SampleRateConfig(instHandle->acBaseAddress,
501                                       AIC31_MODE_DAC,
502                                       acChanConfig->samplingRate);
503             }
505             /* Initialize DAC */
506             AIC31DACInit(instHandle->acBaseAddress);
507         }
508         else if (instHandle->acDataPath == ICodec_DataPath_RX)
509         {
510             if (ICodec_OpMode_MASTER == instHandle->acOpMode)
511             {
512                 AIC31SampleRateConfig(instHandle->acBaseAddress,
513                                       AIC31_MODE_ADC,
514                                       acChanConfig->samplingRate);
515             }
517             /* Initialize ADC */
518             AIC31ADCInit(instHandle->acBaseAddress);
519         }
520         else
521         {
522             if (ICodec_OpMode_MASTER == instHandle->acOpMode)
523             {
524                 AIC31SampleRateConfig(instHandle->acBaseAddress,
525                                       AIC31_MODE_BOTH,
526                                       acChanConfig->samplingRate);
527             }
529             /* Do the default configuration for ADC section           */
530             AIC31ADCInit(instHandle->acBaseAddress);
531             /* Do the default initialization for DAC section          */
532             AIC31DACInit(instHandle->acBaseAddress);
533         }
534 #else
535         acChanConfig = (ICodec_ChannelConfig *)chanParams;
537         /* To remove the compiler warning                                     */
538         if ((NULL != cbFxn) && (NULL != cbArg))
539         {
540             cbFxn = cbFxn;
541             cbArg = cbArg;             
542         }
544         /* copy the initial parameters to the channel                         */
545         instHandle->ChanObj[mode].samplingRate = acChanConfig->samplingRate;
546         instHandle->ChanObj[mode].chanGain = acChanConfig->chanGain;
548         /* If either of the Tx or Rx channel is already open, then in this*
549          * function call, there is no need to do any configuration.           */
550         if ((instHandle->ChanObj[0].chanStatus == ICodec_DriverState_CLOSED)
551           &&(instHandle->ChanObj[1].chanStatus == ICodec_DriverState_CLOSED))
552         {
554             Semaphore_construct(&(instHandle->semObj), 0, NULL);
556             /* These variables are not used as no callback is required by     *
557              *  the codec since it does not support the submit call.hence     *
558              *  to remove the warning by compiler of unused variables we      *
559              *  do a dummy assign                                             */
560             if (NULL != name)
561             {
562                 name  = name;
563             }
565             /* we have to open the control bus to the codec so that we can*
566              * use the handle and configure the codec                         */
567             remName = DEV_match(
568                          instHandle->acCtrlBusName,
569                          &instHandle->acCtrlBusHandle);
571             if ((NULL == instHandle->acCtrlBusHandle) || 
572                 (NULL == remName))
573             {
574                 result = IOM_EBADARGS;
575             }
576             else
577             {
578                                 iomFxns                 = DEV_getFxns(instHandle->acCtrlBusHandle);     
579                             devicepointer       = DEV_getDevp(instHandle->acCtrlBusHandle);
580                             
581                 if (ICodec_ControlBusType_I2C == instHandle->acControlBusType)
582                 {
583                     i2cChanPrms.hEdma = NULL;
584                     i2cChanPrms.masterOrSlave = I2c_CommMode_MASTER;
586                     /* driver handle obtained from the name of the device     */
587                     result = ((IOM_Fxns*)iomFxns)-> \
588                              mdCreateChan(
589                                 &instHandle->hCtrlBus,
590                                 devicepointer,
591                                 remName,
592                                 IOM_INOUT,
593                                 &i2cChanPrms,
594                                 &aic31CallBack,
595                                 (Ptr)(&instHandle->semObj));
596                 }
597                 else
598                 {
599                     result = IOM_EBADMODE;
600                 }
602                 if (NULL == instHandle->hCtrlBus)
603                 {
604                     result = IOM_EBADARGS;
605                 }
607             }
609             /* if the control bus was opened sucesfully then we will          *
610              * start the configuration of the codec                           */
611             if (IOM_COMPLETED == result)
612             {
613                 /* Select Register Page 0 of Aic31                            */
614                 retVal = aic31RegWrite(
615                              instHandle,
616                              Aic31_PAGE_SELECT_ADDR,
617                              Aic31_PAGE_0);
619                 /* Reset the Aic31                                            */
620                 retVal |= aic31RegWrite(
621                              instHandle,
622                              Aic31_P0_REG1,
623                              (uint8_t)0x80);
624                 
625                 /* If Aic31 is master mode then set the direction of          *
626                  * the bit clock and word clock as output                     */
627                 if (ICodec_OpMode_MASTER == instHandle->acOpMode)
628                 {
629                     retVal |= aic31RegWriteBf(
630                                   instHandle,
631                                   Aic31_SERIAL_INTERFACEA_ADDR,
632                                   (uint8_t)6,
633                                   (uint8_t)2,
634                                   (uint8_t)3);
635                 }
637                 /* Configure the audio serial data interface mode             */
638                 switch (instHandle->acSerialDataType)
639                 {
640                     case ICodec_DataType_I2S:    tempData = (0u << 6u); break;
641                     case ICodec_DataType_DSP:    tempData = (1u << 6u); break;
642                     case ICodec_DataType_RIGHTJ: tempData = (2u << 6u); break;
643                     case ICodec_DataType_LEFTJ:  tempData = (3u << 6u); break;
644                     default:                     tempData = (0u << 6u); break;
645                 }
647                 /* configure the slot width                                   */
648                 switch (instHandle->acSlotWidth)
649                 {
650                     case ICodec_SlotWidth_16:  tempData |= (0u << 4u); break;
651                     case ICodec_SlotWidth_20:  tempData |= (1u << 4u); break;
652                     case ICodec_SlotWidth_24:  tempData |= (2u << 4u); break;
653                     case ICodec_SlotWidth_32:  tempData |= (3u << 4u); break;
654                     default:  tempData |= (0x00 << 4); break;
655                 }
657                 retVal |= aic31RegWrite(
658                               instHandle,
659                               Aic31_SERIAL_INTERFACEB_ADDR,
660                               tempData);
662                 if (Aic31_REG_WRITE_FAIL == retVal)
663                 {
664                     result = IOM_EBADARGS;
665                 }
666             }
667         }
669         if (IOM_COMPLETED == result)
670         {
671             /* Configure the sampling rate of the audio codec                 */
672             result = aic31SetSamplingRate(
673                          instHandle,
674                          (ICodec_Channel)(mode),
675                          acChanConfig->samplingRate);
677             /* Complete the default initialization for Tx and RX channels     */
678             if (IOM_COMPLETED == result)
679             {
680                 if (ICodec_Channel_INPUT == mode)
681                 {
682                     /* Do the default configuration for ADC section           */
683                     result = aic31InitAdc(instHandle);
684                 }
685                 else
686                 {
687                     /* Do the default initialization for DAC section          */
688                     result = aic31InitDac(instHandle);
689                 }
690             }
691         }
692 #endif /* SW_I2C */
693     }
695     /* Return the result of opening the audio codec                           */
696     if (IOM_COMPLETED == result )
697     {
698         /* The channel creation is successful hence update the handle         */
699         instHandle->ChanObj[mode].chanStatus   = ICodec_DriverState_OPENED;
700         instHandle->ChanObj[mode].channelMode  = (ICodec_Channel)(mode);
701         instHandle->ChanObj[mode].devHandle    = instHandle;
703         chanHandle = &instHandle->ChanObj[mode];
704         *chanp = chanHandle;
705     }
706     else
707     {
708         chanHandle = NULL;
709         *chanp = NULL;
710     }
712     /* Return the channel handle                                              */
713     return (result);
717 /**
718  *  This function executes a control command specified by the application. The
719  *  channel handle obtained after the channel open call should be passed as the
720  *  parameter.
721  *
722  * \param     instHandle   [IN]     Pointer to the Aic31 driver instance object
723  * \param     chanp        [IN]     Handle to the channel
724  * \param     cmd          [IN]     command to be executed
725  * \param     cmdArgs      [IN]     Arguments for the command(if required)
726  * \param     eb           [OUT]    error block
727  *
728  * \return    None
729  */
730  Int aic31MdControlChan(Ptr chanp, Uns cmd, Ptr cmdArgs)
732     Aic31_Object          *instHandle = NULL;
733     Aic31_Channel_Object  *chanHandle = NULL;
734     ICodec_RegData        *wRegPtr    = NULL;
735     Int                    status     = IOM_COMPLETED;
736     uint32_t                 tempVal    = 0;
737     ICodec_CodecData      *codecData  = NULL;
738     Bool                   retVal     = Aic31_REG_WRITE_FAIL;
740 /* Begin parameter checking                                                   */
741 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
742     if (NULL == chanp)
743     {
744         status = IOM_EBADARGS;
745     }
746     else 
747     {
748 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
749         chanHandle = (Aic31_Channel_Object*)chanp;
750         instHandle = (Aic31_Object *)chanHandle->devHandle;
751 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
752         if (NULL == instHandle)
753         {
754             status = IOM_EBADARGS;
755         }
756     }
757 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
758 /* End parameter checking                                                     */
760     if (IOM_COMPLETED == status)
761     {
762         /* Interpret the control command and execute the comnand              */
763         if (Aic31_AC_IOCTL_MUTE_ON == cmd)
764         {
765             status = aic31MuteConfig(instHandle,chanHandle->channelMode,TRUE);
766         }
768         else if (Aic31_AC_IOCTL_MUTE_OFF == cmd)
769         {
770             status = aic31MuteConfig(instHandle,chanHandle->channelMode,FALSE);
771         }
773         else if (Aic31_AC_IOCTL_SET_VOLUME == cmd)
774         {
775             if (NULL != cmdArgs)
776             {
777                 if (ICodec_Channel_OUTPUT == chanHandle->channelMode)
778                 {
779                     /* calculate the actual values to be set depending on the *
780                      * percentage of the values requested                     */
781                     tempVal =
782                         ((*(uint32_t*)cmdArgs) * Aic31_MAX_DAC_GAIN_VALUE)/100u;
784                     tempVal = Aic31_MAX_DAC_GAIN_VALUE - tempVal;
786                     retVal  = aic31RegWriteBf(
787                                  instHandle,
788                                  Aic31_P0_REG43,
789                                  (uint8_t)0,
790                                  (uint8_t)7,
791                                  (uint8_t)tempVal);
793                     retVal |= aic31RegWriteBf(
794                                   instHandle,
795                                   Aic31_P0_REG44,
796                                   (uint8_t)0,
797                                   (uint8_t)7,
798                                   (uint8_t)tempVal);
799                 }
800                 else if (ICodec_Channel_INPUT == chanHandle->channelMode)
801                 {
802                     /* calculate the actual values to be set depending on the *
803                      * percentage of the values requested                     */
804                     tempVal =
805                         ((*(uint32_t*)cmdArgs) * Aic31_MAX_AGC_GAIN_VALUE)/100u;
807                     /* modify the ADC volume                                  */
808                     retVal  = aic31RegWriteBf(
809                                 instHandle,
810                                 Aic31_P0_REG27,
811                                 (uint8_t)1,
812                                 (uint8_t)7,
813                                 (uint8_t)tempVal);
815                     retVal |= aic31RegWriteBf(
816                                 instHandle,
817                                 Aic31_P0_REG30,
818                                 (uint8_t)1,
819                                 (uint8_t)7,
820                                (uint8_t)tempVal);
821                 }
822                 else
823                 {
824                     status = IOM_EBADARGS;
825                 }
827                 if (Aic31_REG_WRITE_PASS != retVal)
828                 {
829                     status = IOM_EBADARGS;
830                 }                
831             }
832             else
833             {
834                 status = IOM_EBADARGS;
835             }
836         }
837         else if (Aic31_AC_IOCTL_SET_LOOPBACK == cmd)
838         {
839             /* Loopback not supported in Aic31                                */
840             status = IOM_ENOTIMPL;
841         }
843         else if (Aic31_AC_IOCTL_SET_SAMPLERATE == cmd)
844         {
845             /* set the sample rate for the codec                              */
846             if (NULL != cmdArgs)
847             {
848                 status = aic31SetSamplingRate(
849                             instHandle,chanHandle->channelMode,
850                             *(uint32_t *)cmdArgs);
851             }
852             else
853             {
854                 status = IOM_EBADARGS;
855             }
856         }
858         else if (Aic31_AC_IOCTL_REG_WRITE == cmd)
859         {
860             /* cmdArgs should be pointer to type ICodec_RegData               */
861             if (NULL != cmdArgs)
862             {
863                 /* Write a single Aic31 registe                               */
864                 wRegPtr = (ICodec_RegData*)cmdArgs;
865                 retVal = aic31RegWrite(
866                             instHandle,
867                             (uint8_t)wRegPtr->regIndex,
868                             *(uint8_t*)(wRegPtr->regData));
869             }
870             else
871             {
872                 status = IOM_EBADARGS;
873             }
875             if (Aic31_REG_WRITE_PASS != retVal)
876             {
877                 status = IOM_EBADARGS;
878             }            
879         }
881         else if (Aic31_AC_IOCTL_REG_WRITE_MULTIPLE == cmd)
882         {
883             /* Write multiple Aic31 register.                                 */
884             /* cmdArgs should be pointer to type ICodec_RegData               */
885             if (NULL != cmdArgs)
886             {
887                 /* Write multiple Aic31 registers                             */
888                 retVal = aic31CtrlBusWrite(
889                             instHandle->hCtrlBus,
890                             (ICodec_RegData *)cmdArgs);
891             }
892             else
893             {
894                 status = IOM_EBADARGS;
895             }
897             if (Aic31_REG_WRITE_PASS != retVal)
898             {
899                 status = IOM_EBADARGS;
900             }
901         }
903         else if (Aic31_AC_IOCTL_REG_READ == cmd)
904         {
905             /* cmdArgs should be pointer to type ICodec_RegData               */
906             if (NULL != cmdArgs)
907             {
908                 /* Write a single Aic31 registe                               */
909                 wRegPtr = (ICodec_RegData*)cmdArgs;
910                 retVal = aic31RegRead(
911                             instHandle,
912                             (uint8_t)wRegPtr->regIndex,
913                             (uint8_t*)(wRegPtr->regData));
914             }
915             else
916             {
917                 status = IOM_EBADARGS;
918             }
920             if (Aic31_REG_WRITE_PASS != retVal)
921             {
922                 status = IOM_EBADARGS;
923             }            
924         }
925         else if (Aic31_AC_IOCTL_REG_READ_MULTIPLE == cmd)
926         {
927             /* Read multiple Aic31 register.                                  */
928             /* cmdArgs should be pointer to type ICodec_RegData               */
929             if (NULL != cmdArgs)
930             {
931                 /* Read multiple Aic31 registers                              */
932                 retVal = aic31CtrlBusRead(
933                             instHandle,
934                             (ICodec_RegData *)cmdArgs);
935             }
936             else
937             {
938                 status = IOM_EBADARGS;
939             }
940             if (Aic31_REG_WRITE_PASS != retVal)
941             {
942                 status = IOM_EBADARGS;
943             }            
944         }
945         else if (Aic31_AC_IOCTL_SELECT_OUTPUT_SOURCE == cmd)
946         {
947             aic31SelectOutputDest(instHandle,cmdArgs);
948         }
949         else if (Aic31_AC_IOCTL_SELECT_INPUT_SOURCE == cmd)
950         {
951             aic31SelectInputSource(instHandle,cmdArgs);
952         }
953         else if (Aic31_AC_IOCTL_GET_CODEC_INFO == cmd)
954         {
955             /* command is the request for the codec information               */
956             if (NULL != cmdArgs)
957             {
958                 codecData = (ICodec_CodecData *)cmdArgs;
960                 /* update the required information to the provided pointer    */
961                 codecData->acOpMode = instHandle->acOpMode;
962             }
963             else
964             {
965                 status = IOM_EBADARGS;
966             }
967         }
968         else
969         {
970             /* The IOCTL is unrecognised or not implemented                   */
971             status = IOM_ENOTIMPL;
972         }
973         if (IOM_COMPLETED != status)
974         {
975                 status = IOM_EBADARGS;
976         }
977         else
978         {
979                 /* DO NOTHING */        
980         }
981     }
983     /* return the status of the IOCTL executed                                */
984     return (status);
988 /**
989  *  \brief This function is not implemented as codec does not perform any read
990  *  or write operations
991  *
992  * \param     instHandle   [IN]     Aic31 driver object
993  * \param     chanp        [IN]     handle to the channel
994  * \param     packet       [IN]     driver packet
995  * \param     eb           [OUT]    error block
996  *
997  * \return    IOM_ERROR  - error as not implemeted.
998  */
999  Int aic31MdSubmitChan(Ptr chanp, IOM_Packet *ioPacket)
1001     /* to remove compiler warning                                             */
1002     if (NULL != chanp)
1003     {
1004         chanp = chanp;
1005     }
1007     if (NULL != ioPacket)
1008     {
1009         ioPacket = ioPacket;
1010     }
1011     
1012     /* not implemented   */
1013     return IOM_EBADIO;
1017 /**
1018  * \brief    aic31MdDeleteChan
1019  *
1020  *  This function closes an specified Audio Codec Channel. The audio codec
1021  *  is moved into programming mode and then reset when both the channels
1022  *  are closed. It deinitalizes the control bus instance.
1023  *
1024  * \param     instHandle   [IN]     Aic31 driver object
1025  * \param     chanp        [IN]     handle to the channel
1026  * \param     eb           [OUT]    error block
1027  *
1028  * \return    None
1029  */
1030  Int aic31MdDeleteChan(Ptr chanp)
1032     Aic31_Object               *instHandle = NULL;
1033     Aic31_Channel_Object       *chanHandle = NULL;
1034     Int                        retVal      = IOM_COMPLETED;
1035 #ifndef SW_I2C
1036     Bool                       status      = Aic31_REG_WRITE_FAIL;
1037     IOM_Fxns                       *iomFxns; 
1038 #endif /* SW_I2C */
1040 /* Begin parameter checking                                                   */
1041 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
1042     if (NULL == chanp)
1043     {
1044         retVal = IOM_EBADARGS;
1045     }
1046     else
1047     {
1048 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
1049         chanHandle = (Aic31_Channel_Object*)chanp;
1050         instHandle = chanHandle->devHandle;
1051 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
1052         if ((NULL == instHandle) ||
1053             (ICodec_DriverState_CLOSED == chanHandle->chanStatus))
1054         {
1055             retVal = IOM_EBADARGS;
1056         }
1057     }
1058 #endif /* PSP_DISABLE_INPUT_PARAMETER_CHECK */
1059 /* End parameter checking                                                     */
1061     if (IOM_COMPLETED == retVal)
1062     {
1063         /* Write the reset value of Aic31 channel registers                   */
1064         if (chanHandle->channelMode == ICodec_Channel_INPUT )
1065         {
1066             /* Reset the ADC registers                                        */
1067 #ifndef SW_I2C
1068             retVal = aic31DeinitAdc(instHandle);
1069 #else
1070             AIC31ADCDeInit (instHandle->acBaseAddress);
1071 #endif /* SW_I2C */
1072         }
1073         else
1074         {
1075             /* Reset the DAC registers */
1076 #ifndef SW_I2C
1077             retVal = aic31DeinitDac(instHandle);
1078 #else
1079             AIC31DACDeInit (instHandle->acBaseAddress);
1080 #endif /* SW_I2C */
1081         }
1082     }
1085     if (IOM_COMPLETED == retVal)
1086     {
1087         /* Set the state of the channel as closed                             */
1088         chanHandle->chanStatus = ICodec_DriverState_CLOSED;
1090         /* Reset Aic31 only if both the channels are closed.                  */
1091         if ((ICodec_DriverState_CLOSED == instHandle->ChanObj[0].chanStatus)
1092             && (ICodec_DriverState_CLOSED == instHandle->ChanObj[1].chanStatus))
1093         {
1094 #ifndef SW_I2C
1095             /* Select Register Page 0 of Aic31                                */
1096             status = aic31RegWrite(
1097                          instHandle,
1098                          Aic31_PAGE_SELECT_ADDR,
1099                          Aic31_PAGE_0);
1101             /* Reset the Aic31                                                */
1102             status |= aic31RegWrite(
1103                          instHandle,
1104                          Aic31_RESET_ADDR,
1105                          (uint8_t)0x80);
1107             if (Aic31_REG_WRITE_FAIL == status)
1108             {
1109                 retVal = IOM_EBADARGS;
1110             }
1111             
1112                         iomFxns = DEV_getFxns(instHandle->acCtrlBusHandle);     
1113             ((IOM_Fxns*)iomFxns)->mdDeleteChan(
1114                 instHandle->hCtrlBus);
1115 #else
1116         /* Configure the Codec for I2S mode */
1117         AIC31Reset(instHandle->acBaseAddress);
1118 #endif /* SW_I2C */
1120             /* The control bus handle is not valid anymore                    */
1121             instHandle->hCtrlBus = NULL;
1122         }
1123     }
1125     return (retVal);
1128 /**
1129  * \brief     This function change the gain setting of DAC Aic31 codec
1130  *
1131  *  This function internally sets the gain setting of the DAC to adjust or
1132  *  changes the volume of AIC31 codec.
1133  *
1134  * \param     devp         [IN]     pointer to Aic31 driver object
1135  * \param     volume       [IN]     Volume change in percentage
1136  *
1137  * \return    NULL in case of error
1138  */
1139  Int aic31SetVolume(Ptr devp, uint8_t volume)
1140  {
1141     Aic31_Object           *instHandle   = NULL;
1142     int32_t                   result     = IOM_COMPLETED;
1144 /* Begin parameter checking                                                   */
1145 #ifndef PSP_DISABLE_INPUT_PARAMETER_CHECK
1146     if (NULL == devp)
1147     {
1148         result = IOM_EBADARGS;
1149     }
1150 #endif
1151     instHandle = (Aic31_Object *)devp;
1153     /* Configure the data format and sampling rate */
1154     AIC31DACSetVolume(instHandle->acBaseAddress,
1155                         volume);
1156     return result;
1159 /* ========================================================================== */
1160 /*               Local Interface for Aic31 audio codec driver                 */
1161 /* ========================================================================== */
1164 /**
1165  *  \brief  This function sets the sampling rate for the ADC and DAC. The ADC
1166  *          sampling rate is configured when called for input channel. The DAC
1167  *          sampling rate is configured when called for ouput channel.
1168  *
1169  *  \param  instHandle  [IN]  pointer to the aci31 instance handle
1170  *  \param  acChannel   [IN]  operational mode of the channel
1171  *  \param  sampleRate  [IN]  sample rate to be configured
1172  *  \param  eb          [OUT] Error block
1173  */
1174 static int32_t aic31SetSamplingRate(Aic31_Object       *instHandle,
1175                                   ICodec_Channel      acChannel,
1176                                   uint32_t              sampleRate)
1178     uint8_t pllPValue     = 0;
1179     uint8_t pllRValue     = 0;
1180     uint8_t pllJValue     = 0;
1181     uint8_t pllDLowValue  = 0;
1182     uint8_t pllDHighValue = 0;
1183     uint8_t dualRate      = 0x00;
1184     uint8_t sampleRateDiv = 0;
1185     uint8_t fsRef         = 0;
1186     int32_t status        = IOM_COMPLETED;
1187     Bool  retVal        = Aic31_REG_WRITE_FAIL;    
1188     
1189     assert(NULL != instHandle);
1191     if ((ICodec_Channel_INPUT == acChannel) ||
1192         (ICodec_Channel_OUTPUT == acChannel))
1193     {
1195         switch (sampleRate)
1196         {
1197             case 8000:
1198                 /* Set sampling rate to 8000Hz */
1199                 pllPValue      = 4u;
1200                 pllRValue      = 1u;
1201                 pllJValue      = 16u;
1202                 pllDLowValue   = 0u;
1203                 pllDHighValue  = 0u;
1204                 dualRate       = 0u;
1205                 fsRef          = 0u;
1206                 sampleRateDiv  = 10u;
1207                 break;
1209             case 11025:
1210                 /* Set sampling rate to 11025Hz */
1211                 pllPValue      = 2u;
1212                 pllRValue      = 1u;
1213                 pllJValue      = 7u;
1214                 pllDLowValue   = 44u;
1215                 pllDHighValue  = 54u;
1216                 dualRate       = 0u;
1217                 fsRef          = 1u;
1218                 sampleRateDiv  = 6u;
1219                 break;
1221             case 16000:
1222                 /* Set sampling rate to 16000Hz */
1223                 pllPValue      = 4u;
1224                 pllRValue      = 1u;
1225                 pllJValue      = 16u;
1226                 pllDLowValue   = 0u;
1227                 pllDHighValue  = 0u;
1228                 dualRate       = 0u;
1229                 fsRef          = 0u;
1230                 sampleRateDiv  = 4u;
1231                 break;
1233             case 22050:
1234                 /* Set sampling rate to 22050Hz */
1235                 pllPValue      = 2u;
1236                 pllRValue      = 1u;
1237                 pllJValue      = 7u;
1238                 pllDLowValue   = 44u;
1239                 pllDHighValue  = 54u;
1240                 dualRate       = 0u;
1241                 fsRef          = 1u;
1242                 sampleRateDiv  = 2u;
1243                 break;
1245             case 24000:
1246                 /* Set sampling rate to 24000Hz */
1247                 pllPValue      = 4u;
1248                 pllRValue      = 1u;
1249                 pllJValue      = 16u;
1250                 pllDLowValue   = 0u;
1251                 pllDHighValue  = 0u;
1252                 dualRate       = 0u;
1253                 fsRef          = 0u;
1254                 sampleRateDiv  = 2u;
1255                 break;
1257             case 32000:
1258                 /* Set sampling rate to 32000Hz */
1259                 pllPValue      = 4u;
1260                 pllRValue      = 1u;
1261                 pllJValue      = 16u;
1262                 pllDLowValue   = 0u;
1263                 pllDHighValue  = 0u;
1264                 dualRate       = 0u;
1265                 fsRef          = 0u;
1266                 sampleRateDiv  = 1u;
1267                 break;
1269             case 44100:
1270                 /* Set sampling rate to 44100Hz */
1271                 pllPValue      = 2u;
1272                 pllRValue      = 1u;
1273                 pllJValue      = 7u;
1274                 pllDLowValue   = 44u;
1275                 pllDHighValue  = 54u;
1276                 dualRate       = 0u;
1277                 fsRef          = 1u;
1278                 sampleRateDiv  = 0u;
1279                 break;
1281             case 48000:
1282                 /* Set sampling rate to 48000Hz */
1283                 pllPValue      = 4u;
1284                 pllRValue      = 1u;
1285                 pllJValue      = 16u;
1286                 pllDLowValue   = 0u;
1287                 pllDHighValue  = 0u;
1288                 dualRate       = 0u;
1289                 fsRef          = 0u;
1290                 sampleRateDiv  = 0u;
1291                 break;
1293             case 96000:
1294                 /* Set sampling rate to 96000Hz */
1295                 pllPValue      = 4u;
1296                 pllRValue      = 1u;
1297                 pllJValue      = 16u;
1298                 pllDLowValue   = 0u;
1299                 pllDHighValue  = 0u;
1300                 dualRate       = 1u;
1301                 fsRef          = 0u;
1302                 sampleRateDiv  = 0u;
1303                 break;
1304             default:
1305                 /* Sampling rate is not supported */
1306                 status = IOM_EBADARGS;
1307                 break;
1308         }
1310         if (IOM_COMPLETED == status)
1311         {
1312             if (ICodec_Channel_INPUT == acChannel)
1313             {
1314                 /* Write the ADC sample rate divisor value in Reg2 */
1315                 retVal= aic31RegWriteBf(
1316                             instHandle,
1317                             Aic31_P0_REG2,
1318                             (uint8_t)4,
1319                             (uint8_t)4,
1320                             sampleRateDiv);
1322                 retVal |= aic31RegWriteBf(
1323                              instHandle,
1324                              Aic31_P0_REG7,
1325                              (uint8_t)6,
1326                              (uint8_t)1,
1327                              dualRate);
1328             }
1329             else
1330             {
1331                 /* Write the DAC sample rate divisor value in Reg2            */
1332                 retVal = aic31RegWriteBf(
1333                             instHandle,Aic31_P0_REG2,
1334                             (uint8_t)0,
1335                             (uint8_t)4,
1336                             sampleRateDiv);
1338                 retVal |= aic31RegWriteBf(
1339                               instHandle,
1340                               Aic31_P0_REG7,
1341                               (uint8_t)5,
1342                               (uint8_t)1,
1343                               dualRate);
1344             }
1346             /* enable the PLL                                             */
1347             retVal |= aic31RegWriteBf(
1348                           instHandle,
1349                           Aic31_P0_REG3,
1350                           (uint8_t)7,
1351                           (uint8_t)1,
1352                           (uint8_t)1);
1354             /* select the MCLK as the input for the PLL and CLKDIV(N = 16)*/
1355             retVal |= aic31RegWriteBf(
1356                           instHandle,
1357                           Aic31_P0_REG102,
1358                           (uint8_t)4,
1359                           (uint8_t)2,
1360                           (uint8_t)0x00);
1361             /* select the PLL_IN as codec input                           */
1362             retVal |= aic31RegWriteBf(
1363                           instHandle, 
1364                           Aic31_P0_REG101,
1365                           (uint8_t)0, 
1366                           (uint8_t)1,
1367                           (uint8_t)0x00);
1370             /* selec the GPIO to output the divided PLL_IN clock(test purpose)*/
1371             retVal |= aic31RegWrite(instHandle,
1372                             Aic31_P0_REG98,
1373                             (uint8_t)0x20);
1375             /* Write to PLL programming register A                            */
1376             retVal |= aic31RegWriteBf(
1377                             instHandle,
1378                             Aic31_P0_REG3,
1379                             (uint8_t)0,
1380                             (uint8_t)3,
1381                             pllPValue);
1383             /* Write to PLL programming register B                            */
1384             retVal |= aic31RegWriteBf(
1385                             instHandle,
1386                             Aic31_P0_REG4,
1387                             (uint8_t)2,
1388                             (uint8_t)6,
1389                             pllJValue);
1391             /* write the high and low bits of the D value                     */
1392             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG5,pllDHighValue);
1393             retVal |= aic31RegWrite(
1394                            instHandle,
1395                            Aic31_P0_REG6,
1396                            (uint8_t)(pllDLowValue << 2));
1398             retVal |= aic31RegWriteBf(
1399                             instHandle,
1400                             Aic31_P0_REG11,
1401                             (uint8_t)0,
1402                             (uint8_t)4,
1403                             pllRValue);
1405             /* Write to codec datapath setup register                         */
1406             retVal |= aic31RegWriteBf(
1407                             instHandle, 
1408                             Aic31_P0_REG7,
1409                             (uint8_t)7,
1410                             (uint8_t)1,
1411                             fsRef);
1412         }
1413     }
1416     if (Aic31_REG_WRITE_PASS == retVal)
1417     {
1418         status = IOM_COMPLETED;
1419     }
1420     else
1421     {
1422         status = IOM_EBADARGS;
1423     }
1425     /* Return the result of setting the sampling rate */
1426     return (status);
1429 /**
1430  *  This function perfroms a register write(s) to the audio codec. The control
1431  *  bus is selected based on the parameter value selected.
1432  *
1433  *  \param  instHandle  [IN]  pointer to the aci31 instance handle
1434  *  \param  wrRegData   [OUT] data to be written to codec
1435  *
1436  *  \return  Aic31_REG_WRITE_PASS in case of success
1437  *           Aic31_REG_WRITE_FAIL in case of error
1438  */
1439 static Bool aic31CtrlBusWrite(Aic31_Object    *instHandle,
1440                               ICodec_RegData  *wrRegData)
1442     ICodec_ControlBusType     acCtrlBusType;
1443     uint32_t                    deviceId;
1444     Bool                      retVal = Aic31_REG_WRITE_FAIL;
1446     assert((NULL != instHandle) && (NULL != wrRegData));
1448     /* Initialize the local variables */
1449     acCtrlBusType = instHandle->acControlBusType;
1450     deviceId = instHandle->acCodecId;
1452     if (ICodec_ControlBusType_I2C == acCtrlBusType)
1453     {
1454         retVal = aic31I2cWrite(instHandle,deviceId,wrRegData);
1455     }
1456     else if (ICodec_ControlBusType_SPI == acCtrlBusType)
1457     {
1458         /* Add SPI call here */
1459         retVal = Aic31_REG_WRITE_FAIL;
1460     }
1461     else
1462     {
1463         retVal = Aic31_REG_WRITE_FAIL;
1464     }
1465     return (retVal);
1468 /**
1469  *  \brief  This function perfroms a register write(s) to the audio codec using
1470  *          the I2C control bus.
1471  *
1472  *  \param  instHandle [IN]  pointer to the device instance object
1473  *  \param  deviceId   [IN]  slave device address
1474  *  \param  wrRegData  [IN]  data to write to slave
1475  *
1476  *  \return  Aic31_REG_WRITE_PASS in case of success
1477  *           Aic31_REG_WRITE_FAIL in case of error
1478  */
1479 static Bool aic31I2cWrite(Aic31_Object    *instHandle,
1480                           uint32_t           deviceId,
1481                           ICodec_RegData  *wrRegData)
1483     uint8_t              count;      /* Local count variable                    */
1484     uint32_t             regIndex;   /* Register indec to be written            */
1485     uint8_t             *regData;    /* Pointer to array of register write data */
1486 #ifndef SW_I2C
1487     uint8_t              data[2];    /* Temporary data                          */
1488     IOM_Packet         ioPacket;
1489     I2c_DataParam      dataBuffer;
1490     int32_t              result = IOM_EBADARGS; /* Result */
1491     IOM_Fxns           *iomFxns;     
1492 #endif /* SW_I2C */
1493     Bool               retVal = Aic31_REG_WRITE_FAIL;
1495     assert((NULL != instHandle) && (NULL != wrRegData));
1497     /* Initialize the local variables */
1498     regIndex = wrRegData->regIndex;
1499     regData  = (uint8_t*)wrRegData->regData;
1501     assert(NULL != regData);
1503     /* Write all the registers */
1504     for (count = 0; count < wrRegData->regCount; count++)
1505     {
1506 #ifndef SW_I2C
1507         /* Prepare the data to be written to the audio codec */
1508         data[0] = regIndex;
1509         data[1] = ((*regData) & 0xFF);
1511         dataBuffer.slaveAddr = deviceId;
1512         dataBuffer.buffer    = &data[0];
1513         dataBuffer.bufLen    = 2u;
1514         dataBuffer.flags     = I2c_DEFAULT_WRITE;
1516         memset(&ioPacket,0x00,sizeof(IOM_Packet));
1518         ioPacket.addr   = &dataBuffer;
1519         ioPacket.size   = 2u;
1520         ioPacket.cmd    = (Uns)IOM_WRITE;
1521         ioPacket.status = IOM_COMPLETED;
1523         /* Write the data to Aic31 register */
1524                 iomFxns                 = DEV_getFxns(instHandle->acCtrlBusHandle);     
1525         result = ((IOM_Fxns*)iomFxns)-> \
1526                     mdSubmitChan(
1527                         instHandle->hCtrlBus,
1528                         &ioPacket);
1530         if (IOM_PENDING == result)
1531         {
1532             Semaphore_pend(Semaphore_handle(&(instHandle->semObj)), Aic31_I2CTIMEOUT);
1533         }
1535         /* Validate the number of words written to Aic31 codec.               */
1536         if ((IOM_COMPLETED == ioPacket.status) ||
1537             (IOM_PENDING == ioPacket.status))
1538         {
1539             retVal = Aic31_REG_WRITE_PASS;
1540         }
1541         else
1542         {
1543             break;
1544         }
1545 #else
1546         CodecRegWrite(instHandle->acBaseAddress, regIndex, ((*regData) & 0xFF));
1547         retVal = Aic31_REG_WRITE_PASS;
1548 #endif /* SW_I2C */
1549         /* Maintain the register data pointer and register index */
1550         regIndex++;
1551         regData++;
1552     }
1554     /* Return the result of writting to Aic31 registers */
1555     return (retVal);
1559 /**
1560  *  \brief  This function writes a value to a single Aic31 register. This
1561  *          function is a wrapper for faclitating single register writes in the
1562  *          Aic31 codec driver. It internally calls aic31CtrlBusWrite function.
1563  *
1564  *  \param  instHandle [IN]  pointer to the device driver instance object
1565  *  \param  regAddr    [IN]  register address
1566  *  \param  regData    [IN]  register data to be written
1567  *
1568  * \return  FALSE  in case of success
1569  *          Error code in case of error
1570  */
1571 static Bool aic31RegWrite(Aic31_Object  *instHandle,
1572                           uint8_t          regAddr,
1573                           uint8_t          regData)
1575     ICodec_RegData   acRegData;                    /* Register data structure */
1576     Bool             retVal = Aic31_REG_WRITE_FAIL;/* Result of write         */
1578     assert(NULL != instHandle);
1580     /* Write the data from the Aic31 register */
1581     acRegData.regCount = 1u;
1582     acRegData.regIndex = regAddr;
1583     acRegData.regData  = (Ptr)&regData;
1585     retVal = aic31CtrlBusWrite(instHandle,&acRegData);
1587     /* Return the result of reading the register */
1588     return (retVal);
1592 /**
1593  * \brief   This function perfroms a register read(s) to the audio codec.
1594  *          The control bus is selected based on the parameter value selected.
1595  *
1596  * \param   instHandle [IN]  pointer to the device driver instance object
1597  * \param   rdRegData  [OUT] pointer to the register data read structure
1598  *
1599  *  \return  Aic31_REG_READ_PASS in case of success
1600  *           Aic31_REG_READ_FAIL in case of error
1601  */
1602 static Bool aic31CtrlBusRead(Aic31_Object    *instHandle,
1603                              ICodec_RegData  *rdRegData)
1605     Bool                    retVal = Aic31_REG_READ_FAIL;
1606     ICodec_ControlBusType   acCtrlBusType;
1607     uint32_t                  deviceId;
1609     assert(NULL != instHandle);
1611     /* Initialize the local variables */
1612     acCtrlBusType = instHandle->acControlBusType;
1613     deviceId = instHandle->acCodecId;
1615     /* Determine the control bus and invoke the corresponding read function   */
1616     if (ICodec_ControlBusType_I2C == acCtrlBusType)
1617     {
1618         /* Control bus is I2C. Read from I2c bus. */
1619         retVal = aic31I2cRead(instHandle,deviceId,rdRegData);
1620     }
1621     else if (ICodec_ControlBusType_SPI == acCtrlBusType)
1622     {
1623        /*  Add SPI call here */
1624        retVal = Aic31_REG_READ_FAIL;
1625     }
1626     else
1627     {
1628         retVal = Aic31_REG_READ_FAIL;
1629     }
1630     /* Return the result of reading register data */
1631     return (retVal);
1634 /**
1635  *  \brief  This function perfroms a register reads(s) from the audio codec
1636  *          using the  I2C control bus. This function first writes the address
1637  *          of the register address without issuing a I2C stop. It then issues
1638  *          a I2C restart and reads the value of the register.
1639  *
1640  *  \param   instHandle  [IN]  pointer to the driver instance object
1641  *  \param   deviceId    [IN]  I2c slave device address
1642  *  \param   rdRegData   [OUT] register data read
1643  *
1644  *  \return  Aic31_REG_READ_PASS in case of success
1645  *           Aic31_REG_READ_FAIL in case of error
1646  */
1647 static Bool aic31I2cRead(Aic31_Object         *instHandle,
1648                          uint32_t                deviceId,
1649                          ICodec_RegData       *rdRegData)
1651     uint8_t                count;    /* Local count variable                    */
1652     uint32_t               regIndex; /* Register index to be written            */
1653     uint8_t               *regData;  /* Pointer to array of register write data */
1654 #ifndef SW_I2C
1655     uint8_t                data[10]; /* Temporary data                          */
1656     I2c_DataParam        dataBuffer;
1657     IOM_Packet           ioPacket;
1658     int32_t                status = IOM_COMPLETED;
1659     IOM_Fxns             *iomFxns;     
1660 #endif /* SW_I2C */
1661     Bool                 retVal = Aic31_REG_READ_FAIL;
1662     
1663     assert(NULL != rdRegData);
1664     
1665     /* Initialize the local variables                                         */
1666     regIndex = rdRegData->regIndex;
1667     regData  = (uint8_t*)rdRegData->regData;
1669     assert(NULL != regData);
1671     assert(NULL != instHandle);
1673     /* Read all the registers                                                 */
1674     for (count = 0; count < rdRegData->regCount; count++)
1675     {
1676 #ifndef SW_I2C
1677         /* The following the procedure to read data from Aic31 codec
1679            Step A: Write the address of the register to be read.
1680                    Note: The I2C stop should not be issued.
1681            Step B: Issue I2C restart.
1682            Step C: Read the value of the register.                            */
1683         data[0] = regIndex;
1685         /* Prepare the data to be written to the audio codec                  */
1686         dataBuffer.slaveAddr = deviceId;
1687         dataBuffer.buffer    = &data[0];
1688         dataBuffer.bufLen    = 1u;
1689         dataBuffer.flags     = I2c_WRITE | I2c_MASTER | I2c_START;
1691         memset(&ioPacket,0x00,sizeof(IOM_Packet));
1693         ioPacket.addr   = &dataBuffer;
1694         ioPacket.size   = 2u;
1695         ioPacket.cmd    = (Uns)IOM_WRITE;
1696         ioPacket.status = IOM_COMPLETED;
1698         
1699                 iomFxns                 = DEV_getFxns(instHandle->acCtrlBusHandle);     
1700         status = ((IOM_Fxns*)iomFxns)->mdSubmitChan(
1701                         instHandle->hCtrlBus,
1702                         &ioPacket);
1704         if (IOM_PENDING == status)
1705         {
1706             Semaphore_pend(Semaphore_handle(&(instHandle->semObj)), Aic31_I2CTIMEOUT);
1707         }
1709         /* If the write command is complete, read the registers of Aic31      */
1710         if ((IOM_COMPLETED == ioPacket.status )||
1711             (IOM_PENDING == ioPacket.status))
1712         {
1713             ioPacket.cmd = IOM_READ;
1715             dataBuffer.flags = I2c_READ
1716                               | I2c_MASTER
1717                               | I2c_STOP
1718                               | I2c_RESTART;
1720             status = ((IOM_Fxns *)iomFxns)->  \
1721                               mdSubmitChan(instHandle->hCtrlBus,&ioPacket);
1722         }
1724         if (IOM_PENDING == status)
1725         {
1726             Semaphore_pend(Semaphore_handle(&(instHandle->semObj)), Aic31_I2CTIMEOUT);
1727         }
1729         /* If read is complete, then copy the required register values*/
1730         if ((IOM_COMPLETED == ioPacket.status )||
1731                 (IOM_PENDING == ioPacket.status))
1732         {
1733             *regData = data[0];
1734             regData++;
1735             regIndex++;
1736             retVal= Aic31_REG_READ_PASS;
1737         }
1738         else
1739         {
1740             break;
1741         }
1742 #else
1743         CodecRegRead(instHandle->acBaseAddress, regIndex);
1744         retVal= Aic31_REG_READ_PASS;
1745 #endif /* SW_I2C */
1746     }
1748     /* Return the result of reading the Aic31 registers                       */
1749     return (retVal);
1752 /**
1753  *  This function reads the value of a single Aic31 register. This function
1754  *  is a wrapper for faclitating single register reads in the Aic31 codec
1755  *  driver. It internally calls aic31CtrlBusRead function.
1756  *
1757  *  \param   instHandle  [IN]  pointer to the driver instance object
1758  *  \param   regAddr     [IN]  register address
1759  *  \param   regData     [OUT] register data read
1760  *
1761  *  \return  Aic31_REG_READ_PASS in case of success
1762  *           Aic31_REG_READ_FAIL in case of error
1763  */
1764 static Bool aic31RegRead(Aic31_Object  *instHandle,
1765                          uint8_t          regAddr,
1766                          uint8_t         *regData)
1768     ICodec_RegData   acRegData;                   /* Register data structure  */
1769     Bool             retVal = IOM_COMPLETED;      /* Result of read           */
1771     assert((NULL != instHandle) && (NULL != regData));
1773     /* Read the data from the Aic31 register                                  */
1774     acRegData.regCount = 1u;
1775     acRegData.regIndex = regAddr;
1776     acRegData.regData  = (Ptr)regData;
1778     retVal = aic31CtrlBusRead(instHandle, &acRegData);
1780     /* Return the result of reading the register                              */
1781     return (retVal);
1785 /**
1786  *  \brief This function writes data into a bit field of Aic31 register. This
1787  *         function reads the value of the register, modifies the value of the
1788  *         specified register and writes the value back to the register.
1789  *
1790  *  \param  instHandle [IN] pointer to the driver instance object
1791  *  \param  regAddr    [IN] register address
1792  *  \param  bfPosition [IN] bit field position
1793  *  \param  bfSize     [IN] bit field size
1794  *  \param  bfData     [IN] data to be written to the bit field
1795  *
1796  *  \return Aic31_REG_WRITE_PASS in case of success
1797  *          Aic31_REG_WRITE_FAIL in case of error
1799  */
1800 static Bool aic31RegWriteBf(Aic31_Object *instHandle,
1801                             uint8_t         regAddr,
1802                             uint8_t         bfPosition,
1803                             uint8_t         bfSize,
1804                             uint8_t         bfData)
1806     uint8_t   regData     = 0;                  /* Temporary Register data      */
1807     uint8_t   mask        = 0;                  /* Bit field mask               */
1808     Bool    bFalseWhile = TRUE;
1809     Bool    retVal      = Aic31_REG_WRITE_FAIL;
1811     assert(NULL != instHandle);
1813     do
1814     {
1815         bFalseWhile = FALSE;
1816     
1817         /* Read the current value of the register                             */
1818         retVal = aic31RegRead( instHandle , regAddr , &regData );
1820         if (Aic31_REG_WRITE_PASS != retVal)
1821         {
1822             break;
1823         }
1825         /* Update the value of the bit field                                  */
1826         mask = ((1 << bfSize) - 1) << bfPosition;
1827         regData = (regData & (uint8_t)(~(mask)));
1828         regData = (regData | (uint8_t)( bfData << bfPosition));
1830         /* Write the data back into the register                              */
1831         retVal= aic31RegWrite(instHandle,regAddr,regData);
1833     }while (bFalseWhile);
1835     /* Return the result of writing data into the bit field                   */
1836     return (retVal);
1839 #ifndef SW_I2C
1841 /**
1842  *  \brief  This function writes the initialization values for Aic31 ADC
1843  *          registers. This function should be called to initialize the registers
1844  *          of the ADC.
1845  *
1846  *  \param  instHandle [IN]  Pointer to the driver instance object
1847  *
1848  *  \return IOM_COMPLETED
1849  */
1850 static int32_t aic31InitAdc(Aic31_Object *instHandle)
1852     int32_t  status  = IOM_EBADARGS;
1853     Bool   retVal  = Aic31_REG_WRITE_FAIL;
1854     uint8_t  gain   = 0;
1856     assert(NULL != instHandle);
1858     /* Write the initialization values for the ADC registers                  */
1859     retVal  = aic31RegWriteBf(
1860                   instHandle, 
1861                   Aic31_P0_REG7, 
1862                   (uint8_t)1,
1863                   (uint8_t)4, 
1864                   (uint8_t)5);
1866     /* enable the programmable PGA for left and right ADC                     */
1867     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG15, (uint8_t)0x00);
1868     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG16, (uint8_t)0x00);
1870     /* MIC3L/R is not connected to the left ADC PGA                           */
1871     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG17,(uint8_t)0xFF);
1873     /* MIC3L/R is not connected to the right ADC PGA                          */
1874     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG18,(uint8_t)0xFF);
1876     /* power on the Line L1R                                                  */
1877     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG19,(uint8_t)0x04);
1879     /* REG20 (not required)                                                   */
1880     /* REG21 (not required)                                                   */
1882     /* power on the Line LIL                                                  */
1883     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG22,(uint8_t)0x04);
1885    /* check if the user requested gain in less than 100 %                    */
1886     if (instHandle ->ChanObj[0].chanGain <= Aic31_MAX_GAIN_PERCENT)
1887     {
1888         gain = (uint8_t)((instHandle ->ChanObj[0].chanGain * 
1889                     Aic31_MAX_PGA_GAIN_VALUE)/ Aic31_MAX_GAIN_PERCENT);
1891         /* Left AGC control                                                   */
1892         retVal |= aic31RegWrite(
1893                       instHandle,
1894                       Aic31_LEFT_AGC_CTRLA_ADDR,
1895                       (uint8_t)0x80);
1896         retVal |= aic31RegWrite(
1897                       instHandle,
1898                       Aic31_LEFT_AGC_CTRLB_ADDR,
1899                       (uint8_t)(gain << 1));
1900         retVal |= aic31RegWrite(
1901                       instHandle, 
1902                       Aic31_LEFT_AGC_CTRLC_ADDR, 
1903                       (uint8_t)0x00);
1905         /* Right AGC control                                                  */
1906         retVal |= aic31RegWrite(
1907                       instHandle,
1908                       Aic31_RIGHT_AGC_CTRLA_ADDR,
1909                       (uint8_t)0x80);
1910         retVal |= aic31RegWrite(
1911                       instHandle,
1912                       Aic31_RIGHT_AGC_CTRLB_ADDR,
1913                       (uint8_t)(gain << 1));
1914         retVal |= aic31RegWrite(
1915                       instHandle,
1916                       Aic31_RIGHT_AGC_CTRLC_ADDR,
1917                       (uint8_t)0x00);
1918     }
1919     else
1920     {
1921         status = IOM_EBADARGS;
1922     }
1924     if (Aic31_REG_WRITE_PASS == retVal)
1925     {
1926         status = IOM_COMPLETED;
1927     }
1929     return (status);
1932 /**
1933  *
1934  *  \brief  This function writes the initialization values for Aic31 DAC
1935  *          registers. This function should be called to initialize the
1936  *          registers of the DAC.
1937  *
1938  *  \param  instHandle [IN]  Pointer to the driver instance object
1939  *
1940  *  \return IOM_COMPLETED
1941  */
1942 static int32_t aic31InitDac(Aic31_Object *instHandle)
1944     int32_t  status  = IOM_EBADARGS;
1945     Bool   retVal  = Aic31_REG_WRITE_FAIL;
1946     uint8_t  gain    = 0;
1948     assert(NULL != instHandle);
1950     /* Write the initialization values for the DAC registers                  */
1951     retVal  = aic31RegWriteBf(
1952                    instHandle,
1953                    Aic31_P0_REG7,
1954                    (uint8_t)1,
1955                    (uint8_t)4,
1956                    (uint8_t)5);
1958     /* power up the left and right DACs                                       */
1959     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG37, (uint8_t)0xE0);
1961     /* select the DAC L1 R1 Paths                                             */
1962     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG41, (uint8_t)0x02);
1964     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG42, (uint8_t)0x6C);
1966     /* unmute the DAC                                                         */
1967     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG43, (uint8_t)0x00);
1968     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG44, (uint8_t)0x00);
1970     /* DAC L to HPL OUT Is connected                                          */
1971     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG47, (uint8_t)0x80);
1972     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG51, (uint8_t)0x09);
1974     /* DAC R to HPROUT is connected                                           */
1975     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG64, (uint8_t)0x80);
1976     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG65, (uint8_t)0x09);
1978     /* DACL1 connected to LINE1 LOUT                                          */
1979     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG82, (uint8_t)0x80);
1980     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG86, (uint8_t)0x09);
1982     /* DACR1 connected to LINE1 ROUT                                          */
1983     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG92, (uint8_t)0x80);
1984     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG93, (uint8_t)0x09);
1986     /* check if the user requested gain in less than 100 %                    */
1987     if (instHandle ->ChanObj[1].chanGain <= Aic31_MAX_GAIN_PERCENT)
1988     {
1989         gain = (uint8_t)((instHandle->ChanObj[1].chanGain * 
1990                     Aic31_MAX_PGA_GAIN_VALUE) / Aic31_MAX_GAIN_PERCENT);
1992         gain = Aic31_MAX_PGA_GAIN_VALUE - gain;
1994         /* Left/Right DAC digital volume gain                                 */
1995         retVal |= aic31RegWrite(instHandle,Aic31_LEFT_DAC_VOL_CTRL_ADDR, gain);
1996         retVal |= aic31RegWrite(instHandle,Aic31_RIGHT_DAC_VOL_CTRL_ADDR, gain);
1997     }
1998     else
1999     {
2000        status = IOM_EBADARGS;
2001     }
2003     if (Aic31_REG_WRITE_PASS == retVal)
2004     {
2005         status = IOM_COMPLETED;
2006     }
2008     return (status);
2011 /**
2012  *  \brief This function writes the reset values for Aic31 ADC registers.
2013  *         This function should be called to reset the registers of the ADC.
2014  *         It is recommended to write reset values explicitly.
2015  *
2016  *  \param  instHandle [IN]  Pointer to the driver instance object
2017  *
2018  *  \return IOM_COMPLETED
2019  */
2020 static int32_t aic31DeinitAdc(Aic31_Object *instHandle)
2022     int32_t  status = IOM_EBADARGS;
2023     Bool   retVal  = Aic31_REG_WRITE_FAIL;
2025     assert(NULL != instHandle);
2027     /* Write the reset values to ADC registers                                */
2028     retVal  = aic31RegWrite(instHandle, Aic31_P0_REG15, (uint8_t)0x00);
2029     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG16, (uint8_t)0x00);
2030     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG17, (uint8_t)0xFF);
2031     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG18, (uint8_t)0xFF);
2032     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG19, (uint8_t)0x78);
2033     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG22, (uint8_t)0x78);
2034     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG26, (uint8_t)0x00);
2035     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG27, (uint8_t)0xFE);
2036     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG28, (uint8_t)0x00);
2037     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG29, (uint8_t)0x00);
2038     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG30, (uint8_t)0xFE);
2039     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG31, (uint8_t)0x00);
2041     if (Aic31_REG_WRITE_PASS == retVal)
2042     {
2043         status = IOM_COMPLETED;
2044     }
2046     return (status);
2049 /**
2050  *  \brief   This function writes the reset values for Aic31 DAC registers.
2051  *           This function should be called to reset the registers of the DAC.
2052  *           It is recommended to write reset values explicitly.
2053  *
2054  *  \param   instHandle [IN]  Pointer to the driver instance object
2055  *
2056  *  \return  IOM_COMPLETED
2057  */
2058 static int32_t aic31DeinitDac(Aic31_Object *instHandle)
2060     int32_t  status  = IOM_EBADARGS;
2061     Bool   retVal  = Aic31_REG_WRITE_FAIL;
2063     assert(NULL != instHandle);
2065     /* Write the reset values to DAC registers                                */
2066     retVal  = aic31RegWriteBf(
2067                   instHandle, 
2068                   Aic31_P0_REG7, 
2069                   (uint8_t)1, 
2070                   (uint8_t)4,
2071                   (uint8_t)0);
2072     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG37, (uint8_t)0x00);
2073     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG38, (uint8_t)0x00);
2074     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG41, (uint8_t)0x00);
2075     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG42, (uint8_t)0x00);
2076     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG43, (uint8_t)0x80);
2077     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG44, (uint8_t)0x80);
2078     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG51, (uint8_t)0x04);
2079     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG64, (uint8_t)0x00);
2080     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG65, (uint8_t)0x04);
2081     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG82, (uint8_t)0x00);
2082     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG86, (uint8_t)0x00);
2083     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG92, (uint8_t)0x00);
2084     retVal |= aic31RegWrite(instHandle, Aic31_P0_REG93, (uint8_t)0x00);
2086     if (Aic31_REG_WRITE_PASS == retVal)
2087     {
2088         status = IOM_COMPLETED;    
2089     }
2091     return (status);
2094 #endif /* SW_I2C */
2096 /**
2097  *
2098  *  \brief   This function configures the mute for ADC and DAC. The mute
2099  *           functionality can be enabled or disabled for input (ADC) or output
2100  *           (DAC) channels.
2101  *
2102  *  \param   instHandle [IN] pointer to the driver instance object
2103  *  \param   acChannel  [IN] channel type input or output
2104  *  \param   muteconfig [IN] mute configuration value TRUE or FALSE
2105  *
2106  *  \return  IOM_COMPLETED if success
2107  *           IOM_EBADARGS  in case of error
2108  */
2109 static int32_t aic31MuteConfig(Aic31_Object    *instHandle,
2110                              ICodec_Channel   acChannel,
2111                              Bool             muteConfig)
2113     /* Intialize the local variables                                          */
2114     int32_t status        = IOM_COMPLETED;
2115     Bool  notMuteConfig = FALSE;
2116     Bool  retVal        = Aic31_REG_WRITE_FAIL;
2118     assert(NULL != instHandle);
2120     if (ICodec_Channel_INPUT == acChannel)
2121     {
2122         if (TRUE == muteConfig)
2123         {
2124             notMuteConfig = FALSE;
2125         }
2126         else
2127         {
2128             notMuteConfig = TRUE;
2129         }
2130     
2131         /* Mute the left and right input channels                             */
2132         retVal = aic31RegWriteBf(
2133                        instHandle, 
2134                        Aic31_P0_REG26,
2135                        (uint8_t)7, 
2136                        (uint8_t)1,
2137                        (uint8_t)(notMuteConfig));
2138         retVal |= aic31RegWriteBf(
2139                        instHandle, 
2140                        Aic31_P0_REG15, 
2141                        (uint8_t)7, 
2142                        (uint8_t)1,
2143                        (uint8_t)muteConfig);
2144         retVal |= aic31RegWriteBf(
2145                        instHandle,
2146                        Aic31_P0_REG29,
2147                        (uint8_t)7,
2148                        (uint8_t)1,
2149                        (uint8_t)(notMuteConfig));
2150         retVal |= aic31RegWriteBf(
2151                        instHandle,
2152                        Aic31_P0_REG16,
2153                        (uint8_t)7,
2154                        (uint8_t)1,
2155                        (uint8_t)muteConfig);
2156     }
2157     else if (ICodec_Channel_OUTPUT == acChannel)
2158     {
2159         /* Mute the left and right output channels                            */
2160         retVal  = aic31RegWriteBf(
2161                        instHandle, 
2162                        Aic31_P0_REG43, 
2163                        (uint8_t)7,
2164                        (uint8_t)1,
2165                        (uint8_t)muteConfig);
2166         retVal |= aic31RegWriteBf(
2167                       instHandle, 
2168                       Aic31_P0_REG44, 
2169                       (uint8_t)7, 
2170                       (uint8_t)1, 
2171                       (uint8_t)muteConfig);
2172     }
2173     else
2174     {
2175         /* Invalid parameter                                                  */
2176         status = IOM_EBADARGS;
2177     }
2179     if (Aic31_REG_WRITE_PASS == retVal)
2180     {
2181         status = IOM_COMPLETED;
2182     }
2184     /* Return the result of the mute operation                                */
2185     return (status);
2188 #ifndef SW_I2C
2190 /**
2192  *
2193  * \brief   This function is the codec call back function invoked from the I2c
2194  *          driver on transfer completion.
2195  *
2196  * \param   semHandle [IN] pointer to the Semaphore Handle
2197  * \param   ioPacket  [IN] pointer to the completed ioPacket
2198  *
2199  * \return  none
2200  *
2201  */
2202 static Void aic31CallBack (Ptr semHandle, IOM_Packet * ioPacket)
2204     assert((NULL != semHandle) && (NULL != ioPacket));
2206     if (NULL != ioPacket)
2207     {
2208         ioPacket = ioPacket;
2209     }
2211     Semaphore_post(Semaphore_handle(semHandle));
2212     return;
2215 #endif /* #ifndef SW_I2C */
2217 /**
2218  *
2219  * \brief   This function selects the output source of the audio data among the
2220  *          line out,hp out or both options
2221  *
2222  * \param   instHandle  [IN] pointer to the driver object
2223  * \param   destOption  [IN] pointer to Enum specifying the output destination
2224  *
2225  * \return  IOM_COMPLETED in case of success.
2226  *          IOM_EBADARGS  in case of error.
2227  */
2228 static int32_t aic31SelectOutputDest(Aic31_Object    *instHandle,
2229                                    Ptr              destOption)
2231     Int    *dest      = 0;
2232     int32_t   status    = IOM_EBADARGS;
2233     Bool    retVal    = Aic31_REG_WRITE_FAIL;
2235     assert((NULL != instHandle) && (NULL != destOption));
2237     dest = (Int *)destOption;
2239     switch (*dest)
2240     {
2241         case ICodec_OutputDest_LINEOUT:
2242             /* disconnect the HPOUT and conect the lINE OUT                   */
2244             /* disconnect and power down the HPOUT L                          */
2245             retVal  = aic31RegWrite(instHandle, Aic31_P0_REG47, (uint8_t)0x00);
2246             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG51, (uint8_t)0x06);
2248             /* disconnect and powerdown HPOUT R                               */
2249             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG64, (uint8_t)0x00);
2250             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG65, (uint8_t)0x06);
2252             /* DACL1 connected to LINE1 LOUT                                  */
2253             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG82, (uint8_t)0x80);
2254             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG86, (uint8_t)0x09);
2256             /* DACR1 connected to LINE1 ROUT                                  */
2257             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG92, (uint8_t)0x80);
2258             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG93, (uint8_t)0x09);
2259             break;
2261         case ICodec_OutputDest_HPOUT:
2262             /* DACL1 disconnected from LINE1 LOUT                             */
2263             retVal  = aic31RegWrite(instHandle, Aic31_P0_REG82, (uint8_t)0x00);
2264             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG86, (uint8_t)0x06);
2266             /* DACR1 disconnected from LINE1 ROUT                             */
2267             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG92, (uint8_t)0x00);
2268             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG93, (uint8_t)0x06);
2270             /* DAC L to HPL OUT Is connected                                  */
2271             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG47, (uint8_t)0x80);
2272             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG51, (uint8_t)0x09);
2274             /* DAC R to HPROUT is connected                                   */
2275             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG64, (uint8_t)0x80);
2276             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG65, (uint8_t)0x09);
2277             break;
2278         case ICodec_OutputDest_BOTH:
2279             /* DAC L to HPL OUT Is connected                                  */
2280             retVal = aic31RegWrite(instHandle, Aic31_P0_REG47, (uint8_t)0x80);
2281             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG51, (uint8_t)0x09);
2283             /* DAC R to HPROUT is connected                                   */
2284             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG64, (uint8_t)0x80);
2285             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG65, (uint8_t)0x09);
2287             /* DACL1 connected to LINE1 LOUT                                  */
2288             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG82, (uint8_t)0x80);
2289             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG86, (uint8_t)0x09);
2291             /* DACR1 connected to LINE1 ROUT                                  */
2292             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG92, (uint8_t)0x80);
2293             retVal |= aic31RegWrite(instHandle, Aic31_P0_REG93, (uint8_t)0x09);
2294             break;
2295         default:
2296             status = IOM_EBADARGS;
2297             break;
2298     }
2300     if (Aic31_REG_WRITE_PASS == retVal)
2301     {
2302         status = IOM_COMPLETED;
2303     }
2305     return (status);
2308 /**
2309  *
2310  * \brief   This function selects the input source of the audio data among the
2311  *          available sources of Mic in and line in
2312  *
2313  * \param   instHandle  [IN] pointer to the driver object
2314  * \param   srcOption   [IN] Enum specifying the output destination
2315  *
2316  * \return  IOM_COMPLETED in case of success.
2317  *          IOM_EBADARGS  in case of error.(write failed)
2318  *
2319  */
2320 static int32_t aic31SelectInputSource(Aic31_Object    *instHandle,
2321                                     Ptr              srcOption)
2323     Int    *src     = 0;
2324     Bool    retVal  = Aic31_REG_WRITE_FAIL;
2325     int32_t   status  = IOM_EBADARGS;
2327     assert((NULL != instHandle) && (NULL != srcOption));
2329     src = (Int *)srcOption;
2331     if (ICodec_InputDest_MICIN == (*src))
2332     {
2333         /* disable the LINE IN connected to the ADC                           */
2334         retVal  = aic31RegWrite(instHandle, Aic31_P0_REG19, (uint8_t)0x7C);
2335         retVal |= aic31RegWrite(instHandle, Aic31_P0_REG22, (uint8_t)0x7C);
2337         /* connect the MIC IN to the ADC                                      */
2338         retVal |= aic31RegWrite(instHandle, Aic31_P0_REG17, (uint8_t)0x0F);
2339         retVal |= aic31RegWrite(instHandle, Aic31_P0_REG18, (uint8_t)0xF0);
2340     }
2341     else if (ICodec_InputDest_LINEIN == (*src))
2342     {
2343         /* disable the MIC IN connected to the ADC                            */
2344         retVal = aic31RegWrite(instHandle, Aic31_P0_REG17, (uint8_t)0xFF);
2345         retVal |= aic31RegWrite(instHandle, Aic31_P0_REG18, (uint8_t)0xFF);
2346         
2347         /* connect the LINE IN to the ADC                                     */
2348         retVal |= aic31RegWrite(instHandle, Aic31_P0_REG19, (uint8_t)0x04);
2349         retVal |= aic31RegWrite(instHandle, Aic31_P0_REG22, (uint8_t)0x04);
2350     }
2351     else
2352     {
2353         /* Invalid parameter                                                  */
2354         status = IOM_EBADARGS;
2355     }
2357     /* if all the reg writes have passed we will send the status as completed */
2358     if (Aic31_REG_WRITE_PASS == retVal)
2359     {
2360         status = IOM_COMPLETED;
2361     }
2362     
2363     return (status);
2365 /* ========================================================================== */
2366 /*                             END OF FILE                                    */
2367 /* ========================================================================== */