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/clk.h>
20 #include <linux/clk/clk-conf.h>
21 #include <linux/clk-provider.h>
22 #include <linux/delay.h>
23 #include <linux/dmaengine.h>
24 #include <linux/module.h>
25 #include <linux/of_address.h>
26 #include <linux/of_device.h>
27 #include <linux/pm_runtime.h>
28 #include <linux/regmap.h>
29 #include <linux/slab.h>
30 #include <linux/time.h>
31 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
32 #include <linux/mfd/syscon.h>
33 #include <linux/interrupt.h>
34 #include <linux/pinctrl/consumer.h>
35 #include <linux/busfreq-imx.h>
36
37 #include "audio_driver_log.h"
38 #include "imx8mm_platform.h"
39 #include "imx8mm_common.h"
40 #include "osal_mem.h"
41 #include "sai_driver.h"
42
43 #include "osal_io.h"
44 #include "osal_irq.h"
45 #include "osal_sem.h"
46 #include "osal_time.h"
47
48 #define HDF_LOG_TAG imx8mm_sai_driver
49
50 #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE | FSL_SAI_CSR_FEIE)
51
52 #define FSL_SAI_VERID_0301 (0x0301)
53 struct fsl_sai *g_sai;
54 #define BYTE_NUM (8)
55
GetDrvSai(const struct PlatformData * pd)56 static struct fsl_sai *GetDrvSai(const struct PlatformData *pd)
57 {
58 struct PrivPlatformData *ppd = NULL;
59 if (pd == NULL) {
60 AUDIO_DRIVER_LOG_ERR("get drv sai: the input platform data is null");
61 return NULL;
62 }
63 ppd = (struct PrivPlatformData *)pd->dmaPrv;
64 if (ppd != NULL) {
65 return &(ppd->sai);
66 }
67
68 return NULL;
69 }
70
SaiPrintTFRegister(void)71 int32_t SaiPrintTFRegister(void)
72 {
73 struct fsl_sai *sai = g_sai;
74 u32 read_val = 0;
75
76 regmap_read(sai->regmap, FSL_SAI_TFR0, &read_val);
77 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR0 %08x", read_val);
78 regmap_read(sai->regmap, FSL_SAI_TFR1, &read_val);
79 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR1 %08x", read_val);
80 regmap_read(sai->regmap, FSL_SAI_TFR2, &read_val);
81 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR2 %08x", read_val);
82 regmap_read(sai->regmap, FSL_SAI_TFR3, &read_val);
83 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR3 %08x", read_val);
84 regmap_read(sai->regmap, FSL_SAI_TFR4, &read_val);
85 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR4 %08x", read_val);
86 regmap_read(sai->regmap, FSL_SAI_TFR5, &read_val);
87 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR5 %08x", read_val);
88 regmap_read(sai->regmap, FSL_SAI_TFR6, &read_val);
89 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR6 %08x", read_val);
90 regmap_read(sai->regmap, FSL_SAI_TFR7, &read_val);
91 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TFR7 %08x", read_val);
92
93 return 0;
94 }
95
SaiPrintTDRegister(void)96 int32_t SaiPrintTDRegister(void)
97 {
98 struct fsl_sai *sai = g_sai;
99 u32 read_val = 0;
100
101 regmap_read(sai->regmap, FSL_SAI_TDR0, &read_val);
102 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR0 %08x", read_val);
103 regmap_read(sai->regmap, FSL_SAI_TDR1, &read_val);
104 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR1 %08x", read_val);
105 regmap_read(sai->regmap, FSL_SAI_TDR2, &read_val);
106 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR2 %08x", read_val);
107 regmap_read(sai->regmap, FSL_SAI_TDR3, &read_val);
108 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR3 %08x", read_val);
109 regmap_read(sai->regmap, FSL_SAI_TDR4, &read_val);
110 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR4 %08x", read_val);
111 regmap_read(sai->regmap, FSL_SAI_TDR5, &read_val);
112 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR5 %08x", read_val);
113 regmap_read(sai->regmap, FSL_SAI_TDR6, &read_val);
114 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR6 %08x", read_val);
115 regmap_read(sai->regmap, FSL_SAI_TDR7, &read_val);
116 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TDR7 %08x", read_val);
117
118 return 0;
119 }
120
SaiPrintAllRegister(void)121 int32_t SaiPrintAllRegister(void)
122 {
123 struct fsl_sai *sai = g_sai;
124 u32 read_val = 0;
125 regmap_read(sai->regmap, FSL_SAI_TCSR(BYTE_NUM), &read_val);
126 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TCSR %08x", read_val);
127 regmap_read(sai->regmap, FSL_SAI_TCR1(BYTE_NUM), &read_val);
128 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TCR1 %08x", read_val);
129 regmap_read(sai->regmap, FSL_SAI_TCR2(BYTE_NUM), &read_val);
130 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TCR2 %08x", read_val);
131 regmap_read(sai->regmap, FSL_SAI_TCR3(BYTE_NUM), &read_val);
132 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TCR3 %08x", read_val);
133 regmap_read(sai->regmap, FSL_SAI_TCR4(BYTE_NUM), &read_val);
134 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TCR4 %08x", read_val);
135 regmap_read(sai->regmap, FSL_SAI_TCR5(BYTE_NUM), &read_val);
136 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TCR5 %08x", read_val);
137
138 SaiPrintTDRegister();
139 SaiPrintTFRegister();
140
141 regmap_read(sai->regmap, FSL_SAI_TMR, &read_val);
142 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TMR %08x", read_val);
143 regmap_read(sai->regmap, FSL_SAI_TTCTL, &read_val);
144 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TTCTL %08x", read_val);
145 regmap_read(sai->regmap, FSL_SAI_TTCTN, &read_val);
146 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TTCTN %08x", read_val);
147 regmap_read(sai->regmap, FSL_SAI_TTCAP, &read_val);
148 AUDIO_DRIVER_LOG_ERR("FSL_SAI_TTCAP %08x", read_val);
149 regmap_read(sai->regmap, FSL_SAI_MCTL, &read_val);
150 AUDIO_DRIVER_LOG_ERR("FSL_SAI_MCTL %08x", read_val);
151 regmap_read(sai->regmap, FSL_SAI_MDIV, &read_val);
152 AUDIO_DRIVER_LOG_ERR("FSL_SAI_MDIV %08x", read_val);
153
154 return 0;
155 }
156
fsl_sai_rx_irq(int irq,void * devid)157 static bool fsl_sai_rx_irq(int irq, void *devid)
158 {
159 u32 flags = 0, xcsr = 0, mask = 0;
160 bool irq_none = true;
161 struct PrivPlatformData *ppd = (struct PrivPlatformData *)devid;
162 struct fsl_sai *sai = (struct fsl_sai *)&(ppd->sai);
163 unsigned char offset = sai->reg_offset;
164
165 regmap_read(sai->regmap, FSL_SAI_RCSR(offset), &xcsr);
166 flags = xcsr & mask;
167
168 if (flags) {
169 irq_none = false;
170 } else {
171 if (irq_none) {
172 return IRQ_NONE;
173 } else {
174 return IRQ_HANDLED;
175 }
176 }
177
178 if (flags & FSL_SAI_CSR_FEF) {
179 AUDIO_DRIVER_LOG_ERR("isr: Receive overflow detected\n");
180 /* FIFO reset for safety */
181 xcsr |= FSL_SAI_CSR_FR;
182 }
183
184 flags &= FSL_SAI_CSR_xF_W_MASK;
185 xcsr &= ~FSL_SAI_CSR_xF_MASK;
186
187 if (flags) {
188 regmap_write(sai->regmap, FSL_SAI_RCSR(offset), flags | xcsr);
189 }
190
191 return irq_none;
192 }
193
fsl_sai_isr(int irq,void * devid)194 static irqreturn_t fsl_sai_isr(int irq, void *devid)
195 {
196 struct PrivPlatformData *ppd = (struct PrivPlatformData *)devid;
197 struct fsl_sai *sai = (struct fsl_sai *)&(ppd->sai);
198 unsigned char offset = sai->reg_offset;
199 u32 flags = 0, xcsr = 0, mask = 0;
200 bool irq_none = true;
201
202 /*
203 * Both IRQ status bits and IRQ mask bits are in the xCSR but
204 * different shifts. And we here create a mask only for those
205 * IRQs that we activated.
206 */
207 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
208
209 /* Tx IRQ */
210 regmap_read(sai->regmap, FSL_SAI_TCSR(offset), &xcsr);
211 flags = xcsr & mask;
212
213 if (flags) {
214 irq_none = false;
215 } else {
216 if (flags) {
217 irq_none = false;
218 } else {
219 if (irq_none) {
220 return IRQ_NONE;
221 } else {
222 return IRQ_HANDLED;
223 }
224 }
225
226 if (flags & FSL_SAI_CSR_FEF) {
227 AUDIO_DRIVER_LOG_ERR("isr: Receive overflow detected\n");
228 /* FIFO reset for safety */
229 xcsr |= FSL_SAI_CSR_FR;
230 }
231
232 flags &= FSL_SAI_CSR_xF_W_MASK;
233 xcsr &= ~FSL_SAI_CSR_xF_MASK;
234
235 if (flags) {
236 regmap_write(sai->regmap, FSL_SAI_RCSR(offset), flags | xcsr);
237 }
238
239 if (irq_none) {
240 return IRQ_NONE;
241 } else {
242 return IRQ_HANDLED;
243 }
244 }
245
246 if (flags & FSL_SAI_CSR_FEF) {
247 AUDIO_DRIVER_LOG_ERR("isr: Transmit underrun detected\n");
248 /* FIFO reset for safety */
249 xcsr |= FSL_SAI_CSR_FR;
250 }
251
252 flags &= FSL_SAI_CSR_xF_W_MASK;
253 xcsr &= ~FSL_SAI_CSR_xF_MASK;
254
255 if (flags) {
256 regmap_write(sai->regmap, FSL_SAI_TCSR(offset), flags | xcsr);
257 }
258
259 /* Rx IRQ */
260 irq_none = fsl_sai_rx_irq(irq, devid);
261 if (irq_none) {
262 return IRQ_NONE;
263 } else {
264 return IRQ_HANDLED;
265 }
266 }
267
268 static struct reg_default fsl_sai_v3_reg_defaults[] = {
269 {FSL_SAI_TCR1(8), 0},
270 {FSL_SAI_TCR2(8), 0},
271 {FSL_SAI_TCR3(8), 0},
272 {FSL_SAI_TCR4(8), 0},
273 {FSL_SAI_TCR5(8), 0},
274 {FSL_SAI_TDR0, 0},
275 {FSL_SAI_TDR1, 0},
276 {FSL_SAI_TDR2, 0},
277 {FSL_SAI_TDR3, 0},
278 {FSL_SAI_TDR4, 0},
279 {FSL_SAI_TDR5, 0},
280 {FSL_SAI_TDR6, 0},
281 {FSL_SAI_TDR7, 0},
282 {FSL_SAI_TMR, 0},
283 {FSL_SAI_RCR1(8), 0},
284 {FSL_SAI_RCR2(8), 0},
285 {FSL_SAI_RCR3(8), 0},
286 {FSL_SAI_RCR4(8), 0},
287 {FSL_SAI_RCR5(8), 0},
288 {FSL_SAI_RMR, 0},
289 {FSL_SAI_MCTL, 0},
290 {FSL_SAI_MDIV, 0},
291 };
292
fsl_sai_readable_tfr_reg(unsigned int reg)293 static bool fsl_sai_readable_tfr_reg(unsigned int reg)
294 {
295 bool ret = false;
296 switch (reg) {
297 case FSL_SAI_TFR0: fallthrough;
298 case FSL_SAI_TFR1: fallthrough;
299 case FSL_SAI_TFR2: fallthrough;
300 case FSL_SAI_TFR3: fallthrough;
301 case FSL_SAI_TFR4: fallthrough;
302 case FSL_SAI_TFR5: fallthrough;
303 case FSL_SAI_TFR6: fallthrough;
304 case FSL_SAI_TFR7:
305 ret = true;
306 break;
307
308 default:
309 ret = false;
310 break;
311 }
312
313 return ret;
314 }
315
fsl_sai_readable_rxr_reg(unsigned int reg)316 static bool fsl_sai_readable_rxr_reg(unsigned int reg)
317 {
318 bool ret = false;
319 switch (reg) {
320 case FSL_SAI_RDR0: fallthrough;
321 case FSL_SAI_RDR1: fallthrough;
322 case FSL_SAI_RDR2: fallthrough;
323 case FSL_SAI_RDR3: fallthrough;
324 case FSL_SAI_RDR4: fallthrough;
325 case FSL_SAI_RDR5: fallthrough;
326 case FSL_SAI_RDR6: fallthrough;
327 case FSL_SAI_RDR7: fallthrough;
328 case FSL_SAI_RFR0: fallthrough;
329 case FSL_SAI_RFR1: fallthrough;
330 case FSL_SAI_RFR2: fallthrough;
331 case FSL_SAI_RFR3: fallthrough;
332 case FSL_SAI_RFR4: fallthrough;
333 case FSL_SAI_RFR5: fallthrough;
334 case FSL_SAI_RFR6: fallthrough;
335 case FSL_SAI_RFR7: fallthrough;
336 case FSL_SAI_RMR:
337 ret = true;
338 break;
339
340 default:
341 ret = false;
342 break;
343 }
344
345 return ret;
346 }
347
fsl_sai_readable_reg(struct device * dev,unsigned int reg)348 static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
349 {
350 struct fsl_sai *sai = dev_get_drvdata(dev);
351 unsigned char offset = sai->reg_offset;
352
353 if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset)) {
354 return true;
355 }
356
357 if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset)) {
358 return true;
359 }
360
361 if (fsl_sai_readable_tfr_reg(reg) == true) {
362 return true;
363 }
364
365 if (fsl_sai_readable_rxr_reg(reg) == true) {
366 return true;
367 }
368
369 switch (reg) {
370 case FSL_SAI_TMR: fallthrough;
371 case FSL_SAI_MCTL: fallthrough;
372 case FSL_SAI_MDIV: fallthrough;
373 case FSL_SAI_VERID: fallthrough;
374 case FSL_SAI_PARAM: fallthrough;
375 case FSL_SAI_TTCTN: fallthrough;
376 case FSL_SAI_RTCTN: fallthrough;
377 case FSL_SAI_TTCTL: fallthrough;
378 case FSL_SAI_TBCTN: fallthrough;
379 case FSL_SAI_TTCAP: fallthrough;
380 case FSL_SAI_RTCTL: fallthrough;
381 case FSL_SAI_RBCTN: fallthrough;
382 case FSL_SAI_RTCAP:
383 return true;
384 default:
385 return false;
386 }
387 }
388
fsl_sai_volatile_reg(struct device * dev,unsigned int reg)389 static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
390 {
391 struct fsl_sai *sai = dev_get_drvdata(dev);
392 unsigned char offset = sai->reg_offset;
393
394 if (reg == FSL_SAI_TCSR(offset) || reg == FSL_SAI_RCSR(offset)) {
395 return true;
396 }
397
398 if (sai->reg_offset == BYTE_NUM && (reg == FSL_SAI_VERID ||
399 reg == FSL_SAI_PARAM)) {
400 return true;
401 }
402
403 switch (reg) {
404 case FSL_SAI_TFR0:
405 case FSL_SAI_TFR1:
406 case FSL_SAI_TFR2:
407 case FSL_SAI_TFR3:
408 case FSL_SAI_TFR4:
409 case FSL_SAI_TFR5:
410 case FSL_SAI_TFR6:
411 case FSL_SAI_TFR7:
412 case FSL_SAI_RFR0:
413 case FSL_SAI_RFR1:
414 case FSL_SAI_RFR2:
415 case FSL_SAI_RFR3:
416 case FSL_SAI_RFR4:
417 case FSL_SAI_RFR5:
418 case FSL_SAI_RFR6:
419 case FSL_SAI_RFR7:
420 case FSL_SAI_RDR0:
421 case FSL_SAI_RDR1:
422 case FSL_SAI_RDR2:
423 case FSL_SAI_RDR3:
424 case FSL_SAI_RDR4:
425 case FSL_SAI_RDR5:
426 case FSL_SAI_RDR6:
427 case FSL_SAI_RDR7:
428 return true;
429 default:
430 return false;
431 }
432 }
433
fsl_sai_writeable_reg(struct device * dev,unsigned int reg)434 static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
435 {
436 struct fsl_sai *sai = dev_get_drvdata(dev);
437 unsigned char offset = sai->reg_offset;
438
439 if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset)) {
440 return true;
441 }
442
443 if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset)) {
444 return true;
445 }
446
447 switch (reg) {
448 case FSL_SAI_TDR0:
449 case FSL_SAI_TDR1:
450 case FSL_SAI_TDR2:
451 case FSL_SAI_TDR3:
452 case FSL_SAI_TDR4:
453 case FSL_SAI_TDR5:
454 case FSL_SAI_TDR6:
455 case FSL_SAI_TDR7:
456 case FSL_SAI_TMR:
457 case FSL_SAI_RMR:
458 case FSL_SAI_MCTL:
459 case FSL_SAI_MDIV:
460 case FSL_SAI_TTCTL:
461 case FSL_SAI_RTCTL:
462 return true;
463 default:
464 return false;
465 }
466 }
467
468 static const struct regmap_config fsl_sai_regmap_config = {
469 .reg_bits = 32,
470 .reg_stride = 4,
471 .val_bits = 32,
472
473 .max_register = FSL_SAI_MDIV,
474 .reg_defaults = fsl_sai_v3_reg_defaults,
475 .num_reg_defaults = ARRAY_SIZE(fsl_sai_v3_reg_defaults),
476 .readable_reg = fsl_sai_readable_reg,
477 .volatile_reg = fsl_sai_volatile_reg,
478 .writeable_reg = fsl_sai_writeable_reg,
479 .cache_type = REGCACHE_FLAT,
480 };
481
482 #define OFFSET_7 (7)
483 #define OFFSET_8 (8)
fsl_sai_calc_dl_off(unsigned long dl_mask)484 static unsigned int fsl_sai_calc_dl_off(unsigned long dl_mask)
485 {
486 int fbidx = 0, nbidx = 0, offset = 0;
487
488 fbidx = find_first_bit(&dl_mask, OFFSET_8);
489 nbidx = find_next_bit(&dl_mask, OFFSET_8, fbidx + 1);
490 offset = nbidx - fbidx - 1;
491
492 return (offset < 0 || offset >= OFFSET_7 ? 0 : offset);
493 }
494
495 #define ELEMS_3 (3)
fsl_sai_read_dlcfg(struct platform_device * pdev,char * pn,struct fsl_sai_dl_cfg ** rcfg,unsigned int soc_dl)496 static int fsl_sai_read_dlcfg(struct platform_device *pdev, char *pn,
497 struct fsl_sai_dl_cfg **rcfg, unsigned int soc_dl)
498 {
499 int ret = 0, elems = 0, i = 0, index = 0, num_cfg = 0;
500 struct device_node *np = pdev->dev.of_node;
501 struct fsl_sai_dl_cfg *cfg = NULL;
502 u32 rx = 0, tx = 0, pins = 0;
503
504 *rcfg = NULL;
505
506 elems = of_property_count_u32_elems(np, pn);
507 /* consider default value "0 0x1 0x1" if property is missing */
508 if (elems <= 0) {
509 elems = ELEMS_3;
510 }
511
512 if (elems % ELEMS_3) {
513 AUDIO_DRIVER_LOG_ERR(
514 "Number of elements in %s must be divisible to 3.\n", pn);
515 return -EINVAL;
516 }
517
518 num_cfg = elems / ELEMS_3;
519 cfg = devm_kzalloc(&pdev->dev, num_cfg * sizeof(*cfg), GFP_KERNEL);
520 if (cfg == NULL) {
521 AUDIO_DRIVER_LOG_ERR("Cannot allocate memory for %s.\n", pn);
522 return -ENOMEM;
523 }
524
525 for (i = 0, index = 0; i < num_cfg; i++) {
526 ret = of_property_read_u32_index(np, pn, index++, &pins);
527 if (ret) {
528 pins = 0;
529 }
530
531 ret = of_property_read_u32_index(np, pn, index++, &rx);
532 if (ret) {
533 rx = 1;
534 }
535
536 ret = of_property_read_u32_index(np, pn, index++, &tx);
537 if (ret) {
538 tx = 1;
539 }
540
541 if ((rx & ~soc_dl) || (tx & ~soc_dl)) {
542 AUDIO_DRIVER_LOG_ERR(
543 "%s: dataline cfg[%d] setting error, mask is 0x%x\n",
544 pn, i, soc_dl);
545 return -EINVAL;
546 }
547
548 cfg[i].pins = pins;
549 cfg[i].mask[0] = rx;
550 cfg[i].offset[0] = fsl_sai_calc_dl_off(rx);
551 cfg[i].mask[1] = tx;
552 cfg[i].offset[1] = fsl_sai_calc_dl_off(tx);
553 }
554
555 *rcfg = cfg;
556 return num_cfg;
557 }
558
fsl_sai_check_ver(struct fsl_sai * sai,struct device * dev)559 static int fsl_sai_check_ver(struct fsl_sai *sai, struct device *dev)
560 {
561 unsigned char offset = sai->reg_offset;
562 unsigned int val = 0;
563 int ret = 0;
564
565 if (FSL_SAI_TCSR(offset) == FSL_SAI_VERID) {
566 return 0;
567 }
568
569 if (sai->verid.loaded) {
570 return 0;
571 }
572
573 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
574 if (ret < 0) {
575 return ret;
576 }
577
578 AUDIO_DRIVER_LOG_ERR("VERID: 0x%016X\n", val);
579
580 sai->verid.id = (val & FSL_SAI_VER_ID_MASK) >> FSL_SAI_VER_ID_SHIFT;
581 sai->verid.extfifo_en = (val & FSL_SAI_VER_EFIFO_EN);
582 sai->verid.timestamp_en = (val & FSL_SAI_VER_TSTMP_EN);
583
584 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
585 if (ret < 0) {
586 return ret;
587 }
588
589 AUDIO_DRIVER_LOG_ERR("PARAM: 0x%016X\n", val);
590
591 /* max slots per frame, power of 2 */
592 sai->param.spf = 1 <<
593 ((val & FSL_SAI_PAR_SPF_MASK) >> FSL_SAI_PAR_SPF_SHIFT);
594
595 /* words per fifo, power of 2 */
596 sai->param.wpf = 1 <<
597 ((val & FSL_SAI_PAR_WPF_MASK) >> FSL_SAI_PAR_WPF_SHIFT);
598
599 /* number of datalines implemented */
600 sai->param.dln = val & FSL_SAI_PAR_DLN_MASK;
601
602 AUDIO_DRIVER_LOG_ERR(
603 "Version: 0x%08X, SPF: %u, WPF: %u, DLN: %u\n",
604 sai->verid.id, sai->param.spf, sai->param.wpf, sai->param.dln);
605
606 sai->verid.loaded = true;
607
608 return HDF_SUCCESS;
609 }
610
611 #define RATIO_1 (1)
612 #define RATIO_2 (2)
613 #define RATIO_512 (512)
614 #define RATE_1000 (1000)
fsl_sai_set_bclk(struct fsl_sai * sai,bool tx,u32 freq)615 static int fsl_sai_set_bclk(struct fsl_sai *sai, bool tx, u32 freq)
616 {
617 unsigned char offset = sai->reg_offset;
618 unsigned long clk_rate = 0;
619 unsigned int reg = 0;
620 u32 ratio = 0, savesub = freq, saveratio = 0, savediv = 0;
621 u32 id = 0;
622 int ret = 0;
623
624 for (id = 0; id < FSL_SAI_MCLK_MAX; id++) {
625 clk_rate = clk_get_rate(sai->mclk_clk[id]);
626 if (!clk_rate) {
627 continue;
628 }
629
630 if (freq != 0) {
631 ratio = clk_rate / freq;
632 }
633
634 ret = clk_rate - ratio * freq;
635 /*
636 * Drop the source that can not be
637 * divided into the required rate.
638 */
639 if (ret != 0 && clk_rate / ret < RATE_1000) {
640 continue;
641 }
642
643 if ((ratio % RATIO_2 == 0 && ratio >= RATIO_2 && ratio <= RATIO_512) ||
644 (ratio == RATIO_1 && sai->verid.id >= FSL_SAI_VERID_0301)) {
645 if (ret < savesub) {
646 saveratio = ratio;
647 sai->mclk_id[tx] = id;
648 savesub = ret;
649 }
650
651 if (ret == 0) {
652 break;
653 }
654 }
655 }
656
657 /*
658 * 1) For Asynchronous mode, we must set RCR2 register for capture, and
659 * set TCR2 register for playback.
660 * 2) For Tx sync with Rx clock, we must set RCR2 register for playback
661 * and capture.
662 * 3) For Rx sync with Tx clock, we must set TCR2 register for playback
663 * and capture.
664 * 4) For Tx and Rx are both Synchronous with another SAI, we just
665 * ignore it.
666 */
667 if ((!tx || sai->synchronous[TX]) && !sai->synchronous[RX]) {
668 reg = FSL_SAI_RCR2(offset);
669 } else if ((tx || sai->synchronous[RX]) && !sai->synchronous[TX]) {
670 reg = FSL_SAI_TCR2(offset);
671 }
672
673 if (reg) {
674 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,
675 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
676
677 savediv = (saveratio == 1 ? 0 : (saveratio >> 1) - 1);
678 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_DIV_MASK, savediv);
679
680 if (sai->verid.id >= FSL_SAI_VERID_0301) {
681 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_BYP,
682 (saveratio == 1 ? FSL_SAI_CR2_BYP : 0));
683 }
684 }
685
686 if (sai->verid.id >= FSL_SAI_VERID_0301) {
687 /* SAI is in master mode at this point, so enable MCLK */
688 regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
689 FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
690 }
691
692 return 0;
693 }
694 struct fsl_hwParams_register {
695 u32 cr3;
696 u32 cr4;
697 u32 cr5;
698 u32 mr;
699 };
700
SaiGetHwParams(const struct PlatformData * pd,const enum AudioStreamType streamType,u32 * channels,u32 * rate,u32 * word_width)701 int32_t SaiGetHwParams(const struct PlatformData *pd,
702 const enum AudioStreamType streamType,
703 u32 *channels, u32 *rate,
704 u32 *word_width)
705 {
706 int32_t ret = 0;
707
708 if (streamType == AUDIO_RENDER_STREAM) {
709 *channels = pd->renderPcmInfo.channels;
710 *rate = pd->renderPcmInfo.rate;
711 *word_width = pd->renderPcmInfo.bitWidth;
712 } else if (streamType == AUDIO_CAPTURE_STREAM) {
713 *channels = pd->capturePcmInfo.channels;
714 *rate = pd->capturePcmInfo.rate;
715 *word_width = pd->capturePcmInfo.bitWidth;
716 } else {
717 AUDIO_DRIVER_LOG_ERR("streamType is invaild ");
718 return HDF_FAILURE;
719 }
720 return ret;
721 }
722
SaiSetHwParamsPin(struct fsl_sai * sai,u32 channels,u32 * pins,u32 * slots)723 int32_t SaiSetHwParamsPin(struct fsl_sai *sai, u32 channels, u32 *pins, u32 *slots)
724 {
725 int32_t ret = 0;
726
727 if (sai->slots) {
728 *slots = sai->slots;
729 }
730
731 *pins = DIV_ROUND_UP(channels, *slots);
732
733 if (!IS_ERR_OR_NULL(sai->pinctrl)) {
734 sai->pins_state = pinctrl_lookup_state(sai->pinctrl, "default");
735
736 if (!IS_ERR_OR_NULL(sai->pins_state)) {
737 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
738 if (ret) {
739 AUDIO_DRIVER_LOG_ERR("failed to set proper pins state");
740 return ret;
741 }
742 }
743 }
744 return ret;
745 }
746
SaiSetHwParamsClk(struct fsl_sai * sai,bool tx,u32 bclk,const enum AudioStreamType streamType)747 int32_t SaiSetHwParamsClk(struct fsl_sai *sai, bool tx, u32 bclk, const enum AudioStreamType streamType)
748 {
749 int32_t ret = 0;
750 if (!sai->slave_mode[tx]) {
751 ret = fsl_sai_set_bclk(sai, tx, bclk);
752 if (ret) {
753 return ret;
754 }
755
756 /* Do not enable the clock if it is already enabled */
757 if (!(sai->mclk_streams & BIT(streamType))) {
758 AUDIO_DRIVER_LOG_ERR("mclk enable %d", sai->mclk_id[tx]);
759 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);
760 if (ret) {
761 return ret;
762 }
763
764 sai->mclk_streams |= BIT(streamType);
765 }
766 }
767 return ret;
768 }
769
SaiGetHwParamsCR5(struct fsl_sai * sai,u32 slot_width,u32 word_width)770 u32 SaiGetHwParamsCR5(struct fsl_sai *sai, u32 slot_width, u32 word_width)
771 {
772 u32 val_cr5 = 0;
773
774 val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
775 val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
776
777 if (sai->is_lsb_first) {
778 val_cr5 |= FSL_SAI_CR5_FBT(0);
779 } else {
780 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
781 }
782
783 return val_cr5;
784 }
785
SaiGetHwParamsCR4(struct fsl_sai * sai,u32 slot_width,u32 slots)786 u32 SaiGetHwParamsCR4(struct fsl_sai *sai, u32 slot_width, u32 slots)
787 {
788 u32 val_cr4 = 0;
789
790 if (!sai->is_dsp_mode) {
791 val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);
792 }
793 val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
794
795 /* Output Mode - data pins transmit 0 when slots are masked
796 * or channels are disabled
797 */
798 val_cr4 |= FSL_SAI_CR4_CHMOD;
799 return val_cr4;
800 }
801
SaiGetdlMask(struct fsl_sai * sai,bool tx,u32 pins)802 u32 SaiGetdlMask(struct fsl_sai *sai, bool tx, u32 pins)
803 {
804 int32_t i = 0, dl_cfg_cnt, dl_cfg_idx = 0;
805 struct fsl_sai_dl_cfg *dl_cfg = NULL;
806
807 sai->is_dsd = false;
808 dl_cfg = sai->pcm_dl_cfg;
809 dl_cfg_cnt = sai->pcm_dl_cfg_cnt;
810 for (i = 0; i < dl_cfg_cnt; i++) {
811 if (dl_cfg[i].pins == pins) {
812 dl_cfg_idx = i;
813 break;
814 }
815 }
816
817 if (dl_cfg_idx >= dl_cfg_cnt) {
818 AUDIO_DRIVER_LOG_ERR("fsl,dataline%s invalid or not provided.", sai->is_dsd ? ",dsd" : "");
819 return HDF_FAILURE;
820 }
821
822 return dl_cfg[dl_cfg_idx].mask[tx];
823 }
824
SaiSetHwParamsRegister(struct fsl_sai * sai,bool tx,struct fsl_hwParams_register * val,unsigned int dl_mask)825 u32 SaiSetHwParamsRegister(struct fsl_sai *sai, bool tx,
826 struct fsl_hwParams_register *val, unsigned int dl_mask)
827 {
828 unsigned char offset = sai->reg_offset;
829
830 if (!sai->slave_mode[tx]) {
831 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
832 regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset),
833 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
834 FSL_SAI_CR4_CHMOD_MASK, val->cr4);
835 regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset),
836 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
837 FSL_SAI_CR5_FBT_MASK, val->cr5);
838 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
839 regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset),
840 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
841 FSL_SAI_CR4_CHMOD_MASK, val->cr4);
842 regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset),
843 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
844 FSL_SAI_CR5_FBT_MASK, val->cr5);
845 }
846 }
847
848 if (sai->dataline != 0x1) {
849 if (dl_mask <= 1 || sai->is_multi_lane) {
850 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
851 FSL_SAI_CR4_FCOMB_MASK, 0);
852 } else {
853 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
854 FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT);
855 }
856 }
857
858 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
859 FSL_SAI_CR3_TRCE_MASK,
860 FSL_SAI_CR3_TRCE(val->cr3));
861
862 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
863 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
864 FSL_SAI_CR4_CHMOD_MASK,
865 val->cr4);
866
867 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset),
868 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
869 FSL_SAI_CR5_FBT_MASK, val->cr5);
870
871 regmap_write(sai->regmap, FSL_SAI_xMR(tx), val->mr);
872
873 return HDF_SUCCESS;
874 }
875
SaiSetHwParams(const struct PlatformData * pd,const enum AudioStreamType streamType)876 int32_t SaiSetHwParams(const struct PlatformData *pd, const enum AudioStreamType streamType)
877 {
878 struct fsl_sai *sai = GetDrvSai(pd);
879 u32 channels = 0, rate = 0, word_width = 0, pins = 0, bclk = 0;
880 u32 slot_width = word_width, slots = (channels == 1) ? 2 : channels;
881 bool tx = streamType == AUDIO_RENDER_STREAM;
882 struct fsl_hwParams_register val;
883 int32_t trce_mask = 0, ret = 0;
884 unsigned int dl_mask, i;
885
886 ret = SaiGetHwParams(pd, streamType, &channels, &rate, &word_width);
887 if (ret != HDF_SUCCESS) {
888 ADM_LOG_ERR("SaiGetHwParams fail ret=%d", ret);
889 return ret;
890 }
891
892 ret = SaiSetHwParamsPin(sai, channels, &pins, &slots);
893 if (ret != HDF_SUCCESS) {
894 ADM_LOG_ERR("SaiSetHwParamsPin fail ret=%d", ret);
895 return ret;
896 }
897
898 if (sai->slot_width) {
899 slot_width = sai->slot_width;
900 }
901 bclk = rate*(sai->bitclk_ratio ? sai->bitclk_ratio : slots * slot_width);
902 ret = SaiSetHwParamsClk(sai, tx, bclk, streamType);
903 if (ret != HDF_SUCCESS) {
904 ADM_LOG_ERR("SaiSetHwParamsClk fail ret=%d", ret);
905 return ret;
906 }
907
908 val.cr5 = SaiGetHwParamsCR5(sai, slot_width, word_width);
909 val.cr4 = SaiGetHwParamsCR4(sai, slot_width, slots);
910 dl_mask = SaiGetdlMask(sai, tx, pins);
911 if (__sw_hweight8(dl_mask & 0xFF) < pins) {
912 AUDIO_DRIVER_LOG_ERR("channel not supported");
913 return -EINVAL;
914 }
915 for (i = 0; i < BYTE_NUM; i++) {
916 trce_mask = (1 << (i + 1)) - 1;
917 if (__sw_hweight8(dl_mask & trce_mask) == pins) {
918 break;
919 }
920 }
921 val.cr3 = dl_mask & trce_mask;
922 val.mr = ~0UL - ((1 << min(channels, slots)) - 1);
923
924 SaiSetHwParamsRegister(sai, tx, &val, dl_mask);
925 return HDF_SUCCESS;
926 }
927
SaiSetDaiTdmSlot(const struct PlatformData * pd,int32_t tx_mask,int32_t rx_mask,int32_t slots,int32_t slot_width)928 int32_t SaiSetDaiTdmSlot(const struct PlatformData *pd, int32_t tx_mask,
929 int32_t rx_mask, int32_t slots, int32_t slot_width)
930 {
931 struct fsl_sai *sai = GetDrvSai(pd);
932
933 if (sai != NULL) {
934 sai->slots = slots;
935 sai->slot_width = slot_width;
936 } else {
937 return HDF_FAILURE;
938 }
939
940 return HDF_SUCCESS;
941 }
942
SaiSetSysclkTr(struct fsl_sai * sai,int clk_id,unsigned int freq,int fsl_dir)943 static int32_t SaiSetSysclkTr(struct fsl_sai *sai, int clk_id, unsigned int freq, int fsl_dir)
944 {
945 unsigned char offset = 0;
946 bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
947 uint32_t val_cr2 = 0;
948
949 offset = sai->reg_offset;
950 switch (clk_id) {
951 case FSL_SAI_CLK_BUS:
952 val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
953 break;
954 case FSL_SAI_CLK_MAST1:
955 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
956 break;
957 case FSL_SAI_CLK_MAST2:
958 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
959 break;
960 case FSL_SAI_CLK_MAST3:
961 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
962 break;
963 default:
964 return -EINVAL;
965 }
966
967 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
968 FSL_SAI_CR2_MSEL_MASK, val_cr2);
969
970 return HDF_SUCCESS;
971 }
972
973 #define RATIO_DIV (8000)
fsl_sai_set_mclk_rate(struct fsl_sai * sai,int clk_id,unsigned int freq)974 static int32_t fsl_sai_set_mclk_rate(struct fsl_sai *sai, int clk_id, unsigned int freq)
975 {
976 struct clk *p = sai->mclk_clk[clk_id], *pll = 0, *npll = 0;
977 u64 ratio = freq;
978 int ret = 0;
979 AUDIO_DRIVER_LOG_ERR("mclk rate in");
980 while (p && sai->pll8k_clk && sai->pll11k_clk) {
981 struct clk *pp = clk_get_parent(p);
982
983 if (clk_is_match(pp, sai->pll8k_clk) ||
984 clk_is_match(pp, sai->pll11k_clk)) {
985 pll = pp;
986 break;
987 }
988 p = pp;
989 }
990
991 if (pll) {
992 npll = (do_div(ratio, RATIO_DIV) ? sai->pll11k_clk : sai->pll8k_clk);
993 if (!clk_is_match(pll, npll)) {
994 ret = clk_set_parent(p, npll);
995 if (ret < 0) {
996 AUDIO_DRIVER_LOG_ERR("failed to set parent %s: %d\n",
997 __clk_get_name(npll), ret);
998 }
999 }
1000 }
1001
1002 ret = clk_set_rate(sai->mclk_clk[clk_id], freq);
1003 AUDIO_DRIVER_LOG_ERR("mclk_clk id %d freq %d", clk_id, freq);
1004 if (ret < 0) {
1005 AUDIO_DRIVER_LOG_ERR("failed to set clock rate (%u): %d\n",
1006 freq, ret);
1007 }
1008
1009 return ret;
1010 }
1011
SaiSetSysclk(const struct PlatformData * pd,int clk_id,unsigned int freq,int dir)1012 int32_t SaiSetSysclk(const struct PlatformData *pd, int clk_id, unsigned int freq, int dir)
1013 {
1014 struct fsl_sai *sai = GetDrvSai(pd);
1015 int32_t ret = 0;
1016
1017 if (sai == NULL) {
1018 AUDIO_DRIVER_LOG_ERR("sai null");
1019 return HDF_FAILURE;
1020 }
1021
1022 if (dir == SOC_CLOCK_IN) {
1023 return HDF_SUCCESS;
1024 }
1025
1026 if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) {
1027 if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) {
1028 AUDIO_DRIVER_LOG_ERR("Unknown clock id: %d", clk_id);
1029 return -EINVAL;
1030 }
1031
1032 if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) {
1033 AUDIO_DRIVER_LOG_ERR("Unassigned clock: %d", clk_id);
1034 return -EINVAL;
1035 }
1036 AUDIO_DRIVER_LOG_ERR("clock: %d", clk_id);
1037 if (sai->mclk_streams == 0) {
1038 AUDIO_DRIVER_LOG_ERR("mclk rate = %d", freq);
1039 ret = fsl_sai_set_mclk_rate(sai, clk_id, freq);
1040 if (ret < 0) {
1041 return ret;
1042 }
1043 }
1044 }
1045
1046 ret = SaiSetSysclkTr(sai, clk_id, freq, FSL_FMT_TRANSMITTER);
1047 if (ret) {
1048 AUDIO_DRIVER_LOG_ERR("cannot set tx sysclk");
1049 return HDF_FAILURE;
1050 }
1051
1052 ret = SaiSetSysclkTr(sai, clk_id, freq, FSL_FMT_RECEIVER);
1053 if (ret) {
1054 AUDIO_DRIVER_LOG_ERR("cannot set rx sysclk");
1055 return HDF_FAILURE;
1056 }
1057
1058 return HDF_SUCCESS;
1059 }
1060
HandleDaiMode(unsigned int fmt,int32_t * val_cr2,int32_t * val_cr4,struct fsl_sai ** sai)1061 static int32_t HandleDaiMode(unsigned int fmt, int32_t *val_cr2, int32_t *val_cr4, struct fsl_sai **sai)
1062 {
1063 /* DAI mode */
1064 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1065 case SND_SOC_DAIFMT_I2S:
1066 /*
1067 * Frame low, 1clk before data, one word length for frame sync,
1068 * frame sync starts one serial clock cycle earlier,
1069 * that is, together with the last bit of the previous
1070 * data word.
1071 */
1072 *val_cr2 |= FSL_SAI_CR2_BCP;
1073 *val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
1074 break;
1075 case SND_SOC_DAIFMT_LEFT_J:
1076 /*
1077 * Frame high, one word length for frame sync,
1078 * frame sync asserts with the first bit of the frame.
1079 */
1080 *val_cr2 |= FSL_SAI_CR2_BCP;
1081 break;
1082 case SND_SOC_DAIFMT_DSP_A:
1083 /*
1084 * Frame high, 1clk before data, one bit for frame sync,
1085 * frame sync starts one serial clock cycle earlier,
1086 * that is, together with the last bit of the previous
1087 * data word.
1088 */
1089 *val_cr2 |= FSL_SAI_CR2_BCP;
1090 *val_cr4 |= FSL_SAI_CR4_FSE;
1091 (*sai)->is_dsp_mode = true;
1092 break;
1093 case SND_SOC_DAIFMT_DSP_B:
1094 /*
1095 * Frame high, one bit for frame sync,
1096 * frame sync asserts with the first bit of the frame.
1097 */
1098 *val_cr2 |= FSL_SAI_CR2_BCP;
1099 (*sai)->is_dsp_mode = true;
1100 break;
1101 case SND_SOC_DAIFMT_PDM:
1102 *val_cr2 |= FSL_SAI_CR2_BCP;
1103 *val_cr4 &= ~FSL_SAI_CR4_MF;
1104 (*sai)->is_dsp_mode = true;
1105 break;
1106 case SND_SOC_DAIFMT_RIGHT_J:
1107 /* To be done */
1108 default:
1109 return -EINVAL;
1110 }
1111 return 0;
1112 }
1113
HandleDaiCLK(unsigned int fmt,int32_t * val_cr2,int32_t * val_cr4)1114 static int32_t HandleDaiCLK(unsigned int fmt, int32_t *val_cr2, int32_t *val_cr4)
1115 {
1116 /* DAI clock inversion */
1117 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1118 case SND_SOC_DAIFMT_IB_IF:
1119 /* Invert both clocks */
1120 *val_cr2 ^= FSL_SAI_CR2_BCP;
1121 *val_cr4 ^= FSL_SAI_CR4_FSP;
1122 break;
1123 case SND_SOC_DAIFMT_IB_NF:
1124 /* Invert bit clock */
1125 *val_cr2 ^= FSL_SAI_CR2_BCP;
1126 break;
1127 case SND_SOC_DAIFMT_NB_IF:
1128 /* Invert frame clock */
1129 *val_cr4 ^= FSL_SAI_CR4_FSP;
1130 break;
1131 case SND_SOC_DAIFMT_NB_NF:
1132 /* Nothing to do for both normal cases */
1133 break;
1134 default:
1135 return -EINVAL;
1136 }
1137
1138 return 0;
1139 }
1140
SaiSetDaiFmtTr(struct PrivPlatformData * ppd,unsigned int fmt,int fsl_dir)1141 static int32_t SaiSetDaiFmtTr(struct PrivPlatformData *ppd, unsigned int fmt, int fsl_dir)
1142 {
1143 struct fsl_sai *sai = NULL;
1144 unsigned char offset = 0;
1145 int32_t val_cr2 = 0, val_cr4 = 0;
1146 bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
1147 uint32_t read_val;
1148
1149 if (ppd == NULL) {
1150 return HDF_FAILURE;
1151 }
1152
1153 sai = &ppd->sai;
1154 offset = sai->reg_offset;
1155
1156 if (!sai->is_lsb_first) {
1157 val_cr4 |= FSL_SAI_CR4_MF;
1158 }
1159
1160 sai->is_dsp_mode = false;
1161 if (HandleDaiMode(fmt, &val_cr2, &val_cr4, &sai) < 0) {
1162 return -EINVAL;
1163 }
1164
1165 if (HandleDaiCLK(fmt, &val_cr2, &val_cr4) < 0) {
1166 return -EINVAL;
1167 }
1168
1169 sai->slave_mode[tx] = false;
1170
1171 /* DAI clock master masks */
1172 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1173 case SND_SOC_DAIFMT_CBS_CFS:
1174 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
1175 val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
1176 break;
1177 case SND_SOC_DAIFMT_CBM_CFM:
1178 sai->slave_mode[tx] = true;
1179 break;
1180 case SND_SOC_DAIFMT_CBS_CFM:
1181 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
1182 break;
1183 case SND_SOC_DAIFMT_CBM_CFS:
1184 val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
1185 sai->slave_mode[tx] = true;
1186 break;
1187 default:
1188 return -EINVAL;
1189 }
1190
1191 regmap_read(sai->regmap, FSL_SAI_xCR2(tx, offset), &read_val);
1192 regmap_read(sai->regmap, FSL_SAI_xCR4(tx, offset), &read_val);
1193
1194 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
1195 FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
1196 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
1197 FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
1198 FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
1199
1200 regmap_read(sai->regmap, FSL_SAI_xCR2(tx, offset), &read_val);
1201 regmap_read(sai->regmap, FSL_SAI_xCR4(tx, offset), &read_val);
1202
1203 return HDF_SUCCESS;
1204 }
1205
SaiSetDaiFmt(const struct PlatformData * pd,unsigned int fmt)1206 int32_t SaiSetDaiFmt(const struct PlatformData *pd, unsigned int fmt)
1207 {
1208 struct PrivPlatformData *ppd = (struct PrivPlatformData *)pd->dmaPrv;
1209 int32_t ret;
1210
1211 ret = SaiSetDaiFmtTr(ppd, fmt, FSL_FMT_TRANSMITTER);
1212 if (ret != HDF_SUCCESS) {
1213 AUDIO_DRIVER_LOG_ERR("set dai fmt tx failed");
1214 return ret;
1215 }
1216
1217 ret = SaiSetDaiFmtTr(ppd, fmt, FSL_FMT_RECEIVER);
1218 if (ret != HDF_SUCCESS) {
1219 AUDIO_DRIVER_LOG_ERR("set dai fmt tx failed");
1220 }
1221
1222 return ret;
1223 }
1224
SaiHwFree(const struct DaiData * pd,int isTx)1225 int32_t SaiHwFree(const struct DaiData *pd, int isTx)
1226 {
1227 struct fsl_sai *sai = g_sai;
1228 unsigned char offset = sai->reg_offset;
1229 bool tx = isTx == TRIGGER_TX;
1230 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
1231 FSL_SAI_CR3_TRCE_MASK, 0);
1232
1233 if (sai->mclk_streams != 0) {
1234 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
1235 if (sai->mclk_streams & BIT(AUDIO_RENDER_STREAM)) {
1236 sai->mclk_streams &= ~BIT(AUDIO_RENDER_STREAM);
1237 } else if (sai->mclk_streams & BIT(AUDIO_CAPTURE_STREAM)) {
1238 sai->mclk_streams &= ~BIT(AUDIO_CAPTURE_STREAM);
1239 }
1240 }
1241
1242 return HDF_SUCCESS;
1243 }
1244
1245 #define NUM_128 (128)
1246 #define DELAY_10 (10)
SaiDriverInitClk(struct PrivPlatformData * ppd,void __iomem * base)1247 int32_t SaiDriverInitClk(struct PrivPlatformData *ppd, void __iomem *base)
1248 {
1249 int ret = 0, i = 0;;
1250 struct fsl_sai *sai = &ppd->sai;
1251 unsigned long clk_rate = 0;
1252 char tmp[8];
1253
1254 sai->regmap = devm_regmap_init_mmio_clk(&ppd->pdev->dev, "bus", base, &fsl_sai_regmap_config);
1255
1256 if (IS_ERR(sai->regmap) && PTR_ERR(sai->regmap) != -EPROBE_DEFER) {
1257 sai->regmap = devm_regmap_init_mmio_clk(&ppd->pdev->dev, "sai", base, &fsl_sai_regmap_config);
1258 }
1259 if (IS_ERR(sai->regmap)) {
1260 AUDIO_DRIVER_LOG_ERR("regmap init failed\n");
1261 return PTR_ERR(sai->regmap);
1262 }
1263
1264 sai->bus_clk = devm_clk_get(&ppd->pdev->dev, "bus");
1265
1266 if (IS_ERR(sai->bus_clk)) {
1267 AUDIO_DRIVER_LOG_ERR("failed to get bus clk %d", PTR_ERR(sai->bus_clk));
1268 sai->bus_clk = NULL;
1269 }
1270
1271 clk_rate = clk_get_rate(sai->bus_clk);
1272 AUDIO_DRIVER_LOG_ERR("bus rate %d", clk_rate);
1273
1274 for (i = 0; i < FSL_SAI_MCLK_MAX; i++) {
1275 ret = snprintf_s(tmp, sizeof(tmp)-1, sizeof(tmp)-1, "mclk%d", i);
1276 if (ret < 0) {
1277 AUDIO_DRIVER_LOG_ERR("failed to write mclk");
1278 }
1279 sai->mclk_clk[i] = devm_clk_get(&ppd->pdev->dev, tmp);
1280 if (IS_ERR(sai->mclk_clk[i])) {
1281 AUDIO_DRIVER_LOG_ERR("failed to get mclk%d clock: %ld\n", i, PTR_ERR(sai->mclk_clk[i]));
1282 sai->mclk_clk[i] = NULL;
1283 }
1284 clk_rate = clk_get_rate(sai->mclk_clk[i]);
1285 }
1286
1287 sai->pll8k_clk = devm_clk_get(&ppd->pdev->dev, "pll8k");
1288 if (IS_ERR(sai->pll8k_clk)) {
1289 sai->pll8k_clk = NULL;
1290 }
1291
1292 sai->pll11k_clk = devm_clk_get(&ppd->pdev->dev, "pll11k");
1293 if (IS_ERR(sai->pll11k_clk)) {
1294 sai->pll11k_clk = NULL;
1295 }
1296 return HDF_SUCCESS;
1297 }
1298
SaiDriverInitDataline(struct PrivPlatformData * ppd)1299 int32_t SaiDriverInitDataline(struct PrivPlatformData *ppd)
1300 {
1301 int ret = 0;
1302 struct fsl_sai *sai = &ppd->sai;
1303
1304 ret = fsl_sai_read_dlcfg(ppd->pdev, "fsl,dataline", &sai->pcm_dl_cfg,
1305 sai->dataline);
1306 if (ret < 0) {
1307 return ret;
1308 }
1309
1310 sai->pcm_dl_cfg_cnt = ret;
1311
1312 ret = fsl_sai_read_dlcfg(ppd->pdev, "fsl,dataline,dsd", &sai->dsd_dl_cfg,
1313 sai->dataline);
1314 if (ret < 0) {
1315 return ret;
1316 }
1317
1318 sai->dsd_dl_cfg_cnt = ret;
1319
1320 return ret;
1321 }
1322
SaiDriverInitIrq(struct PrivPlatformData * ppd,struct device_node * np)1323 int32_t SaiDriverInitIrq(struct PrivPlatformData *ppd, struct device_node *np)
1324 {
1325 int irq = 0, ret = 0;
1326 struct fsl_sai *sai = &ppd->sai;
1327
1328 irq = platform_get_irq(ppd->pdev, 0);
1329 if (irq < 0) {
1330 AUDIO_DRIVER_LOG_ERR("failed to get irq");
1331 return irq;
1332 }
1333
1334 ret = devm_request_irq(&ppd->pdev->dev, irq, fsl_sai_isr, 0,
1335 np->name, ppd);
1336 if (ret) {
1337 AUDIO_DRIVER_LOG_ERR("failed to claim irq");
1338 return ret;
1339 }
1340
1341 sai->synchronous[RX] = true;
1342 sai->synchronous[TX] = false;
1343
1344 if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
1345 of_find_property(np, "fsl,sai-asynchronous", NULL)) {
1346 /* error out if both synchronous and asynchronous are present */
1347 AUDIO_DRIVER_LOG_ERR("invalid binding for synchronous mode\n");
1348 return -EINVAL;
1349 }
1350
1351 if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
1352 /* Sync Rx with Tx */
1353 sai->synchronous[RX] = false;
1354 sai->synchronous[TX] = true;
1355 } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
1356 /* Discard all settings for asynchronous mode */
1357 sai->synchronous[RX] = false;
1358 sai->synchronous[TX] = false;
1359 }
1360
1361 return ret;
1362 }
1363
SaiDriverInitDma(struct PrivPlatformData * ppd,struct device_node * np,struct resource * res)1364 int32_t SaiDriverInitDma(struct PrivPlatformData *ppd, struct device_node *np, struct resource *res)
1365 {
1366 int ret = 0;
1367 struct fsl_sai *sai = &ppd->sai;
1368
1369 platform_set_drvdata(ppd->pdev, sai);
1370 ret = fsl_sai_check_ver(sai, &ppd->pdev->dev);
1371 if (ret < 0) {
1372 AUDIO_DRIVER_LOG_ERR("Error reading SAI version: %d", ret);
1373 }
1374
1375 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
1376 sai->verid.id >= FSL_SAI_VERID_0301) {
1377 regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
1378 FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
1379 }
1380
1381 ppd->dma_addr_src = res->start + FSL_SAI_RDR0;
1382 ppd->dma_addr_dst = res->start + FSL_SAI_TDR0;
1383 ppd->dma_maxburst_rx = FSL_SAI_MAXBURST_RX;
1384 ppd->dma_maxburst_tx = FSL_SAI_MAXBURST_TX;
1385
1386 sai->pinctrl = devm_pinctrl_get(&ppd->pdev->dev);
1387 regcache_cache_only(sai->regmap, true);
1388
1389 pm_runtime_enable(&ppd->pdev->dev);
1390
1391 return ret;
1392 }
1393
SaiDriverInit(struct PlatformData * pd)1394 int32_t SaiDriverInit(struct PlatformData *pd)
1395 {
1396 struct PrivPlatformData *ppd = (struct PrivPlatformData *)pd->dmaPrv;
1397 struct device_node *np = ppd->pdev->dev.of_node;
1398 struct resource *res = NULL;
1399 struct fsl_sai *sai = &ppd->sai;
1400 void __iomem *base = NULL;
1401 int ret = 0;
1402 g_sai = sai;
1403
1404 ret = of_clk_set_defaults(np, false);
1405 if (ret < 0) {
1406 AUDIO_DRIVER_LOG_ERR("sai driver init clk set default failed");
1407 return HDF_FAILURE;
1408 }
1409
1410 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
1411 res = platform_get_resource(ppd->pdev, IORESOURCE_MEM, 0);
1412 base = devm_ioremap_resource(&ppd->pdev->dev, res);
1413 if (IS_ERR(base)) {
1414 return PTR_ERR(base);
1415 }
1416
1417 sai->reg_offset = FSL_REG_OFFSET;
1418 ret = SaiDriverInitClk(ppd, base);
1419 if (ret != HDF_SUCCESS) {
1420 ADM_LOG_ERR("SaiDriverInitClk fail ret=%d", ret);
1421 return ret;
1422 }
1423 sai->dataline = 0xFF;
1424 sai->fifo_depth = NUM_128;
1425 ret = SaiDriverInitDataline(ppd);
1426 if (ret < 0) {
1427 ADM_LOG_ERR("SaiDriverInitDataline fail ret=%d", ret);
1428 return ret;
1429 }
1430 ret = SaiDriverInitIrq(ppd, np);
1431 if (ret != HDF_SUCCESS) {
1432 ADM_LOG_ERR("SaiDriverInitIrq fail ret=%d", ret);
1433 return ret;
1434 }
1435 ret = SaiDriverInitDma(ppd, np, res);
1436 if (ret != HDF_SUCCESS) {
1437 ADM_LOG_ERR("SaiDriverInitDma fail ret=%d", ret);
1438 return ret;
1439 }
1440 AUDIO_DRIVER_LOG_ERR("success probe in sai driver");
1441 return HDF_SUCCESS;
1442 }
1443
SaiTriggerStart(struct fsl_sai * sai,bool tx,u8 channels,u32 dl_mask,u32 pins)1444 void SaiTriggerStart(struct fsl_sai *sai, bool tx, u8 channels, u32 dl_mask, u32 pins)
1445 {
1446 unsigned char offset = sai->reg_offset;
1447 int i = 0, j = 0, k = 0;
1448 /*
1449 * Asynchronous mode: Clear SYNC for both Tx and Rx.
1450 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
1451 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
1452 */
1453 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), FSL_SAI_CR2_SYNC,
1454 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
1455 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), FSL_SAI_CR2_SYNC,
1456 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
1457
1458 while (tx && i < channels) {
1459 if (dl_mask & (1 << j)) {
1460 regmap_write(sai->regmap, FSL_SAI_TDR0 + j * 0x4, 0x0);
1461 i++;
1462 k++;
1463 }
1464 j++;
1465
1466 if ((pins != 0) && (k % pins) == 0) {
1467 j = 0;
1468 }
1469 }
1470
1471 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
1472 FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
1473
1474 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
1475 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
1476 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
1477 FSL_SAI_CSR_SE, FSL_SAI_CSR_SE);
1478 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
1479 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
1480 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
1481 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
1482 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
1483 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
1484 }
1485
1486 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
1487 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
1488 }
SaiTriggerStop(struct fsl_sai * sai,bool tx)1489 void SaiTriggerStop(struct fsl_sai *sai, bool tx)
1490 {
1491 unsigned char offset = sai->reg_offset;
1492 u32 xcsr = 0, count = 100;
1493
1494 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
1495 FSL_SAI_CSR_FRDE, 0);
1496 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
1497 FSL_SAI_CSR_xIE_MASK, 0);
1498
1499 /* Check if the opposite FRDE is also disabled */
1500 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, offset), &xcsr);
1501 if (!(xcsr & FSL_SAI_CSR_FRDE)) {
1502 /* Disable both directions and reset their FIFOs */
1503 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
1504 FSL_SAI_CSR_TERE, 0);
1505 regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
1506 FSL_SAI_CSR_TERE, 0);
1507
1508 /* TERE will remain set till the end of current frame */
1509 do {
1510 udelay(DELAY_10);
1511 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, offset), &xcsr);
1512 } while (((--count) && (xcsr)) & (FSL_SAI_CSR_TERE));
1513
1514 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
1515 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
1516 regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
1517 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
1518
1519 /*
1520 * For sai master mode, after several open/close sai,
1521 * there will be no frame clock, and can't recover
1522 * anymore. Add software reset to fix this issue.
1523 * This is a hardware bug, and will be fix in the
1524 * next sai version.
1525 */
1526 if (!sai->slave_mode[tx]) {
1527 /* Software Reset for both Tx and Rx */
1528 regmap_write(sai->regmap,
1529 FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
1530 regmap_write(sai->regmap,
1531 FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
1532 /* Clear SR bit to finish the reset */
1533 regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
1534 regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
1535 }
1536 }
1537 }
1538
SaiTrigger(const struct DaiData * pd,int cmd,int isTx)1539 int32_t SaiTrigger(const struct DaiData *pd, int cmd, int isTx)
1540 {
1541 struct fsl_sai *sai = g_sai;
1542 bool tx = isTx == TRIGGER_TX;
1543 u8 channels = 0;
1544 u32 slots = (channels == 1) ? 2 : channels;
1545 u32 pins = 0;
1546 u32 dl_mask = 0;
1547
1548 if (isTx == TRIGGER_TX) {
1549 channels = pd->pcmInfo.channels;
1550 } else if (isTx == TRIGGER_RX) {
1551 channels = pd->pcmInfo.channels;
1552 }
1553
1554 if (sai->slots) {
1555 slots = sai->slots;
1556 }
1557
1558 pins = DIV_ROUND_UP(channels, slots);
1559 dl_mask = SaiGetdlMask(sai, tx, pins);
1560
1561 if (cmd == TRIGGER_START) {
1562 SaiTriggerStart(sai, tx, channels, dl_mask, pins);
1563 } else {
1564 SaiTriggerStop(sai, tx);
1565 }
1566
1567 SaiPrintAllRegister();
1568 return HDF_SUCCESS;
1569 }
1570
1571 #define DELAY_1000 (1000)
1572 #define DELAY_2000 (2000)
SaiRuntimeResume(const struct PlatformData * platformData)1573 int32_t SaiRuntimeResume(const struct PlatformData *platformData)
1574 {
1575 struct fsl_sai *sai = GetDrvSai(platformData);
1576 uint8_t offset = sai->reg_offset;
1577 int32_t ret;
1578
1579 AUDIO_DRIVER_LOG_ERR("bus_clk enable");
1580 ret = clk_prepare_enable(sai->bus_clk);
1581 if (ret) {
1582 AUDIO_DRIVER_LOG_ERR("failed to enable bus clock: %d\n", ret);
1583 return ret;
1584 }
1585
1586 if (sai->mclk_streams & BIT(AUDIO_RENDER_STREAM)) {
1587 AUDIO_DRIVER_LOG_ERR("mclk enable %d", sai->mclk_id[TX]);
1588 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[TX]]);
1589 if (ret) {
1590 clk_disable_unprepare(sai->bus_clk);
1591 return ret;
1592 }
1593 }
1594
1595 if (sai->mclk_streams & BIT(AUDIO_CAPTURE_STREAM)) {
1596 AUDIO_DRIVER_LOG_ERR("mclk enable %d", sai->mclk_id[RX]);
1597 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[RX]]);
1598 if (ret) {
1599 if (sai->mclk_streams & BIT(AUDIO_RENDER_STREAM)) {
1600 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1601 }
1602 clk_disable_unprepare(sai->bus_clk);
1603
1604 return ret;
1605 }
1606 }
1607
1608 request_bus_freq(BUS_FREQ_AUDIO);
1609
1610 regcache_cache_only(sai->regmap, false);
1611 regcache_mark_dirty(sai->regmap);
1612
1613 regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
1614 regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
1615 usleep_range(DELAY_1000, DELAY_2000);
1616 regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
1617 regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
1618
1619 ret = regcache_sync(sai->regmap);
1620 if (ret) {
1621 if (sai->mclk_streams & BIT(AUDIO_CAPTURE_STREAM)) {
1622 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1623 }
1624 if (sai->mclk_streams & BIT(AUDIO_RENDER_STREAM)) {
1625 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1626 }
1627 clk_disable_unprepare(sai->bus_clk);
1628
1629 return ret;
1630 }
1631
1632 return HDF_SUCCESS;
1633 }
1634
SaiRuntimeSuspend(const struct DaiData * platformData)1635 int32_t SaiRuntimeSuspend(const struct DaiData *platformData)
1636 {
1637 struct fsl_sai *sai = g_sai;
1638
1639 regcache_cache_only(sai->regmap, true);
1640
1641 release_bus_freq(BUS_FREQ_AUDIO);
1642
1643 if (sai->mclk_streams & BIT(AUDIO_CAPTURE_STREAM)) {
1644 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1645 }
1646
1647 if (sai->mclk_streams & BIT(AUDIO_RENDER_STREAM)) {
1648 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1649 }
1650
1651 clk_disable_unprepare(sai->bus_clk);
1652
1653 regcache_cache_only(sai->regmap, true);
1654 regcache_mark_dirty(sai->regmap);
1655
1656 return HDF_SUCCESS;
1657 }
1658
SaiDaiProbe(const struct PlatformData * platformData)1659 int32_t SaiDaiProbe(const struct PlatformData *platformData)
1660 {
1661 struct fsl_sai *sai = GetDrvSai(platformData);
1662 uint8_t offset = sai->reg_offset;
1663 int32_t ret = 0;
1664
1665 AUDIO_DRIVER_LOG_ERR("sai dai probe");
1666 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset),
1667 sai->fifo_depth - 1,
1668 sai->fifo_depth - FSL_SAI_MAXBURST_TX);
1669 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset),
1670 sai->fifo_depth - 1,
1671 FSL_SAI_MAXBURST_RX - 1);
1672
1673 if (!IS_ERR_OR_NULL(sai->pinctrl)) {
1674 sai->pins_state = pinctrl_lookup_state(sai->pinctrl, "default");
1675 if (!IS_ERR_OR_NULL(sai->pins_state)) {
1676 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
1677 if (ret) {
1678 AUDIO_DRIVER_LOG_ERR("failed to set properpins state");
1679 return HDF_FAILURE;
1680 }
1681 }
1682 }
1683
1684 return HDF_SUCCESS;
1685 }
1686
SaiWrite(const struct PlatformData * platformData,int i)1687 int32_t SaiWrite(const struct PlatformData *platformData, int i)
1688 {
1689 struct fsl_sai *sai = GetDrvSai(platformData);
1690
1691 regmap_update_bits(sai->regmap, FSL_SAI_TDR0, 0xFFFF, (i*0xFF+i));
1692
1693 return 0;
1694 }
1695