1 /*
2 * Copyright (C) 2022 HiHope Open Source Organization .
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8 #include <sound/pcm_params.h>
9 #include <sound/dmaengine_pcm.h>
10 #include <linux/module.h>
11 #include <linux/mfd/syscon.h>
12 #include <linux/delay.h>
13 #include <linux/of_gpio.h>
14 #include <linux/of_device.h>
15 #include <linux/of_address.h>
16 #include <linux/clk.h>
17 #include <linux/clk/rockchip.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/regmap.h>
20 #include <linux/reset.h>
21 #include <linux/spinlock.h>
22
23 #include "audio_host.h"
24 #include "audio_control.h"
25 #include "audio_dai_if.h"
26 #include "audio_dai_base.h"
27 #include "audio_driver_log.h"
28 #include "audio_stream_dispatch.h"
29 #include "osal_io.h"
30 #include "rk3588_audio_common.h"
31 #include "audio_platform_base.h"
32 #include "rk3588_dai_ops.h"
33 #include "rk3588_dai_linux.h"
34
35 #define HDF_LOG_TAG rk3588_dai_ops
36
37
38 void *g_regDaiBase = NULL;
39 static const char *g_i2s1DtsTreePath = "/i2s@fe470000";
40 static struct platform_device *g_platformDev;
41
getPlatformDev(void)42 struct platform_device *getPlatformDev(void)
43 {
44 struct device_node *dmaOfNode;
45 dmaOfNode = of_find_node_by_path(g_i2s1DtsTreePath);
46 if (dmaOfNode == NULL) {
47 AUDIO_DEVICE_LOG_ERR("get device node failed.");
48 return NULL;
49 }
50 g_platformDev = of_find_device_by_node(dmaOfNode);
51 return g_platformDev;
52 }
53
Rk3588DeviceReadReg(const struct DaiDevice * dai,uint32_t reg,uint32_t * val)54 int32_t Rk3588DeviceReadReg(const struct DaiDevice *dai, uint32_t reg, uint32_t *val)
55 {
56 struct platform_device *platformdev = getPlatformDev();
57 struct rk3588_i2s_tdm_dev *i2sTdm = NULL;
58
59 if (platformdev == NULL) {
60 AUDIO_DEVICE_LOG_ERR("platformdev is null");
61 return HDF_FAILURE;
62 }
63 (void)dai;
64 i2sTdm = dev_get_drvdata(&platformdev->dev);
65 if (i2sTdm == NULL) {
66 AUDIO_DEVICE_LOG_ERR("i2sTdm is null");
67 return HDF_FAILURE;
68 }
69
70 if (regmap_read(i2sTdm->regmap, reg, val)) {
71 AUDIO_DEVICE_LOG_ERR("read register fail: [%04x]", reg);
72 return HDF_FAILURE;
73 }
74
75 AUDIO_DEVICE_LOG_DEBUG("success");
76 return HDF_SUCCESS;
77 }
78
Rk3588DeviceWriteReg(const struct DaiDevice * dai,uint32_t reg,uint32_t value)79 int32_t Rk3588DeviceWriteReg(const struct DaiDevice *dai, uint32_t reg, uint32_t value)
80 {
81 struct platform_device *platformdev = getPlatformDev();
82 struct rk3588_i2s_tdm_dev *i2sTdm = NULL;
83 (void)dai;
84
85 if (platformdev == NULL) {
86 AUDIO_DEVICE_LOG_ERR("platformdev is null");
87 return HDF_FAILURE;
88 }
89 i2sTdm = dev_get_drvdata(&platformdev->dev);
90 if (i2sTdm == NULL) {
91 AUDIO_DEVICE_LOG_ERR("i2sTdm is null");
92 return HDF_FAILURE;
93 }
94
95 if (regmap_write(i2sTdm->regmap, reg, value)) {
96 AUDIO_DEVICE_LOG_ERR("write register fail: [%04x] = %04x", reg, value);
97 return HDF_FAILURE;
98 }
99
100 AUDIO_DEVICE_LOG_DEBUG("success");
101 return HDF_SUCCESS;
102 }
103
Rk3588DaiDeviceInit(struct AudioCard * card,const struct DaiDevice * dai)104 int32_t Rk3588DaiDeviceInit(struct AudioCard *card, const struct DaiDevice *dai)
105 {
106 struct DaiData *data;
107
108 if (dai == NULL || dai->device == NULL || dai->devDaiName == NULL) {
109 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
110 return HDF_ERR_INVALID_PARAM;
111 }
112 if (dai == NULL || dai->devData == NULL) {
113 AUDIO_DEVICE_LOG_ERR("dai host is NULL.");
114 return HDF_FAILURE;
115 }
116 data = dai->devData;
117 if (DaiSetConfigInfoOfControls(data) != HDF_SUCCESS) {
118 AUDIO_DEVICE_LOG_ERR("set config info fail.");
119 return HDF_FAILURE;
120 }
121
122 if (g_regDaiBase == NULL) {
123 g_regDaiBase = OsalIoRemap(data->regConfig->audioIdInfo.chipIdRegister,
124 data->regConfig->audioIdInfo.chipIdSize);
125 if (g_regDaiBase == NULL) {
126 AUDIO_DEVICE_LOG_ERR("OsalIoRemap fail.");
127 return HDF_FAILURE;
128 }
129 }
130 data->regVirtualAddr = (uintptr_t)g_regDaiBase;
131
132 if (dai->devData->daiInitFlag == true) {
133 AUDIO_DRIVER_LOG_DEBUG("dai init complete!");
134 return HDF_SUCCESS;
135 }
136
137 dai->devData->daiInitFlag = true;
138 AUDIO_DEVICE_LOG_DEBUG("success");
139 return HDF_SUCCESS;
140 }
141
Rk3588DaiStartup(const struct AudioCard * card,const struct DaiDevice * dai)142 int32_t Rk3588DaiStartup(const struct AudioCard *card, const struct DaiDevice *dai)
143 {
144 (void)card;
145 (void)dai;
146 return HDF_SUCCESS;
147 }
148
RK3588SetI2sFomartVal(const struct AudioPcmHwParams * param)149 int RK3588SetI2sFomartVal(const struct AudioPcmHwParams *param)
150 {
151 int32_t val = 0;
152 if (param == NULL) {
153 AUDIO_DEVICE_LOG_ERR("input param is null.");
154 return -1;
155 }
156 switch (param->format) {
157 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
158 val |= I2S_TXCR_VDW(8); // 8-bit
159 break;
160 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
161 val |= I2S_TXCR_VDW(16); // 16-bit
162 break;
163 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
164 val |= I2S_TXCR_VDW(24); // 24-bit
165 break;
166 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
167 val |= I2S_TXCR_VDW(32); // 32-bit
168 break;
169 default:
170 AUDIO_DEVICE_LOG_ERR("format error, format is 0x%x", param->format);
171 return -1;
172 }
173 AUDIO_DEVICE_LOG_DEBUG("sucess");
174 return val;
175 }
176
RK3588SetI2sChannels(struct rk3588_i2s_tdm_dev * i2sTdm,const struct AudioPcmHwParams * param)177 int32_t RK3588SetI2sChannels(struct rk3588_i2s_tdm_dev *i2sTdm, const struct AudioPcmHwParams *param)
178 {
179 unsigned int regFmt, fmt;
180 int32_t ret = 0;
181
182 if (i2sTdm == NULL || param == NULL) {
183 AUDIO_DEVICE_LOG_ERR("input param is null.");
184 return HDF_FAILURE;
185 }
186 if (param->streamType == AUDIO_RENDER_STREAM) {
187 regFmt = I2S_TXCR;
188 } else {
189 regFmt = I2S_RXCR;
190 }
191
192 regmap_read(i2sTdm->regmap, regFmt, &fmt);
193 fmt &= I2S_TXCR_TFS_MASK;
194 if (fmt == 0) { // I2S mode
195 switch (param->channels) {
196 case 8: // channels is 8
197 ret = I2S_CHN_8;
198 break;
199 case 6: // channels is 6
200 ret = I2S_CHN_6;
201 break;
202 case 4: // channels is 4
203 ret = I2S_CHN_4;
204 break;
205 case 2: // channels is 2
206 ret = I2S_CHN_2;
207 break;
208 default:
209 ret = -EINVAL;
210 break;
211 }
212 }
213 AUDIO_DEVICE_LOG_DEBUG("success");
214 return ret;
215 }
216
ConfigInfoSetToReg(struct rk3588_i2s_tdm_dev * i2sTdm,const struct AudioPcmHwParams * param,unsigned int div_bclk,unsigned int div_lrck,int32_t fmt)217 int32_t ConfigInfoSetToReg(struct rk3588_i2s_tdm_dev *i2sTdm, const struct AudioPcmHwParams *param,
218 unsigned int div_bclk, unsigned int div_lrck, int32_t fmt)
219 {
220 if (i2sTdm == NULL || param == NULL) {
221 AUDIO_DEVICE_LOG_ERR("input para is null.");
222 return HDF_FAILURE;
223 }
224
225 regmap_update_bits(i2sTdm->regmap, I2S_CLKDIV,
226 I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK,
227 I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk));
228 regmap_update_bits(i2sTdm->regmap, I2S_CKR,
229 I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK,
230 I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck));
231
232 if (param->streamType == AUDIO_RENDER_STREAM) {
233 regmap_update_bits(i2sTdm->regmap, I2S_TXCR,
234 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
235 fmt);
236 } else {
237 regmap_update_bits(i2sTdm->regmap, I2S_RXCR,
238 I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
239 fmt);
240 }
241 AUDIO_DEVICE_LOG_DEBUG("success");
242 return HDF_SUCCESS;
243 }
244
245 // i2s_tdm->mclk_tx_freq ? i2s_tdm->mclk_rx_freq ?
RK3588I2sTdmSetMclk(struct rk3588_i2s_tdm_dev * i2sTdm,const struct AudioPcmHwParams * param)246 int32_t RK3588I2sTdmSetMclk(struct rk3588_i2s_tdm_dev *i2sTdm, const struct AudioPcmHwParams *param)
247 {
248 int32_t ret = 0;
249 unsigned int mclkRate = 0;
250 unsigned int bclkRate = 0;
251 unsigned int bclkDiv = 0;
252 unsigned int lrclkDiv = 0;
253 int32_t fmt = 0;
254 int32_t channels = 0;
255 if (i2sTdm == NULL || param == NULL) {
256 AUDIO_DEVICE_LOG_ERR("input param is null.");
257 return HDF_FAILURE;
258 }
259
260 if (param->streamType == AUDIO_RENDER_STREAM) {
261 ret = clk_set_rate(i2sTdm->mclk_tx, i2sTdm->mclk_tx_freq);
262 if (ret) {
263 AUDIO_DEVICE_LOG_ERR(" clk_set_rate ret = %d", ret);
264 return ret;
265 }
266 mclkRate = clk_get_rate(i2sTdm->mclk_tx);
267 } else if (param->streamType == AUDIO_CAPTURE_STREAM) {
268 ret = clk_set_rate(i2sTdm->mclk_rx, i2sTdm->mclk_rx_freq);
269 if (ret) {
270 AUDIO_DEVICE_LOG_ERR(" clk_set_rate ret = %d", ret);
271 return ret;
272 }
273 mclkRate = clk_get_rate(i2sTdm->mclk_rx);
274 } else {
275 AUDIO_DEVICE_LOG_ERR("streamType is invalid.");
276 return HDF_FAILURE;
277 }
278
279 bclkRate = i2sTdm->bclk_fs * param->rate;
280 bclkDiv = DIV_ROUND_CLOSEST(mclkRate, bclkRate);
281 lrclkDiv = bclkRate / param->rate;
282 fmt = RK3588SetI2sFomartVal(param);
283 if (fmt < 0) {
284 AUDIO_DEVICE_LOG_ERR(" RK3588SetI2sFomartVal fmt = %d", fmt);
285 return HDF_FAILURE;
286 }
287 channels = RK3588SetI2sChannels(i2sTdm, param);
288 if (channels < 0) {
289 AUDIO_DEVICE_LOG_ERR(" RK3588SetI2sFomartVal channels = %d", channels);
290 return HDF_FAILURE;
291 }
292
293 fmt |= channels;
294 ret = ConfigInfoSetToReg(i2sTdm, param, bclkDiv, lrclkDiv, fmt);
295 if (ret != HDF_SUCCESS) {
296 AUDIO_DEVICE_LOG_ERR(" ConfigInfoSetToReg ret= %d", ret);
297 return HDF_FAILURE;
298 }
299
300 AUDIO_DEVICE_LOG_DEBUG("success");
301 return HDF_SUCCESS;
302 }
303
RK3588I2sTdmSetSysClk(struct rk3588_i2s_tdm_dev * i2sTdm,const struct AudioPcmHwParams * param)304 int32_t RK3588I2sTdmSetSysClk(struct rk3588_i2s_tdm_dev *i2sTdm, const struct AudioPcmHwParams *param)
305 {
306 uint32_t sampleRate;
307 uint32_t mclk_parent_freq = 0;
308
309 if (i2sTdm == NULL || param == NULL) {
310 AUDIO_DEVICE_LOG_ERR("input para is null.");
311 return HDF_FAILURE;
312 }
313 sampleRate = param->rate;
314
315 /* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */
316 switch (sampleRate) {
317 case AUDIO_DEVICE_SAMPLE_RATE_8000:
318 case AUDIO_DEVICE_SAMPLE_RATE_16000:
319 case AUDIO_DEVICE_SAMPLE_RATE_24000:
320 case AUDIO_DEVICE_SAMPLE_RATE_32000:
321 case AUDIO_DEVICE_SAMPLE_RATE_48000:
322 case AUDIO_DEVICE_SAMPLE_RATE_64000:
323 case AUDIO_DEVICE_SAMPLE_RATE_96000:
324 mclk_parent_freq = i2sTdm->bclk_fs * AUDIO_DEVICE_SAMPLE_RATE_192000;
325 break;
326 case AUDIO_DEVICE_SAMPLE_RATE_11025:
327 case AUDIO_DEVICE_SAMPLE_RATE_22050:
328 case AUDIO_DEVICE_SAMPLE_RATE_44100:
329 mclk_parent_freq = i2sTdm->bclk_fs * AUDIO_DEVICE_SAMPLE_RATE_176400;
330 break;
331 default:
332 AUDIO_DEVICE_LOG_ERR("Invalid LRCK freq: %u Hz\n", sampleRate);
333 return HDF_FAILURE;
334 }
335 i2sTdm->mclk_tx_freq = mclk_parent_freq;
336 i2sTdm->mclk_rx_freq = mclk_parent_freq;
337
338 return HDF_SUCCESS;
339 }
340
Rk3588DaiHwParams(const struct AudioCard * card,const struct AudioPcmHwParams * param)341 int32_t Rk3588DaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param)
342 {
343 int ret;
344 uint32_t bitWidth;
345 struct DaiData *data = DaiDataFromCard(card);
346 struct platform_device *platformdev = getPlatformDev();
347 struct rk3588_i2s_tdm_dev *i2sTdm = NULL;
348
349 if (data == NULL || platformdev == NULL) {
350 AUDIO_DEVICE_LOG_ERR("platformHost is nullptr.");
351 return HDF_FAILURE;
352 }
353 if (param == NULL || param->cardServiceName == NULL) {
354 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
355 return HDF_ERR_INVALID_PARAM;
356 }
357 data->pcmInfo.channels = param->channels;
358
359 AUDIO_DEVICE_LOG_DEBUG("channels count : %d .", param->channels);
360 if (AudioFormatToBitWidth(param->format, &bitWidth) != HDF_SUCCESS) {
361 AUDIO_DEVICE_LOG_ERR("AudioFormatToBitWidth error");
362 return HDF_FAILURE;
363 }
364 data->pcmInfo.bitWidth = bitWidth;
365 data->pcmInfo.rate = param->rate;
366 data->pcmInfo.streamType = param->streamType;
367
368 i2sTdm = dev_get_drvdata(&platformdev->dev);
369 ret = RK3588I2sTdmSetSysClk(i2sTdm, param);
370 if (ret != HDF_SUCCESS) {
371 AUDIO_DEVICE_LOG_ERR("RK3588I2sTdmSetSysClk error");
372 return HDF_FAILURE;
373 }
374
375 ret = RK3588I2sTdmSetMclk(i2sTdm, param);
376 if (ret != HDF_SUCCESS) {
377 AUDIO_DEVICE_LOG_ERR("RK3588I2sTdmSetMclk error");
378 return HDF_FAILURE;
379 }
380 AUDIO_DEVICE_LOG_DEBUG("success");
381 return HDF_SUCCESS;
382 }
383
GetTriggeredFlag(int cmd)384 static int GetTriggeredFlag(int cmd)
385 {
386 int32_t triggerFlag = false;
387 switch (cmd) {
388 case AUDIO_DRV_PCM_IOCTL_RENDER_START:
389 case AUDIO_DRV_PCM_IOCTL_RENDER_RESUME:
390 case AUDIO_DRV_PCM_IOCTL_CAPTURE_START:
391 case AUDIO_DRV_PCM_IOCTL_CAPTURE_RESUME:
392 triggerFlag = true;
393 break;
394
395 case AUDIO_DRV_PCM_IOCTL_RENDER_STOP:
396 case AUDIO_DRV_PCM_IOCTL_CAPTURE_STOP:
397 case AUDIO_DRV_PCM_IOCTL_RENDER_PAUSE:
398 case AUDIO_DRV_PCM_IOCTL_CAPTURE_PAUSE:
399 triggerFlag = false;
400 break;
401
402 default:
403 triggerFlag = false;
404 }
405 AUDIO_DEVICE_LOG_DEBUG("success");
406 return triggerFlag;
407 }
408
409
GetStreamType(int cmd)410 static int GetStreamType(int cmd)
411 {
412 enum AudioStreamType streamType = AUDIO_CAPTURE_STREAM;
413 switch (cmd) {
414 case AUDIO_DRV_PCM_IOCTL_RENDER_START:
415 case AUDIO_DRV_PCM_IOCTL_RENDER_RESUME:
416 case AUDIO_DRV_PCM_IOCTL_RENDER_STOP:
417 case AUDIO_DRV_PCM_IOCTL_RENDER_PAUSE:
418 streamType = AUDIO_RENDER_STREAM;
419 break;
420 case AUDIO_DRV_PCM_IOCTL_CAPTURE_START:
421 case AUDIO_DRV_PCM_IOCTL_CAPTURE_RESUME:
422 case AUDIO_DRV_PCM_IOCTL_CAPTURE_STOP:
423 case AUDIO_DRV_PCM_IOCTL_CAPTURE_PAUSE:
424 streamType = AUDIO_CAPTURE_STREAM;
425 break;
426
427 default:
428 break;
429 }
430 AUDIO_DEVICE_LOG_DEBUG("success");
431 return streamType;
432 }
433
Rk3588TxAndRxStart(struct rk3588_i2s_tdm_dev * i2sTdm,enum AudioStreamType streamType)434 static int32_t Rk3588TxAndRxStart(struct rk3588_i2s_tdm_dev *i2sTdm, enum AudioStreamType streamType)
435 {
436 uint32_t val = 0;
437
438 if (streamType == AUDIO_RENDER_STREAM) {
439 if (i2sTdm->mclk_tx == NULL) {
440 AUDIO_DEVICE_LOG_ERR("mclk tx is null");
441 return HDF_FAILURE;
442 }
443
444 if (clk_prepare_enable(i2sTdm->mclk_tx) != HDF_SUCCESS) {
445 AUDIO_DEVICE_LOG_ERR("clk_prepare_enable fail");
446 return HDF_FAILURE;
447 }
448
449 if (regmap_update_bits(i2sTdm->regmap, I2S_DMACR, I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE)) {
450 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
451 return HDF_FAILURE;
452 }
453 i2sTdm->txStart = true;
454 } else {
455 if (i2sTdm->mclk_rx == NULL) {
456 AUDIO_DEVICE_LOG_ERR("mclk rx is null");
457 return HDF_FAILURE;
458 }
459
460 if (clk_prepare_enable(i2sTdm->mclk_rx) != HDF_SUCCESS) {
461 AUDIO_DEVICE_LOG_ERR("clk_prepare_enable fail");
462 return HDF_FAILURE;
463 }
464
465 if (regmap_update_bits(i2sTdm->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE)) {
466 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
467 return HDF_FAILURE;
468 }
469
470 if (regmap_read(i2sTdm->regmap, I2S_DMACR, &val)) {
471 AUDIO_DEVICE_LOG_ERR("read register fail: [%04x]", I2S_DMACR);
472 return HDF_FAILURE;
473 }
474 i2sTdm->rxStart = true;
475 }
476
477 if (regmap_update_bits(i2sTdm->regmap, I2S_XFER, I2S_XFER_TXS_START | I2S_XFER_RXS_START,
478 I2S_XFER_TXS_START | I2S_XFER_RXS_START) != HDF_SUCCESS) {
479 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
480 return HDF_FAILURE;
481 }
482
483 if (regmap_read(i2sTdm->regmap, I2S_XFER, &val)) {
484 AUDIO_DEVICE_LOG_ERR("read register fail: [%04x]", I2S_XFER);
485 return HDF_FAILURE;
486 }
487
488 return HDF_SUCCESS;
489 }
490
Rk3588TxAndRxStop(struct rk3588_i2s_tdm_dev * i2sTdm,enum AudioStreamType streamType)491 static int32_t Rk3588TxAndRxStop(struct rk3588_i2s_tdm_dev *i2sTdm, enum AudioStreamType streamType)
492 {
493 uint32_t val = 0;
494 int retry = 10; // retry 10 times
495 int ret;
496
497 if (streamType == AUDIO_RENDER_STREAM) {
498 ret = regmap_update_bits(i2sTdm->regmap, I2S_DMACR, I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
499 if (ret != HDF_SUCCESS) {
500 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
501 return HDF_FAILURE;
502 }
503 i2sTdm->txStart = false;
504 } else {
505 ret = regmap_update_bits(i2sTdm->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
506 if (ret != HDF_SUCCESS) {
507 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
508 return HDF_FAILURE;
509 }
510 i2sTdm->rxStart = false;
511 }
512 if (i2sTdm->txStart || i2sTdm->rxStart) {
513 return HDF_SUCCESS;
514 }
515
516 ret = regmap_update_bits(i2sTdm->regmap, I2S_XFER,
517 I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP);
518 if (ret != HDF_SUCCESS) {
519 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
520 return HDF_FAILURE;
521 }
522
523 udelay(150);
524 ret = regmap_update_bits(i2sTdm->regmap, I2S_CLR, I2S_CLR_TXC | I2S_CLR_RXC, I2S_CLR_TXC | I2S_CLR_RXC);
525 if (ret != HDF_SUCCESS) {
526 AUDIO_DEVICE_LOG_ERR("regmap_update_bits fail");
527 return HDF_FAILURE;
528 }
529
530 ret = regmap_read(i2sTdm->regmap, I2S_CLR, &val);
531 if (ret != HDF_SUCCESS) {
532 AUDIO_DEVICE_LOG_ERR("regmap_read fail");
533 return HDF_FAILURE;
534 }
535
536 /* Should wait for clear operation to finish */
537 while (val && retry > 0) {
538 ret = regmap_read(i2sTdm->regmap, I2S_CLR, &val);
539 if (ret != HDF_SUCCESS) {
540 AUDIO_DEVICE_LOG_ERR("regmap_read fail");
541 return HDF_FAILURE;
542 }
543
544 retry--;
545 }
546
547 return HDF_SUCCESS;
548 }
549
Rk3588TxAndRxSetReg(struct rk3588_i2s_tdm_dev * i2sTdm,enum AudioStreamType streamType,int on)550 static int32_t Rk3588TxAndRxSetReg(struct rk3588_i2s_tdm_dev *i2sTdm,
551 enum AudioStreamType streamType, int on)
552 {
553 int ret;
554
555 if (i2sTdm == NULL || i2sTdm->regmap == NULL) {
556 AUDIO_DEVICE_LOG_ERR("i2sTdm is null");
557 return HDF_FAILURE;
558 }
559
560 if (on) { // when start/resume
561 ret = Rk3588TxAndRxStart(i2sTdm, streamType);
562 if (ret != HDF_SUCCESS) {
563 AUDIO_DEVICE_LOG_ERR("Rk3588TxAndRxStart is failed");
564 return HDF_FAILURE;
565 }
566 } else { // when stop/pause
567 ret = Rk3588TxAndRxStop(i2sTdm, streamType);
568 if (ret != HDF_SUCCESS) {
569 AUDIO_DEVICE_LOG_ERR("Rk3588TxAndRxStop is failed");
570 return HDF_FAILURE;
571 }
572 }
573
574 AUDIO_DEVICE_LOG_DEBUG("success");
575 return HDF_SUCCESS;
576 }
577
578 /* normal scene */
Rk3588NormalTrigger(const struct AudioCard * card,int cmd,const struct DaiDevice * device)579 int32_t Rk3588NormalTrigger(const struct AudioCard *card, int cmd, const struct DaiDevice *device)
580 {
581 struct platform_device *platformdev = getPlatformDev();
582 struct rk3588_i2s_tdm_dev *i2sTdm = NULL;
583 int32_t triggerFlag = GetTriggeredFlag(cmd);
584 enum AudioStreamType streamType = GetStreamType(cmd);
585 int ret;
586
587 if (platformdev == NULL) {
588 AUDIO_DEVICE_LOG_ERR("platformdev is null");
589 return HDF_FAILURE;
590 }
591
592 i2sTdm = dev_get_drvdata(&platformdev->dev);
593 ret = Rk3588TxAndRxSetReg(i2sTdm, streamType, triggerFlag);
594 if (ret != HDF_SUCCESS) {
595 AUDIO_DEVICE_LOG_ERR("Rk3588TxAndRxSetReg is failed");
596 return HDF_FAILURE;
597 }
598
599 AUDIO_DEVICE_LOG_DEBUG("success");
600 return HDF_SUCCESS;
601 }
602