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