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