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 *)(®Val), (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