1 /*
2  * Copyright 2017-2018, NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include <string.h>
10 
11 #include "srtm_i2c_codec_adapter.h"
12 #include "srtm_heap.h"
13 #include "fsl_codec_i2c.h"
14 #include "srtm_audio_service.h"
15 /*******************************************************************************
16  * Definitions
17  ******************************************************************************/
18 /* Codec adapter */
19 typedef struct _srtm_i2c_codec_adapter
20 {
21     struct _srtm_codec_adapter adapter;
22     srtm_i2c_codec_config_t config;
23     codec_handle_t *driver;
24     uint32_t srate;
25     uint8_t format;
26 } * srtm_i2c_codec_adapter_t;
27 
28 /*******************************************************************************
29  * Prototypes
30  ******************************************************************************/
31 
32 /*******************************************************************************
33  * Variables
34  ******************************************************************************/
35 
36 /*******************************************************************************
37  * Code
38  ******************************************************************************/
39 /* Currently only 1 audio instance is adequate, so index is just ignored */
SRTM_I2CCodecAdapter_SetParam(srtm_codec_adapter_t adapter,uint8_t index,uint8_t format,uint32_t srate)40 static srtm_status_t SRTM_I2CCodecAdapter_SetParam(srtm_codec_adapter_t adapter,
41                                                    uint8_t index,
42                                                    uint8_t format,
43                                                    uint32_t srate)
44 {
45     srtm_i2c_codec_adapter_t handle = (srtm_i2c_codec_adapter_t)(void *)adapter;
46     SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s: %d. fmt %d, srate %d\r\n", __func__, index, format, srate);
47     uint32_t bitWidth = 0U;
48 
49     if (format > (uint8_t)SRTM_Audio_DSD32bits)
50     {
51         SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%s: unsupported format %d!\r\n", __func__, format);
52         return SRTM_Status_InvalidParameter;
53     }
54 
55     if (handle->srate != srate || handle->format != format)
56     {
57         handle->format = format;
58 
59         if (format >= (uint8_t)SRTM_Audio_DSD8bits)
60         {
61             (void)CODEC_ModuleControl(handle->driver, kCODEC_ModuleSwitchI2SInInterface,
62                                       kCODEC_ModuleI2SInInterfaceDSD);
63         }
64         else
65         {
66             (void)CODEC_ModuleControl(handle->driver, kCODEC_ModuleSwitchI2SInInterface,
67                                       kCODEC_ModuleI2SInInterfacePCM);
68         }
69 
70         if ((format >= (uint8_t)SRTM_Audio_DSD8bits) && (format <= (uint8_t)SRTM_Audio_DSD32bits))
71         {
72             bitWidth = saiFormatMap[format - 45U].bitwidth;
73         }
74         else if (format <= (uint8_t)SRTM_Audio_Stereo32Bits)
75         {
76             bitWidth = saiFormatMap[format].bitwidth;
77         }
78         else
79         {
80             return SRTM_Status_Error;
81         }
82 
83         /* Only set codec when configuration changes. */
84         (void)CODEC_SetFormat(handle->driver, handle->config.mclk, srate, bitWidth);
85         handle->srate = srate;
86     }
87 
88     return SRTM_Status_Success;
89 }
90 
SRTM_I2CCodecAdapter_SetReg(srtm_codec_adapter_t adapter,uint32_t reg,uint32_t regVal)91 static srtm_status_t SRTM_I2CCodecAdapter_SetReg(srtm_codec_adapter_t adapter, uint32_t reg, uint32_t regVal)
92 {
93     srtm_i2c_codec_adapter_t handle = (srtm_i2c_codec_adapter_t)(void *)adapter;
94     status_t status;
95 
96     SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s: %d, %d\r\n", __func__, reg, regVal);
97 
98     if (handle->config.writeRegMap != NULL)
99     {
100         status = handle->config.writeRegMap(handle->driver, reg, regVal);
101     }
102     else
103     {
104         status =
105             CODEC_I2C_Send(handle->config.i2cHandle, handle->config.slaveAddr, reg, (uint8_t)handle->config.addrType,
106                            (uint8_t *)(&regVal), (uint8_t)handle->config.regWidth);
107     }
108     return status == kStatus_Success ? SRTM_Status_Success : SRTM_Status_Error;
109 }
110 
SRTM_I2CCodecAdapter_GetReg(srtm_codec_adapter_t adapter,uint32_t reg,uint32_t * pRegVal)111 static srtm_status_t SRTM_I2CCodecAdapter_GetReg(srtm_codec_adapter_t adapter, uint32_t reg, uint32_t *pRegVal)
112 {
113     srtm_i2c_codec_adapter_t handle = (srtm_i2c_codec_adapter_t)(void *)adapter;
114     status_t status;
115 
116     assert(pRegVal != NULL);
117 
118     SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s: %d\r\n", __func__, reg);
119 
120     *pRegVal = 0; /* Clear high bytes. */
121     if (handle->config.readRegMap != NULL)
122     {
123         status = handle->config.readRegMap(handle->driver, reg, pRegVal);
124     }
125     else
126     {
127         status = CODEC_I2C_Receive(handle->config.i2cHandle, handle->config.slaveAddr, reg,
128                                    (uint8_t)handle->config.addrType, (void *)pRegVal, (uint8_t)handle->config.regWidth);
129     }
130     return status == kStatus_Success ? SRTM_Status_Success : SRTM_Status_Error;
131 }
132 
SRTM_I2CCodecAdapter_Create(codec_handle_t * driver,srtm_i2c_codec_config_t * config)133 srtm_codec_adapter_t SRTM_I2CCodecAdapter_Create(codec_handle_t *driver, srtm_i2c_codec_config_t *config)
134 {
135     srtm_i2c_codec_adapter_t handle;
136 
137     assert((driver != NULL) && (config != NULL));
138 
139     SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
140 
141     handle = (srtm_i2c_codec_adapter_t)SRTM_Heap_Malloc(sizeof(struct _srtm_i2c_codec_adapter));
142     assert(handle != NULL);
143 
144     handle->driver = driver;
145     (void)memcpy(&handle->config, config, sizeof(struct _srtm_i2c_codec_config));
146     handle->srate  = 0;
147     handle->format = 0;
148 
149     /* Adapter interfaces. */
150     handle->adapter.setParam = SRTM_I2CCodecAdapter_SetParam;
151     handle->adapter.setReg   = SRTM_I2CCodecAdapter_SetReg;
152     handle->adapter.getReg   = SRTM_I2CCodecAdapter_GetReg;
153 
154     return &handle->adapter;
155 }
156 
SRTM_I2CCodecAdapter_Destroy(srtm_codec_adapter_t adapter)157 void SRTM_I2CCodecAdapter_Destroy(srtm_codec_adapter_t adapter)
158 {
159     srtm_i2c_codec_adapter_t handle = (srtm_i2c_codec_adapter_t)(void *)adapter;
160 
161     assert(adapter != NULL);
162 
163     SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
164 
165     SRTM_Heap_Free(handle);
166 }
167