• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021–2022 Beijing OSWare Technology Co., Ltd
3  * This file contains confidential and proprietary information of
4  * OSWare Technology Co., Ltd
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <linux/dma-mapping.h>
20 
21 #include "imx8mm_platform.h"
22 #include "imx8mm_common.h"
23 #include "audio_platform_base.h"
24 #include "audio_sapm.h"
25 #include "audio_driver_log.h"
26 #include "osal_io.h"
27 #include "osal_uaccess.h"
28 #include "osal_time.h"
29 #include "dma_driver.h"
30 
31 #define RATE_48000  (48000)
32 #define RATE_44100  (44100)
33 #define RATE_24576000  (24576000)
34 #define RATE_22579200  (22579200)
35 #define HDF_LOG_TAG imx8mm_platform_ops
36 int32_t g_dmaRequestChannel = 0;
37 
Imx8mmDmaBufAlloc(struct PlatformData * data,const enum AudioStreamType streamType)38 int32_t Imx8mmDmaBufAlloc(struct PlatformData *data, const enum AudioStreamType streamType)
39 {
40     int32_t ret = HDF_SUCCESS;
41 
42     if (data == NULL) {
43         AUDIO_DRIVER_LOG_ERR("data is null");
44         return HDF_FAILURE;
45     }
46 
47     if (AUDIO_RENDER_STREAM == streamType) {
48         ret = DMAInitTxBuff(data);
49         if (ret != HDF_SUCCESS) {
50             AUDIO_DRIVER_LOG_ERR("Imx8mmDmaBufAlloc: fail");
51             return HDF_FAILURE;
52         }
53     } else if (AUDIO_CAPTURE_STREAM == streamType) {
54         ret = DMAInitRxBuff(data);
55         if (ret != HDF_SUCCESS) {
56             AUDIO_DRIVER_LOG_ERR("Imx8mmDmaBufAlloc: fail");
57             return HDF_FAILURE;
58         }
59     } else {
60         AUDIO_DRIVER_LOG_ERR("stream Type is invalude.");
61         return HDF_FAILURE;
62     }
63 
64     return HDF_SUCCESS;
65 }
66 
Imx8mmDmaBufFree(struct PlatformData * data,const enum AudioStreamType streamType)67 int32_t Imx8mmDmaBufFree(struct PlatformData *data, const enum AudioStreamType streamType)
68 {
69     if (data == NULL) {
70         AUDIO_DRIVER_LOG_ERR("data is null");
71         return HDF_FAILURE;
72     }
73 
74     if (streamType == AUDIO_CAPTURE_STREAM) {
75         if (data->captureBufInfo.virtAddr != NULL) {
76             (void)DMADeinitRxBuff(data);
77         }
78     } else if (streamType == AUDIO_RENDER_STREAM) {
79         if (data->renderBufInfo.virtAddr != NULL) {
80             (void)DMADeinitTxBuff(data);
81         }
82     } else {
83         AUDIO_DRIVER_LOG_ERR("stream Type is invalude.");
84         return HDF_FAILURE;
85     }
86 
87     return HDF_SUCCESS;
88 }
89 
90 #define BYTE_NUM  (2)
Imx8mmDmaRequestChannel(const struct PlatformData * data,const enum AudioStreamType streamType)91 int32_t  Imx8mmDmaRequestChannel(const struct PlatformData *data, const enum AudioStreamType streamType)
92 {
93     int32_t ret;
94     uint32_t fmt = 0, freq = 0, clkId = 0, rate = 0, bitWidth = 0;
95     int channel = 0;
96     g_dmaRequestChannel = false;
97 
98     if (data == NULL) {
99         return HDF_FAILURE;
100     }
101 
102     if (streamType == AUDIO_RENDER_STREAM) {
103         channel = data->renderPcmInfo.channels;
104         rate = data->renderPcmInfo.rate;
105         bitWidth = data->renderPcmInfo.bitWidth;
106     } else if (streamType == AUDIO_CAPTURE_STREAM) {
107         channel = data->capturePcmInfo.channels;
108         rate = data->capturePcmInfo.rate;
109         bitWidth = data->capturePcmInfo.bitWidth;
110     } else {
111         return HDF_FAILURE;
112     }
113 
114     fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_NB_NF;
115     if (rate == RATE_48000) {
116         freq = RATE_24576000;
117     } else if (rate == RATE_44100) {
118         freq = RATE_22579200;
119     }
120 
121     clkId = FSL_SAI_CLK_MAST1;
122 
123     ret = SaiRuntimeResume(data);
124     if (ret != HDF_SUCCESS) {
125         return ret;
126     }
127 
128     ret = SaiSetDaiFmt(data, fmt);
129     if (ret != HDF_SUCCESS) {
130         return ret;
131     }
132 
133     ret = SaiSetDaiTdmSlot(data, 0, 0, BYTE_NUM, bitWidth);
134     if (ret != HDF_SUCCESS) {
135         return ret;
136     }
137 
138     ret = SaiSetSysclk(data, clkId, freq, SOC_CLOCK_OUT);
139     if (ret != HDF_SUCCESS) {
140         return ret;
141     }
142 
143     ret = SaiSetHwParams(data, streamType);
144     if (ret != HDF_SUCCESS) {
145         return ret;
146     }
147 
148     g_dmaRequestChannel = true;
149     return HDF_SUCCESS;
150 }
151 
Imx8mmDmaConfigChannel(const struct PlatformData * data,const enum AudioStreamType streamType)152 int32_t Imx8mmDmaConfigChannel(const struct PlatformData *data, const enum AudioStreamType streamType)
153 {
154     int32_t ret;
155     struct PlatformData *platformData;
156 
157     platformData = (struct PlatformData *)data;
158 
159     if (streamType == AUDIO_CAPTURE_STREAM) {
160         if (platformData->captureBufInfo.virtAddr != NULL) {
161             ret = DMAConfigRxBuff(platformData);
162             if (ret != HDF_SUCCESS) {
163                 AUDIO_DRIVER_LOG_ERR("DMAAiInit: fail");
164                 return HDF_FAILURE;
165             }
166         }
167     } else if (streamType == AUDIO_RENDER_STREAM) {
168         if (data->renderBufInfo.virtAddr != NULL) {
169             ret = DMAConfigTxBuff((struct PlatformData *)data);
170             if (ret != HDF_SUCCESS) {
171                 AUDIO_DRIVER_LOG_ERR("DMAAoInit: fail");
172                 return HDF_FAILURE;
173             }
174         }
175         ret = DMAEnableTx(data);
176         if (ret != HDF_SUCCESS) {
177             AUDIO_DRIVER_LOG_ERR("DMAEnableTx failed");
178             return HDF_FAILURE;
179         }
180     } else {
181         AUDIO_DRIVER_LOG_ERR("stream Type is invalude.");
182         return HDF_FAILURE;
183     }
184 
185     return HDF_SUCCESS;
186 }
187 
Imx8mmDmaPrep(const struct PlatformData * data,const enum AudioStreamType streamType)188 int32_t Imx8mmDmaPrep(const struct PlatformData *data, const enum AudioStreamType streamType)
189 {
190     (void)data;
191     (void)streamType;
192     return HDF_SUCCESS;
193 }
194 
Imx8mmDmaSubmit(const struct PlatformData * data,const enum AudioStreamType streamType)195 int32_t Imx8mmDmaSubmit(const struct PlatformData *data, const enum AudioStreamType streamType)
196 {
197     int ret = 0;
198     struct PlatformData *platformData;
199 
200     platformData = (struct PlatformData *)data;
201 
202     if (data == NULL) {
203         AUDIO_DRIVER_LOG_ERR("data is null");
204         return HDF_FAILURE;
205     }
206 
207     if (streamType == AUDIO_CAPTURE_STREAM) {
208         ret = DMAEnableRx(data);
209         if (ret != HDF_SUCCESS) {
210             AUDIO_DRIVER_LOG_ERR("DMAEnableRx failed");
211             return HDF_FAILURE;
212         }
213     } else if (streamType == AUDIO_RENDER_STREAM) {
214         // delete dmaEnable because 1.after pause remalloc DMA buffer 2.DMA process must before sai trigger
215     } else {
216         AUDIO_DRIVER_LOG_ERR("stream Type is invalude.");
217         return HDF_FAILURE;
218     }
219 
220     return HDF_SUCCESS;
221 }
222 
Imx8mmDmaPending(struct PlatformData * data,const enum AudioStreamType streamType)223 int32_t Imx8mmDmaPending(struct PlatformData *data, const enum AudioStreamType streamType)
224 {
225     (void)data;
226     (void)streamType;
227     return HDF_SUCCESS;
228 }
229 
Imx8mmDmaPause(struct PlatformData * data,const enum AudioStreamType streamType)230 int32_t Imx8mmDmaPause(struct PlatformData *data, const enum AudioStreamType streamType)
231 {
232     struct PrivPlatformData *ppd = NULL;
233 
234     if (data == NULL) {
235         AUDIO_DRIVER_LOG_ERR("data is null");
236         return HDF_FAILURE;
237     }
238 
239     ppd = (struct PrivPlatformData *)data->dmaPrv;
240 
241     if (streamType == AUDIO_CAPTURE_STREAM) {
242         DMAPauseRx(data);
243     } else if (streamType == AUDIO_RENDER_STREAM) {
244         data->renderBufInfo.runStatus = 0;
245         // change Disable DMA becasue 1.after pause remalloc DMA buffer
246         DMADisableTx(data);
247         ppd->tx_dma_pos = 0;
248     } else {
249         AUDIO_DRIVER_LOG_ERR("stream Type is invalude.");
250         return HDF_FAILURE;
251     }
252     return HDF_SUCCESS;
253 }
254 
Imx8mmDmaResume(const struct PlatformData * data,const enum AudioStreamType streamType)255 int32_t Imx8mmDmaResume(const struct PlatformData *data, const enum AudioStreamType streamType)
256 {
257     int ret = 0;
258 
259     if (data == NULL) {
260         AUDIO_DRIVER_LOG_ERR("data is null");
261         return HDF_FAILURE;
262     }
263 
264     if (streamType == AUDIO_CAPTURE_STREAM) {
265         ret = DMAEnableRx(data);
266         if (ret != HDF_SUCCESS) {
267             AUDIO_DRIVER_LOG_ERR("DMAEnableRx failed");
268             return HDF_FAILURE;
269         }
270     } else if (streamType == AUDIO_RENDER_STREAM) {
271         ret = DMAEnableTx(data);
272         if (ret != HDF_SUCCESS) {
273             AUDIO_DRIVER_LOG_ERR("DMAEnableTx failed");
274             return HDF_FAILURE;
275         }
276     }
277 
278     return HDF_SUCCESS;
279 }
280 
Imx8mmDmaPointer(struct PlatformData * data,const enum AudioStreamType streamType,uint32_t * pointer)281 int32_t Imx8mmDmaPointer(struct PlatformData *data, const enum AudioStreamType streamType, uint32_t *pointer)
282 {
283     struct PrivPlatformData *ppd = NULL;
284 
285     if (data == NULL || pointer == NULL) {
286         AUDIO_DRIVER_LOG_ERR("data is null");
287         return HDF_FAILURE;
288     }
289 
290     ppd = (struct PrivPlatformData *)data->dmaPrv;
291 
292     if (streamType == AUDIO_RENDER_STREAM) {
293         OsalMutexLock(&data->renderBufInfo.buffMutex);
294         *pointer = (ppd->tx_dma_pos) / (data->renderPcmInfo.frameSize);
295         OsalMutexUnlock(&data->renderBufInfo.buffMutex);
296     } else if (streamType == AUDIO_CAPTURE_STREAM) {
297         OsalMutexLock(&data->captureBufInfo.buffMutex);
298         *pointer = (ppd->rx_dma_pos) / (data->capturePcmInfo.frameSize);
299         OsalMutexUnlock(&data->captureBufInfo.buffMutex);
300     } else {
301         AUDIO_DRIVER_LOG_ERR("stream Type is fail.");
302         return HDF_FAILURE;
303     }
304 
305     return HDF_SUCCESS;
306 }
307