1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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
9 #include "audio_sapm.h"
10 #include "audio_driver_log.h"
11 #include "osal_io.h"
12 #include "osal_time.h"
13 #include "osal_thread.h"
14
15 #define HDF_LOG_TAG HDF_AUDIO_SAPM
16
17 #define SAPM_POLL_TIME 10 /* 10s */
18 #define SAPM_SLEEP_TIMES ((3 * 60) / (SAPM_POLL_TIME)) /* sleep times */
19 #define SAPM_THREAD_NAME 60
20 #define SAPM_POWER_DOWN 0
21 #define SAPM_POWER_UP 1
22 #define SAPM_STACK_SIZE 10000
23
24 #define CONNECT_CODEC_PIN 1
25 #define UNCONNECT_CODEC_PIN 0
26
27 #define EXIST_EXTERNAL_WIDGET 1
28 #define UNEXIST_EXTERNAL_WIDGET 1
29
30 #define CONNECT_SINK_AND_SOURCE 1
31 #define UNCONNECT_SINK_AND_SOURCE 0
32
33 uint32_t g_cardNum = 0;
34 static void AudioSapmTimerCallback(struct AudioCard *audioCard);
35 static int32_t AudioSapmRefreshTime(struct AudioCard *audioCard, bool bRefresh);
36
37 /* power up sequences */
38 static int32_t g_audioSapmPowerUpSeq[] = {
39 [AUDIO_SAPM_PRE] = 0, /* 0 is audio sapm power up sequences */
40 [AUDIO_SAPM_SUPPLY] = 1, /* 1 is audio sapm power up sequences */
41 [AUDIO_SAPM_MICBIAS] = 2, /* 2 is audio sapm power up sequences */
42 [AUDIO_SAPM_AIF_IN] = 3, /* 3 is audio sapm power up sequences */
43 [AUDIO_SAPM_AIF_OUT] = 3, /* 3 is audio sapm power up sequences */
44 [AUDIO_SAPM_MIC] = 4, /* 4 is audio sapm power up sequences */
45 [AUDIO_SAPM_MUX] = 5, /* 5 is audio sapm power up sequences */
46 [AUDIO_SAPM_VIRT_MUX] = 5, /* 5 is audio sapm power up sequences */
47 [AUDIO_SAPM_VALUE_MUX] = 5, /* 5 is audio sapm power up sequences */
48 [AUDIO_SAPM_DAC] = 6, /* 6 is audio sapm power up sequences */
49 [AUDIO_SAPM_MIXER] = 7, /* 7 is audio sapm power up sequences */
50 [AUDIO_SAPM_MIXER_NAMED_CTRL] = 7, /* 7 is audio sapm power up sequences */
51 [AUDIO_SAPM_PGA] = 8, /* 8 is audio sapm power up sequences */
52 [AUDIO_SAPM_ADC] = 9, /* 9 is audio sapm power up sequences */
53 [AUDIO_SAPM_OUT_DRV] = 10, /* 10 is audio sapm power up sequences */
54 [AUDIO_SAPM_HP] = 10, /* 10 is audio sapm power up sequences */
55 [AUDIO_SAPM_SPK] = 10, /* 10 is audio sapm power up sequences */
56 [AUDIO_SAPM_POST] = 11, /* 11 is audio sapm power up sequences */
57 };
58
59 /* power down sequences */
60 static int32_t g_audioSapmPowerDownSeq[] = {
61 [AUDIO_SAPM_PRE] = 0, /* 0 is audio sapm power down sequences */
62 [AUDIO_SAPM_ADC] = 1, /* 1 is audio sapm power down sequences */
63 [AUDIO_SAPM_HP] = 2, /* 2 is audio sapm power down sequences */
64 [AUDIO_SAPM_SPK] = 2, /* 2 is audio sapm power down sequences */
65 [AUDIO_SAPM_OUT_DRV] = 2, /* 2 is audio sapm power down sequences */
66 [AUDIO_SAPM_PGA] = 4, /* 4 is audio sapm power down sequences */
67 [AUDIO_SAPM_MIXER_NAMED_CTRL] = 5, /* 5 is audio sapm power down sequences */
68 [AUDIO_SAPM_MIXER] = 5, /* 5 is audio sapm power down sequences */
69 [AUDIO_SAPM_DAC] = 6, /* 6 is audio sapm power down sequences */
70 [AUDIO_SAPM_MIC] = 7, /* 7 is audio sapm power down sequences */
71 [AUDIO_SAPM_MICBIAS] = 8, /* 8 is audio sapm power down sequences */
72 [AUDIO_SAPM_MUX] = 9, /* 9 is audio sapm power down sequences */
73 [AUDIO_SAPM_VIRT_MUX] = 9, /* 9 is audio sapm power down sequences */
74 [AUDIO_SAPM_VALUE_MUX] = 9, /* 9 is audio sapm power down sequences */
75 [AUDIO_SAPM_AIF_IN] = 10, /* 10 is audio sapm power down sequences */
76 [AUDIO_SAPM_AIF_OUT] = 10, /* 10 is audio sapm power down sequences */
77 [AUDIO_SAPM_SUPPLY] = 11, /* 11 is audio sapm power down sequences */
78 [AUDIO_SAPM_POST] = 12, /* 12 is audio sapm power down sequences */
79 };
80
ConnectedInputEndPoint(const struct AudioSapmComponent * sapmComponent)81 static int32_t ConnectedInputEndPoint(const struct AudioSapmComponent *sapmComponent)
82 {
83 struct AudioSapmpath *path = NULL;
84 int32_t count = 0;
85 const int32_t endPointVal = 1;
86
87 if (sapmComponent == NULL) {
88 ADM_LOG_ERR("input param sapmComponent is NULL.");
89 return HDF_FAILURE;
90 }
91
92 switch (sapmComponent->sapmType) {
93 case AUDIO_SAPM_DAC:
94 case AUDIO_SAPM_AIF_IN:
95 case AUDIO_SAPM_INPUT:
96 case AUDIO_SAPM_MIC:
97 case AUDIO_SAPM_LINE:
98 return endPointVal;
99 default:
100 break;
101 }
102
103 DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
104 if ((path->source != NULL) && (path->connect == CONNECT_SINK_AND_SOURCE)) {
105 count += ConnectedInputEndPoint(path->source);
106 }
107 }
108 return count;
109 }
110
ConnectedOutputEndPoint(const struct AudioSapmComponent * sapmComponent)111 static int32_t ConnectedOutputEndPoint(const struct AudioSapmComponent *sapmComponent)
112 {
113 struct AudioSapmpath *path = NULL;
114 int32_t count = 0;
115 const int32_t endPointVal = 1;
116
117 if (sapmComponent == NULL) {
118 ADM_LOG_ERR("input param sapmComponent is NULL.");
119 return HDF_FAILURE;
120 }
121
122 switch (sapmComponent->sapmType) {
123 case AUDIO_SAPM_ADC:
124 case AUDIO_SAPM_AIF_OUT:
125 case AUDIO_SAPM_OUTPUT:
126 case AUDIO_SAPM_HP:
127 case AUDIO_SAPM_SPK:
128 case AUDIO_SAPM_LINE:
129 return endPointVal;
130 default:
131 break;
132 }
133
134 DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
135 if ((path->sink != NULL) && (path->connect == CONNECT_SINK_AND_SOURCE)) {
136 count += ConnectedOutputEndPoint(path->sink);
137 }
138 }
139 return count;
140 }
141
AudioSapmGenericCheckPower(const struct AudioSapmComponent * sapmComponent)142 static int32_t AudioSapmGenericCheckPower(const struct AudioSapmComponent *sapmComponent)
143 {
144 int32_t input;
145 int32_t output;
146
147 if (sapmComponent == NULL) {
148 ADM_LOG_ERR("input param cpt is NULL.");
149 return HDF_FAILURE;
150 }
151
152 input = ConnectedInputEndPoint(sapmComponent);
153 if (input == HDF_FAILURE) {
154 ADM_LOG_ERR("input endpoint fail!");
155 return HDF_FAILURE;
156 }
157 output = ConnectedOutputEndPoint(sapmComponent);
158 if (output == HDF_FAILURE) {
159 ADM_LOG_ERR("output endpoint fail!");
160 return HDF_FAILURE;
161 }
162
163 if ((input == 0) || (output == 0)) {
164 ADM_LOG_DEBUG("component %s is not in a complete path.", sapmComponent->componentName);
165 return SAPM_POWER_DOWN;
166 }
167 return SAPM_POWER_UP;
168 }
169
AudioSapmAdcPowerClock(struct AudioSapmComponent * sapmComponent)170 static int32_t AudioSapmAdcPowerClock(struct AudioSapmComponent *sapmComponent)
171 {
172 if (sapmComponent == NULL) {
173 ADM_LOG_ERR("param sapmComponent is NULL.");
174 return HDF_ERR_INVALID_PARAM;
175 }
176
177 ADM_LOG_INFO("%s standby mode entry!", sapmComponent->componentName);
178 return HDF_SUCCESS;
179 }
180
AudioSapmDacPowerClock(struct AudioSapmComponent * sapmComponent)181 static int32_t AudioSapmDacPowerClock(struct AudioSapmComponent *sapmComponent)
182 {
183 if (sapmComponent == NULL) {
184 ADM_LOG_ERR("param sapmComponent is NULL.");
185 return HDF_ERR_INVALID_PARAM;
186 }
187
188 ADM_LOG_INFO("%s standby mode entry!", sapmComponent->componentName);
189 return HDF_SUCCESS;
190 }
191
AudioSapmAdcCheckPower(const struct AudioSapmComponent * sapmComponent)192 static int32_t AudioSapmAdcCheckPower(const struct AudioSapmComponent *sapmComponent)
193 {
194 int32_t input;
195
196 if (sapmComponent == NULL) {
197 ADM_LOG_ERR("input param sapmComponent is NULL.");
198 return HDF_FAILURE;
199 }
200
201 if (sapmComponent->active == 0) {
202 input = AudioSapmGenericCheckPower(sapmComponent);
203 } else {
204 input = ConnectedInputEndPoint(sapmComponent);
205 }
206 if (input == HDF_FAILURE) {
207 ADM_LOG_ERR("input endpoint fail!");
208 return HDF_FAILURE;
209 }
210 return input;
211 }
212
AudioSapmDacCheckPower(const struct AudioSapmComponent * sapmComponent)213 static int32_t AudioSapmDacCheckPower(const struct AudioSapmComponent *sapmComponent)
214 {
215 int32_t output;
216
217 if (sapmComponent == NULL) {
218 ADM_LOG_ERR("input sapmComponent cpt is NULL.");
219 return HDF_FAILURE;
220 }
221
222 if (sapmComponent->active == 0) {
223 output = AudioSapmGenericCheckPower(sapmComponent);
224 } else {
225 output = ConnectedOutputEndPoint(sapmComponent);
226 }
227 if (output == HDF_FAILURE) {
228 ADM_LOG_ERR("output endpoint fail!");
229 return HDF_FAILURE;
230 }
231 return output;
232 }
233
AudioSampCheckPowerCallback(struct AudioSapmComponent * sapmComponent)234 static void AudioSampCheckPowerCallback(struct AudioSapmComponent *sapmComponent)
235 {
236 if (sapmComponent == NULL) {
237 ADM_LOG_ERR("input param cpt is NULL.");
238 return;
239 }
240
241 switch (sapmComponent->sapmType) {
242 case AUDIO_SAPM_ANALOG_SWITCH:
243 case AUDIO_SAPM_MIXER:
244 case AUDIO_SAPM_MIXER_NAMED_CTRL:
245 sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
246 break;
247 case AUDIO_SAPM_MUX:
248 case AUDIO_SAPM_VIRT_MUX:
249 case AUDIO_SAPM_VALUE_MUX:
250 sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
251 break;
252 case AUDIO_SAPM_ADC:
253 case AUDIO_SAPM_AIF_OUT:
254 sapmComponent->PowerCheck = AudioSapmAdcCheckPower;
255 break;
256 case AUDIO_SAPM_DAC:
257 case AUDIO_SAPM_AIF_IN:
258 sapmComponent->PowerCheck = AudioSapmDacCheckPower;
259 break;
260 case AUDIO_SAPM_PGA:
261 case AUDIO_SAPM_OUT_DRV:
262 case AUDIO_SAPM_INPUT:
263 case AUDIO_SAPM_OUTPUT:
264 case AUDIO_SAPM_MICBIAS:
265 case AUDIO_SAPM_SPK:
266 case AUDIO_SAPM_HP:
267 case AUDIO_SAPM_MIC:
268 case AUDIO_SAPM_LINE:
269 sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
270 break;
271 default:
272 sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
273 break;
274 }
275
276 return;
277 }
278
AudioSampPowerClockCallback(struct AudioSapmComponent * sapmComponent)279 static void AudioSampPowerClockCallback(struct AudioSapmComponent *sapmComponent)
280 {
281 if (sapmComponent == NULL) {
282 ADM_LOG_ERR("input param cpt is NULL.");
283 return;
284 }
285
286 switch (sapmComponent->sapmType) {
287 case AUDIO_SAPM_ANALOG_SWITCH:
288 case AUDIO_SAPM_MIXER:
289 case AUDIO_SAPM_MIXER_NAMED_CTRL:
290 sapmComponent->PowerClockOp = NULL;
291 break;
292 case AUDIO_SAPM_MUX:
293 case AUDIO_SAPM_VIRT_MUX:
294 case AUDIO_SAPM_VALUE_MUX:
295 sapmComponent->PowerClockOp = NULL;
296 break;
297 case AUDIO_SAPM_ADC:
298 case AUDIO_SAPM_AIF_OUT:
299 sapmComponent->PowerClockOp = AudioSapmAdcPowerClock;
300 break;
301 case AUDIO_SAPM_DAC:
302 case AUDIO_SAPM_AIF_IN:
303 sapmComponent->PowerClockOp = AudioSapmDacPowerClock;
304 break;
305 case AUDIO_SAPM_PGA:
306 case AUDIO_SAPM_OUT_DRV:
307 case AUDIO_SAPM_INPUT:
308 case AUDIO_SAPM_OUTPUT:
309 case AUDIO_SAPM_MICBIAS:
310 case AUDIO_SAPM_MIC:
311 case AUDIO_SAPM_SPK:
312 case AUDIO_SAPM_HP:
313 case AUDIO_SAPM_LINE:
314 sapmComponent->PowerClockOp = NULL;
315 break;
316 default:
317 sapmComponent->PowerClockOp = NULL;
318 break;
319 }
320
321 return;
322 }
323
AudioSapmNewComponent(struct AudioCard * audioCard,const struct AudioSapmComponent * component)324 static int32_t AudioSapmNewComponent(struct AudioCard *audioCard, const struct AudioSapmComponent *component)
325 {
326 struct AudioSapmComponent *sapmComponent = NULL;
327
328 if ((audioCard == NULL || audioCard->rtd == NULL)) {
329 ADM_LOG_ERR("input params check error: audioCard is NULL.");
330 return HDF_FAILURE;
331 }
332 if (component == NULL || component->componentName == NULL) {
333 ADM_LOG_ERR("params component or component->componentName is null.");
334 return HDF_FAILURE;
335 }
336
337 sapmComponent = (struct AudioSapmComponent *)OsalMemCalloc(sizeof(struct AudioSapmComponent));
338 if (sapmComponent == NULL) {
339 ADM_LOG_ERR("malloc cpt fail!");
340 return HDF_FAILURE;
341 }
342 if (memcpy_s(sapmComponent, sizeof(struct AudioSapmComponent),
343 component, sizeof(struct AudioSapmComponent)) != EOK) {
344 ADM_LOG_ERR("memcpy cpt fail!");
345 OsalMemFree(sapmComponent);
346 return HDF_FAILURE;
347 }
348
349 sapmComponent->componentName = (char *)OsalMemCalloc(strlen(component->componentName) + 1);
350 if (sapmComponent->componentName == NULL) {
351 ADM_LOG_ERR("malloc cpt->componentName fail!");
352 OsalMemFree(sapmComponent);
353 return HDF_FAILURE;
354 }
355 if (memcpy_s(sapmComponent->componentName, strlen(component->componentName) + 1,
356 component->componentName, strlen(component->componentName) + 1) != EOK) {
357 ADM_LOG_ERR("memcpy cpt->componentName fail!");
358 OsalMemFree(sapmComponent->componentName);
359 OsalMemFree(sapmComponent);
360 return HDF_FAILURE;
361 }
362
363 sapmComponent->codec = audioCard->rtd->codec;
364 sapmComponent->kcontrolsNum = component->kcontrolsNum;
365 sapmComponent->active = 0;
366 AudioSampCheckPowerCallback(sapmComponent);
367 AudioSampPowerClockCallback(sapmComponent);
368
369 DListHeadInit(&sapmComponent->sources);
370 DListHeadInit(&sapmComponent->sinks);
371 DListHeadInit(&sapmComponent->list);
372 DListHeadInit(&sapmComponent->dirty);
373 DListInsertHead(&sapmComponent->list, &audioCard->components);
374
375 sapmComponent->connected = CONNECT_CODEC_PIN;
376
377 return HDF_SUCCESS;
378 }
379
AudioSapmNewComponents(struct AudioCard * audioCard,const struct AudioSapmComponent * component,int32_t cptMaxNum)380 int32_t AudioSapmNewComponents(struct AudioCard *audioCard,
381 const struct AudioSapmComponent *component, int32_t cptMaxNum)
382 {
383 int32_t i;
384 int32_t ret;
385
386 if (audioCard == NULL) {
387 ADM_LOG_ERR("input params check error: audioCard is NULL.");
388 return HDF_FAILURE;
389 }
390 if (component == NULL) {
391 ADM_LOG_ERR("input params check error: component is NULL.");
392 return HDF_FAILURE;
393 }
394
395 for (i = 0; i < cptMaxNum; i++) {
396 ret = AudioSapmNewComponent(audioCard, component);
397 if (ret != HDF_SUCCESS) {
398 ADM_LOG_ERR("AudioSapmNewComponent fail!");
399 return HDF_FAILURE;
400 }
401 component++;
402 }
403
404 return HDF_SUCCESS;
405 }
406
MuxSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,const struct AudioEnumKcontrol * enumKtl,int32_t i)407 static void MuxSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
408 const struct AudioEnumKcontrol *enumKtl, int32_t i)
409 {
410 int32_t ret;
411 uint32_t val = 0;
412 int32_t curValue;
413 uint32_t shift;
414
415 if (sapmComponent == NULL || sapmComponent->codec == NULL) {
416 ADM_LOG_ERR("input MuxSet params check error");
417 return;
418 }
419 if (path == NULL || path->name == NULL) {
420 ADM_LOG_ERR("input params check error: path is NULL.");
421 return;
422 }
423 if (enumKtl == NULL) {
424 ADM_LOG_ERR("input params check error: enumKtl is NULL.");
425 return;
426 }
427
428 shift = enumKtl->shiftLeft;
429 ret = AudioCodecReadReg(sapmComponent->codec, enumKtl->reg, &val);
430 if (ret != HDF_SUCCESS) {
431 ADM_LOG_ERR("codec read reg fail!");
432 return;
433 }
434
435 curValue = (val >> shift) & enumKtl->mask;
436 path->connect = UNCONNECT_SINK_AND_SOURCE;
437
438 if (enumKtl->texts != NULL) {
439 for (i = 0; i < enumKtl->max; i++) {
440 if (enumKtl->texts[i] == NULL) {
441 ADM_LOG_ERR("enumKtl->texts[%d] is NULL", i);
442 continue;
443 }
444
445 if ((strcmp(path->name, enumKtl->texts[i]) == 0) && curValue == i) {
446 path->connect = CONNECT_SINK_AND_SOURCE;
447 }
448 }
449 } else {
450 if (curValue) {
451 path->connect = CONNECT_SINK_AND_SOURCE;
452 }
453 }
454
455 return;
456 }
457
MuxValueSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,const struct AudioEnumKcontrol * enumKtl,int32_t i)458 static void MuxValueSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
459 const struct AudioEnumKcontrol *enumKtl, int32_t i)
460 {
461 int32_t ret;
462 uint32_t val = 0;
463 uint32_t item;
464 uint32_t shift;
465 if (sapmComponent == NULL || sapmComponent->codec == NULL) {
466 ADM_LOG_ERR("input muxValueSet params check error");
467 return;
468 }
469 if (path == NULL || path->name == NULL) {
470 ADM_LOG_ERR("input MuxValueSet params check error: path is NULL.");
471 return;
472 }
473 if (enumKtl == NULL) {
474 ADM_LOG_ERR("input MuxValueSet params check error: enumKtl is NULL.");
475 return;
476 }
477 shift = enumKtl->shiftLeft;
478 ret = AudioCodecReadReg(sapmComponent->codec, enumKtl->reg, &val);
479 if (ret != HDF_SUCCESS) {
480 ADM_LOG_ERR("muxValueSet read reg fail!");
481 return;
482 }
483
484 val = (val >> shift) & enumKtl->mask;
485 path->connect = UNCONNECT_SINK_AND_SOURCE;
486
487 if (enumKtl->values != NULL && enumKtl->texts != NULL) {
488 for (item = 0; item < enumKtl->max; item++) {
489 if (val == enumKtl->values[item]) {
490 break;
491 }
492 }
493
494 for (i = 0; i < enumKtl->max; i++) {
495 if (enumKtl->texts[i] == NULL) {
496 continue;
497 }
498 if ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) {
499 path->connect = CONNECT_SINK_AND_SOURCE;
500 }
501 }
502 } else {
503 if (val) {
504 path->connect = CONNECT_SINK_AND_SOURCE;
505 }
506 }
507
508 return;
509 }
510
MixerSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,const struct AudioMixerControl * mixerCtrl)511 static void MixerSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
512 const struct AudioMixerControl *mixerCtrl)
513 {
514 int32_t ret;
515 uint32_t reg;
516 uint32_t mask;
517 uint32_t shift;
518 uint32_t invert;
519 uint32_t curValue = 0;
520
521 if (sapmComponent == NULL) {
522 ADM_LOG_ERR("input params check error: sapmComponent is NULL.");
523 return;
524 }
525 if (path == NULL) {
526 ADM_LOG_ERR("input params check error: path is NULL.");
527 return;
528 }
529 if (mixerCtrl == NULL) {
530 ADM_LOG_ERR("input params check error: mixerCtrl is NULL.");
531 return;
532 }
533
534 reg = mixerCtrl->reg;
535 shift = mixerCtrl->shift;
536 mask = mixerCtrl->mask;
537 invert = mixerCtrl->invert;
538
539 if (sapmComponent->codec != NULL) {
540 ret = AudioCodecReadReg(sapmComponent->codec, reg, &curValue);
541 if (ret != HDF_SUCCESS) {
542 ADM_LOG_ERR("read reg fail!");
543 return;
544 }
545 } else {
546 ADM_LOG_ERR("codec is null!");
547 return;
548 }
549
550 curValue = (curValue >> shift) & mask;
551 if ((invert && !curValue) || (!invert && curValue)) {
552 path->connect = CONNECT_SINK_AND_SOURCE;
553 } else {
554 path->connect = UNCONNECT_SINK_AND_SOURCE;
555 }
556
557 return;
558 }
559
AudioSapmSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,int32_t i)560 static int32_t AudioSapmSetPathStatus(const struct AudioSapmComponent *sapmComponent,
561 struct AudioSapmpath *path, int32_t i)
562 {
563 if ((sapmComponent == NULL) || (path == NULL)) {
564 ADM_LOG_ERR("input params check error");
565 return HDF_FAILURE;
566 }
567 switch (sapmComponent->sapmType) {
568 case AUDIO_SAPM_MIXER:
569 case AUDIO_SAPM_ANALOG_SWITCH:
570 case AUDIO_SAPM_MIXER_NAMED_CTRL:
571 MixerSetPathStatus(sapmComponent, path,
572 (struct AudioMixerControl *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue));
573 break;
574 case AUDIO_SAPM_MUX:
575 MuxSetPathStatus(sapmComponent, path,
576 (struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
577 break;
578 case AUDIO_SAPM_VALUE_MUX:
579 MuxValueSetPathStatus(sapmComponent, path,
580 (struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
581 break;
582 default:
583 path->connect = CONNECT_SINK_AND_SOURCE;
584 break;
585 }
586
587 return HDF_SUCCESS;
588 }
589
AudioSapmConnectMux(struct AudioCard * audioCard,struct AudioSapmComponent * source,struct AudioSapmComponent * sink,struct AudioSapmpath * path,const char * controlName)590 static int32_t AudioSapmConnectMux(struct AudioCard *audioCard,
591 struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
592 struct AudioSapmpath *path, const char *controlName)
593 {
594 int32_t i;
595 struct AudioEnumKcontrol *enumKtl = NULL;
596
597 if ((audioCard == NULL) || (source == NULL) || (sink == NULL) || (path == NULL) || (controlName == NULL)) {
598 ADM_LOG_ERR("input params check error");
599 return HDF_FAILURE;
600 }
601
602 if (sink->kcontrolNews == NULL) {
603 ADM_LOG_ERR("input params sink kcontrolNews is null.");
604 return HDF_FAILURE;
605 }
606 enumKtl = (struct AudioEnumKcontrol *)&sink->kcontrolNews[0].privateValue;
607 if (enumKtl == NULL || enumKtl->texts == NULL) {
608 ADM_LOG_ERR("kcontrolNews privateValue is null.");
609 return HDF_FAILURE;
610 }
611
612 for (i = 0; i < enumKtl->max; i++) {
613 if (strcmp(controlName, enumKtl->texts[i]) == 0) {
614 DListInsertHead(&path->list, &audioCard->paths);
615 DListInsertHead(&path->listSink, &sink->sources);
616 DListInsertHead(&path->listSource, &source->sinks);
617 path->name = (char*)enumKtl->texts[i];
618 AudioSapmSetPathStatus(sink, path, i);
619
620 return HDF_SUCCESS;
621 }
622 }
623
624 return HDF_FAILURE;
625 }
626
AudioSapmConnectMixer(struct AudioCard * audioCard,struct AudioSapmComponent * source,struct AudioSapmComponent * sink,struct AudioSapmpath * path,const char * controlName)627 static int32_t AudioSapmConnectMixer(struct AudioCard *audioCard,
628 struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
629 struct AudioSapmpath *path, const char *controlName)
630 {
631 int32_t i;
632
633 if ((audioCard == NULL) || (source == NULL) || (sink == NULL) || (path == NULL) || (controlName == NULL)) {
634 ADM_LOG_ERR("input params check error");
635 return HDF_FAILURE;
636 }
637
638 for (i = 0; i < sink->kcontrolsNum; i++) {
639 if (sink->kcontrolNews[i].name == NULL) {
640 continue;
641 }
642
643 if (strcmp(controlName, sink->kcontrolNews[i].name) == 0) {
644 path->name = (char *)OsalMemCalloc(strlen(sink->kcontrolNews[i].name) + 1);
645 if (path->name == NULL) {
646 ADM_LOG_ERR("malloc path->name fail!");
647 return HDF_FAILURE;
648 }
649 if (memcpy_s(path->name, strlen(sink->kcontrolNews[i].name) + 1, sink->kcontrolNews[i].name,
650 strlen(sink->kcontrolNews[i].name) + 1) != EOK) {
651 OsalMemFree(path->name);
652 ADM_LOG_ERR("memcpy cpt->componentName fail!");
653 return HDF_FAILURE;
654 }
655 DListInsertHead(&path->list, &audioCard->paths);
656 DListInsertHead(&path->listSink, &sink->sources);
657 DListInsertHead(&path->listSource, &source->sinks);
658
659 AudioSapmSetPathStatus(sink, path, i);
660
661 return HDF_SUCCESS;
662 }
663 }
664
665 return HDF_FAILURE;
666 }
667
AudioSampStaticOrDynamicPath(struct AudioCard * audioCard,struct AudioSapmComponent * source,struct AudioSapmComponent * sink,struct AudioSapmpath * path,const struct AudioSapmRoute * route)668 static int32_t AudioSampStaticOrDynamicPath(struct AudioCard *audioCard,
669 struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
670 struct AudioSapmpath *path, const struct AudioSapmRoute *route)
671 {
672 int32_t ret;
673
674 if (route->control == NULL) {
675 DListInsertHead(&path->list, &audioCard->paths);
676 DListInsertHead(&path->listSink, &sink->sources);
677 DListInsertHead(&path->listSource, &source->sinks);
678 path->connect = CONNECT_SINK_AND_SOURCE;
679 return HDF_SUCCESS;
680 }
681
682 switch (sink->sapmType) {
683 case AUDIO_SAPM_MUX:
684 case AUDIO_SAPM_VIRT_MUX:
685 case AUDIO_SAPM_VALUE_MUX:
686 ret = AudioSapmConnectMux(audioCard, source, sink, path, route->control);
687 if (ret != HDF_SUCCESS) {
688 ADM_LOG_ERR("connect mux fail!");
689 return HDF_FAILURE;
690 }
691 break;
692 case AUDIO_SAPM_ANALOG_SWITCH:
693 case AUDIO_SAPM_MIXER:
694 case AUDIO_SAPM_MIXER_NAMED_CTRL:
695 case AUDIO_SAPM_PGA:
696 case AUDIO_SAPM_SPK:
697 ret = AudioSapmConnectMixer(audioCard, source, sink, path, route->control);
698 if (ret != HDF_SUCCESS) {
699 ADM_LOG_ERR("connect mixer fail!");
700 return HDF_FAILURE;
701 }
702 break;
703 case AUDIO_SAPM_HP:
704 case AUDIO_SAPM_MIC:
705 case AUDIO_SAPM_LINE:
706 DListInsertHead(&path->list, &audioCard->paths);
707 DListInsertHead(&path->listSink, &sink->sources);
708 DListInsertHead(&path->listSource, &source->sinks);
709 path->connect = CONNECT_SINK_AND_SOURCE;
710 break;
711 default:
712 DListInsertHead(&path->list, &audioCard->paths);
713 DListInsertHead(&path->listSink, &sink->sources);
714 DListInsertHead(&path->listSource, &source->sinks);
715 path->connect = CONNECT_SINK_AND_SOURCE;
716 break;
717 }
718
719 return HDF_SUCCESS;
720 }
721
AudioSampExtComponentsCheck(struct AudioSapmComponent * cptSource,struct AudioSapmComponent * cptSink)722 static void AudioSampExtComponentsCheck(struct AudioSapmComponent *cptSource, struct AudioSapmComponent *cptSink)
723 {
724 if ((cptSource == NULL) || (cptSink == NULL)) {
725 ADM_LOG_ERR("input params check error");
726 return;
727 }
728
729 /* check for external components */
730 if (cptSink->sapmType == AUDIO_SAPM_INPUT) {
731 if (cptSource->sapmType == AUDIO_SAPM_MICBIAS || cptSource->sapmType == AUDIO_SAPM_MIC ||
732 cptSource->sapmType == AUDIO_SAPM_LINE || cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
733 cptSink->external = EXIST_EXTERNAL_WIDGET;
734 }
735 }
736 if (cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
737 if (cptSink->sapmType == AUDIO_SAPM_SPK || cptSink->sapmType == AUDIO_SAPM_HP ||
738 cptSink->sapmType == AUDIO_SAPM_LINE || cptSink->sapmType == AUDIO_SAPM_INPUT) {
739 cptSource->external = EXIST_EXTERNAL_WIDGET;
740 }
741 }
742
743 return;
744 }
745
AudioSapmAddRoute(struct AudioCard * audioCard,const struct AudioSapmRoute * route)746 static int32_t AudioSapmAddRoute(struct AudioCard *audioCard, const struct AudioSapmRoute *route)
747 {
748 struct AudioSapmpath *path = NULL;
749 struct AudioSapmComponent *cptSource = NULL;
750 struct AudioSapmComponent *cptSink = NULL;
751 struct AudioSapmComponent *sapmComponent = NULL;
752 int32_t ret;
753
754 if (route == NULL || route->source == NULL || route->sink == NULL) {
755 ADM_LOG_ERR("input params check error: route is NULL.");
756 return HDF_FAILURE;
757 }
758
759 DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
760 if (sapmComponent->componentName == NULL) {
761 continue;
762 }
763 if ((cptSource == NULL) && (strcmp(sapmComponent->componentName, route->source) == 0)) {
764 cptSource = sapmComponent;
765 continue;
766 }
767 if ((cptSink == NULL) && (strcmp(sapmComponent->componentName, route->sink) == 0)) {
768 cptSink = sapmComponent;
769 }
770 if ((cptSource != NULL) && (cptSink != NULL)) {
771 break;
772 }
773 }
774 if ((cptSource == NULL) || (cptSink == NULL)) {
775 ADM_LOG_ERR("find component fail!");
776 return HDF_FAILURE;
777 }
778
779 path = (struct AudioSapmpath *)OsalMemCalloc(sizeof(struct AudioSapmpath));
780 if (path == NULL) {
781 ADM_LOG_ERR("malloc path fail!");
782 return HDF_FAILURE;
783 }
784 path->source = cptSource;
785 path->sink = cptSink;
786 DListHeadInit(&path->list);
787 DListHeadInit(&path->listSink);
788 DListHeadInit(&path->listSource);
789
790 /* check for external components */
791 AudioSampExtComponentsCheck(cptSource, cptSink);
792
793 ret = AudioSampStaticOrDynamicPath(audioCard, cptSource, cptSink, path, route);
794 if (ret != HDF_SUCCESS) {
795 OsalMemFree(path);
796 ADM_LOG_ERR("static or dynamic path fail!");
797 return HDF_FAILURE;
798 }
799 return HDF_SUCCESS;
800 }
801
AudioSapmAddRoutes(struct AudioCard * audioCard,const struct AudioSapmRoute * route,int32_t routeMaxNum)802 int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, const struct AudioSapmRoute *route, int32_t routeMaxNum)
803 {
804 int32_t i;
805 int32_t ret;
806
807 if (audioCard == NULL) {
808 ADM_LOG_ERR("input params check error: audioCard is NULL.");
809 return HDF_FAILURE;
810 }
811 if (route == NULL) {
812 ADM_LOG_ERR("input params check error: route is NULL.");
813 return HDF_FAILURE;
814 }
815
816 for (i = 0; i < routeMaxNum; i++) {
817 ret = AudioSapmAddRoute(audioCard, route);
818 if (ret != HDF_SUCCESS) {
819 ADM_LOG_ERR("AudioSapmAddRoute failed!");
820 return HDF_FAILURE;
821 }
822 route++;
823 }
824 return HDF_SUCCESS;
825 }
826
AudioSapmNewMixerControls(const struct AudioSapmComponent * sapmComponent,struct AudioCard * audioCard)827 static int32_t AudioSapmNewMixerControls(
828 const struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
829 {
830 struct AudioSapmpath *path = NULL;
831 int32_t i;
832
833 if (sapmComponent == NULL || sapmComponent->kcontrols == NULL) {
834 ADM_LOG_ERR("input params check error: sapmComponent is NULL.");
835 return HDF_FAILURE;
836 }
837 if (audioCard == NULL) {
838 ADM_LOG_ERR("input params check error: audioCard is NULL.");
839 return HDF_FAILURE;
840 }
841
842 for (i = 0; i < sapmComponent->kcontrolsNum; i++) {
843 DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
844 if (path->name == NULL || sapmComponent->kcontrolNews == NULL
845 || sapmComponent->kcontrolNews[i].name == NULL) {
846 continue;
847 }
848
849 if (strcmp(path->name, sapmComponent->kcontrolNews[i].name) != 0) {
850 continue;
851 }
852
853 path->kcontrol = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[i]);
854 if (path->kcontrol == NULL) {
855 ADM_LOG_ERR("add control fail!");
856 return HDF_FAILURE;
857 }
858 sapmComponent->kcontrols[i] = path->kcontrol;
859 DListInsertHead(&sapmComponent->kcontrols[i]->list, &audioCard->controls);
860 }
861 }
862
863 return HDF_SUCCESS;
864 }
865
AudioSapmNewMuxControls(struct AudioSapmComponent * sapmComponent,struct AudioCard * audioCard)866 static int32_t AudioSapmNewMuxControls(struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
867 {
868 struct AudioKcontrol *kctrl = NULL;
869
870 if (sapmComponent == NULL || sapmComponent->kcontrolNews == NULL || audioCard == NULL) {
871 ADM_LOG_ERR("input param is NULL.");
872 return HDF_FAILURE;
873 }
874
875 if (sapmComponent->kcontrolsNum != 1) {
876 ADM_LOG_ERR("incorrect number of controls.");
877 return HDF_FAILURE;
878 }
879
880 kctrl = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[0]);
881 if (kctrl == NULL) {
882 ADM_LOG_ERR("add control fail!");
883 return HDF_FAILURE;
884 }
885
886 if (sapmComponent->kcontrols == NULL) {
887 OsalMemFree(kctrl);
888 kctrl = NULL;
889 ADM_LOG_ERR("sapmComponent->kcontrols is NULL!");
890 return HDF_FAILURE;
891 }
892 sapmComponent->kcontrols[0] = kctrl;
893 DListInsertHead(&sapmComponent->kcontrols[0]->list, &audioCard->controls);
894
895 return HDF_SUCCESS;
896 }
897
AudioSapmPowerSeqInsert(struct AudioSapmComponent * newSapmComponent,struct DListHead * list,int8_t isPowerUp)898 static void AudioSapmPowerSeqInsert(struct AudioSapmComponent *newSapmComponent,
899 struct DListHead *list, int8_t isPowerUp)
900 {
901 struct AudioSapmComponent *sapmComponent = NULL;
902 int32_t *seq = {0};
903
904 if (newSapmComponent == NULL || list == NULL || newSapmComponent->componentName == NULL) {
905 ADM_LOG_ERR("input param newCpt is NULL.");
906 return;
907 }
908
909 if (isPowerUp) {
910 seq = g_audioSapmPowerUpSeq;
911 } else {
912 seq = g_audioSapmPowerDownSeq;
913 }
914
915 DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
916 if ((seq[newSapmComponent->sapmType] - seq[sapmComponent->sapmType]) < 0) {
917 DListInsertTail(&newSapmComponent->powerList, &sapmComponent->powerList);
918 return;
919 }
920 }
921 DListInsertTail(&newSapmComponent->powerList, list);
922
923 ADM_LOG_DEBUG("[%s] success.", newSapmComponent->componentName);
924 return;
925 }
926
AudioSapmSetPower(struct AudioCard * audioCard,struct AudioSapmComponent * sapmComponent,uint8_t power,struct DListHead * upList,struct DListHead * downList)927 static void AudioSapmSetPower(struct AudioCard *audioCard, struct AudioSapmComponent *sapmComponent,
928 uint8_t power, struct DListHead *upList, struct DListHead *downList)
929 {
930 struct AudioSapmpath *path = NULL;
931
932 if (sapmComponent == NULL) {
933 ADM_LOG_ERR("input param sapmComponent is NULL.");
934 return;
935 }
936
937 DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
938 if (path->source != NULL) {
939 if ((path->source->power != power) && path->connect) {
940 if (DListIsEmpty(&path->source->dirty)) {
941 DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
942 }
943 }
944 }
945 }
946 DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
947 if (path->sink != NULL) {
948 if ((path->sink->power != power) && path->connect) {
949 if (DListIsEmpty(&path->sink->dirty)) {
950 DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
951 }
952 }
953 }
954 }
955
956 if (power) {
957 AudioSapmPowerSeqInsert(sapmComponent, upList, power);
958 } else {
959 AudioSapmPowerSeqInsert(sapmComponent, downList, power);
960 }
961
962 return;
963 }
964
AudioSapmPowerUpSeqRun(const struct DListHead * list)965 static void AudioSapmPowerUpSeqRun(const struct DListHead *list)
966 {
967 uint32_t val;
968 struct AudioMixerControl mixerControl;
969 struct AudioSapmComponent *sapmComponent = NULL;
970 ADM_LOG_DEBUG("entry!");
971 if (list == NULL) {
972 ADM_LOG_ERR("input param list is NULL.");
973 return;
974 }
975
976 DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
977 if (sapmComponent->power == SAPM_POWER_DOWN) {
978 val = SAPM_POWER_UP;
979 if (sapmComponent->invert) {
980 val = !val;
981 }
982 sapmComponent->power = SAPM_POWER_UP;
983 if (sapmComponent->reg != AUDIO_NO_SAPM_REG) {
984 mixerControl.reg = sapmComponent->reg;
985 mixerControl.mask = sapmComponent->mask;
986 mixerControl.shift = sapmComponent->shift;
987 AudioUpdateCodecRegBits(sapmComponent->codec, mixerControl.reg, mixerControl.mask,
988 mixerControl.shift, val);
989 ADM_LOG_INFO("Sapm Codec %s Power Up.", sapmComponent->componentName);
990 }
991 }
992 }
993
994 return;
995 }
996
AudioSapmPowerDownSeqRun(const struct DListHead * list)997 static void AudioSapmPowerDownSeqRun(const struct DListHead *list)
998 {
999 uint32_t val;
1000 struct AudioMixerControl mixerControl;
1001 struct AudioSapmComponent *sapmComponent = NULL;
1002 ADM_LOG_DEBUG("entry!");
1003
1004 if (list == NULL) {
1005 ADM_LOG_ERR("sapm input param list is NULL.");
1006 return;
1007 }
1008 DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
1009 if (sapmComponent->power == SAPM_POWER_UP) {
1010 val = SAPM_POWER_DOWN;
1011 if (sapmComponent->invert) {
1012 val = !val;
1013 }
1014 sapmComponent->power = SAPM_POWER_DOWN;
1015
1016 if (sapmComponent->reg != AUDIO_NO_SAPM_REG) {
1017 mixerControl.mask = sapmComponent->mask;
1018 mixerControl.reg = sapmComponent->reg;
1019 mixerControl.shift = sapmComponent->shift;
1020
1021 AudioUpdateCodecRegBits(sapmComponent->codec, mixerControl.reg, mixerControl.mask,
1022 mixerControl.shift, val);
1023 ADM_LOG_INFO("Sapm Codec %s Power Down.", sapmComponent->componentName);
1024 }
1025 }
1026 }
1027
1028 return;
1029 }
1030
AudioSapmPowerComponents(struct AudioCard * audioCard)1031 static void AudioSapmPowerComponents(struct AudioCard *audioCard)
1032 {
1033 int32_t ret;
1034 struct AudioSapmComponent *sapmComponent = NULL;
1035 struct DListHead upList;
1036 struct DListHead downList;
1037 ADM_LOG_DEBUG("entry!");
1038
1039 if (audioCard == NULL) {
1040 ADM_LOG_ERR("input param audioCard is NULL.");
1041 return;
1042 }
1043
1044 DListHeadInit(&upList);
1045 DListHeadInit(&downList);
1046
1047 DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->sapmDirty, struct AudioSapmComponent, dirty) {
1048 sapmComponent->newPower = sapmComponent->PowerCheck(sapmComponent);
1049 if (sapmComponent->newPower == sapmComponent->power) {
1050 continue;
1051 }
1052
1053 if (audioCard->sapmStandbyState && sapmComponent->PowerClockOp != NULL) {
1054 ret = sapmComponent->PowerClockOp(sapmComponent);
1055 if (ret != HDF_SUCCESS) {
1056 continue;
1057 }
1058 }
1059
1060 AudioSapmSetPower(audioCard, sapmComponent, sapmComponent->newPower, &upList, &downList);
1061 }
1062
1063 DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1064 DListRemove(&sapmComponent->dirty);
1065 DListHeadInit(&sapmComponent->dirty);
1066 }
1067
1068 AudioSapmPowerDownSeqRun(&downList);
1069 AudioSapmPowerUpSeqRun(&upList);
1070 }
1071
ReadInitComponentPowerStatus(struct AudioSapmComponent * sapmComponent)1072 static void ReadInitComponentPowerStatus(struct AudioSapmComponent *sapmComponent)
1073 {
1074 int32_t ret;
1075 uint32_t regVal = 0;
1076
1077 if (sapmComponent == NULL || sapmComponent->codec == NULL) {
1078 ADM_LOG_ERR("input param sapmComponent is NULL.");
1079 return;
1080 }
1081
1082 if (sapmComponent->reg != AUDIO_NO_SAPM_REG) {
1083 ret = AudioCodecReadReg(sapmComponent->codec, sapmComponent->reg, ®Val);
1084 if (ret != HDF_SUCCESS) {
1085 ADM_LOG_ERR("read reg fail!");
1086 return;
1087 }
1088 regVal &= 1 << sapmComponent->shift;
1089
1090 if (sapmComponent->invert) {
1091 regVal = !regVal;
1092 }
1093
1094 if (regVal) {
1095 sapmComponent->power = SAPM_POWER_UP;
1096 } else {
1097 sapmComponent->power = SAPM_POWER_DOWN;
1098 }
1099 }
1100
1101 return;
1102 }
1103
AudioSapmThread(void * data)1104 static int AudioSapmThread(void *data)
1105 {
1106 struct AudioCard *audioCard = (struct AudioCard *)data;
1107 audioCard->time = 0;
1108
1109 while (true) {
1110 OsalSleep(SAPM_POLL_TIME);
1111 AudioSapmTimerCallback(audioCard);
1112 audioCard->time++;
1113 }
1114
1115 return 0;
1116 }
1117
AudioSapmSleep(struct AudioCard * audioCard)1118 int32_t AudioSapmSleep(struct AudioCard *audioCard)
1119 {
1120 int32_t ret;
1121 char *sapmThreadName = NULL;
1122 struct OsalThreadParam threadCfg;
1123 OSAL_DECLARE_THREAD(audioSapmThread);
1124
1125 if (audioCard == NULL) {
1126 ADM_LOG_ERR("input param audioCard is NULL.");
1127 return HDF_ERR_INVALID_OBJECT;
1128 }
1129
1130 (void)AudioSapmRefreshTime(audioCard, true);
1131 sapmThreadName = OsalMemCalloc(SAPM_THREAD_NAME);
1132 if (sapmThreadName == NULL) {
1133 return HDF_ERR_MALLOC_FAIL;
1134 }
1135 if (snprintf_s(sapmThreadName, SAPM_THREAD_NAME, SAPM_THREAD_NAME - 1, "AudioSapmThread%u", g_cardNum) < 0) {
1136 ADM_LOG_ERR("snprintf_s failed.");
1137 OsalMemFree(sapmThreadName);
1138 return HDF_FAILURE;
1139 }
1140
1141 ret = OsalThreadCreate(&audioSapmThread, (OsalThreadEntry)AudioSapmThread, (void *)audioCard);
1142 if (ret != HDF_SUCCESS) {
1143 ADM_LOG_ERR("create sapm thread fail, ret=%d", ret);
1144 OsalMemFree(sapmThreadName);
1145 return HDF_FAILURE;
1146 }
1147
1148 (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
1149 threadCfg.name = sapmThreadName;
1150 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
1151 threadCfg.stackSize = SAPM_STACK_SIZE;
1152 ret = OsalThreadStart(&audioSapmThread, &threadCfg);
1153 if (ret != HDF_SUCCESS) {
1154 ADM_LOG_ERR("start sapm thread fail, ret=%d", ret);
1155 OsalThreadDestroy(&audioSapmThread);
1156 OsalMemFree(sapmThreadName);
1157 return HDF_FAILURE;
1158 }
1159
1160 g_cardNum++;
1161 audioCard->sapmStandbyState = false;
1162 audioCard->sapmSleepState = false;
1163 OsalMemFree(sapmThreadName);
1164
1165 return HDF_SUCCESS;
1166 }
1167
AudioSapmNewControls(struct AudioCard * audioCard)1168 int32_t AudioSapmNewControls(struct AudioCard *audioCard)
1169 {
1170 struct AudioSapmComponent *sapmComponent = NULL;
1171 int32_t ret = HDF_SUCCESS;
1172
1173 if (audioCard == NULL) {
1174 ADM_LOG_ERR("input param audioCard is NULL.");
1175 return HDF_ERR_INVALID_OBJECT;
1176 }
1177
1178 DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1179 if (sapmComponent->newCpt) {
1180 continue;
1181 }
1182 if (sapmComponent->kcontrolsNum > 0) {
1183 sapmComponent->kcontrols = OsalMemCalloc(sizeof(struct AudioKcontrol*) * sapmComponent->kcontrolsNum);
1184 if (sapmComponent->kcontrols == NULL) {
1185 ADM_LOG_ERR("malloc kcontrols fail!");
1186 return HDF_FAILURE;
1187 }
1188 }
1189
1190 switch (sapmComponent->sapmType) {
1191 case AUDIO_SAPM_ANALOG_SWITCH:
1192 case AUDIO_SAPM_MIXER:
1193 case AUDIO_SAPM_MIXER_NAMED_CTRL:
1194 ret = AudioSapmNewMixerControls(sapmComponent, audioCard);
1195 break;
1196 case AUDIO_SAPM_MUX:
1197 case AUDIO_SAPM_VIRT_MUX:
1198 case AUDIO_SAPM_VALUE_MUX:
1199 ret = AudioSapmNewMuxControls(sapmComponent, audioCard);
1200 break;
1201 default:
1202 ret = HDF_SUCCESS;
1203 break;
1204 }
1205 if (ret != HDF_SUCCESS) {
1206 OsalMemFree(sapmComponent->kcontrols);
1207 ADM_LOG_ERR("sapm new mixer or mux controls fail!");
1208 return HDF_FAILURE;
1209 }
1210
1211 ReadInitComponentPowerStatus(sapmComponent);
1212 sapmComponent->newCpt = 1;
1213 DListInsertTail(&sapmComponent->dirty, &audioCard->sapmDirty);
1214 }
1215
1216 AudioSapmPowerComponents(audioCard);
1217
1218 return HDF_SUCCESS;
1219 }
1220
MixerUpdatePowerStatus(const struct AudioKcontrol * kcontrol,uint32_t pathStatus)1221 static int32_t MixerUpdatePowerStatus(const struct AudioKcontrol *kcontrol, uint32_t pathStatus)
1222 {
1223 struct AudioCard *audioCard = NULL;
1224 struct AudioSapmpath *path = NULL;
1225
1226 if (kcontrol == NULL || kcontrol->pri == NULL) {
1227 ADM_LOG_ERR("Mixer input param kcontrol is NULL.");
1228 return HDF_ERR_INVALID_OBJECT;
1229 }
1230 audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
1231
1232 DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) {
1233 if (path->kcontrol != kcontrol) {
1234 continue;
1235 }
1236 if (path->sink == NULL || path->source == NULL) {
1237 ADM_LOG_ERR("get path sink or source fail!");
1238 return HDF_FAILURE;
1239 }
1240 if (path->sink->sapmType != AUDIO_SAPM_MIXER &&
1241 path->sink->sapmType != AUDIO_SAPM_MIXER_NAMED_CTRL &&
1242 path->sink->sapmType != AUDIO_SAPM_PGA &&
1243 path->sink->sapmType != AUDIO_SAPM_SPK &&
1244 path->sink->sapmType != AUDIO_SAPM_ANALOG_SWITCH) {
1245 ADM_LOG_DEBUG("no mixer device.");
1246 return HDF_DEV_ERR_NO_DEVICE;
1247 }
1248
1249 path->connect = pathStatus;
1250 DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
1251 DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
1252 break;
1253 }
1254
1255 AudioSapmPowerComponents(audioCard);
1256
1257 return HDF_SUCCESS;
1258 }
1259
MuxUpdatePowerStatus(const struct AudioKcontrol * kcontrol,int32_t i,struct AudioEnumKcontrol * enumKtl)1260 static int32_t MuxUpdatePowerStatus(const struct AudioKcontrol *kcontrol, int32_t i, struct AudioEnumKcontrol *enumKtl)
1261 {
1262 struct AudioCard *audioCard = NULL;
1263 struct AudioSapmpath *path = NULL;
1264
1265 if (kcontrol == NULL || kcontrol->pri == NULL) {
1266 ADM_LOG_ERR("Mux input param kcontrol is NULL.");
1267 return HDF_ERR_INVALID_OBJECT;
1268 }
1269 audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
1270
1271 DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) {
1272 if (path->kcontrol != kcontrol) {
1273 continue;
1274 }
1275 if (path->name == NULL || enumKtl->texts[i] == NULL) {
1276 continue;
1277 }
1278
1279 if (path->sink->sapmType != AUDIO_SAPM_MUX &&
1280 path->sink->sapmType != AUDIO_SAPM_VIRT_MUX &&
1281 path->sink->sapmType != AUDIO_SAPM_VALUE_MUX) {
1282 ADM_LOG_ERR("no mux device.");
1283 return HDF_DEV_ERR_NO_DEVICE;
1284 }
1285
1286 if (strcmp(path->name, enumKtl->texts[i]) == 0) {
1287 path->connect = 1;
1288 } else {
1289 if (path->connect == 1) {
1290 path->connect = 0;
1291 }
1292 }
1293
1294 DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
1295 DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
1296 break;
1297 }
1298
1299 AudioSapmPowerComponents(audioCard);
1300 return HDF_SUCCESS;
1301 }
1302
AudioCodecSapmGetCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)1303 int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
1304 {
1305 if (AudioCodecGetCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
1306 ADM_LOG_ERR("Audio codec sapm get control switch is fail!");
1307 return HDF_FAILURE;
1308 }
1309
1310 return HDF_SUCCESS;
1311 }
1312
1313 /* 1.first user specify old component -- power down; 2.second user specify new component -- power up */
AudioSapmSetCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue,uint32_t * value,uint32_t * pathStatus)1314 static int32_t AudioSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue,
1315 uint32_t *value, uint32_t *pathStatus)
1316 {
1317 struct AudioMixerControl *mixerCtrl = NULL;
1318 int32_t iFlag = (kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)
1319 || (value == NULL) || (pathStatus == NULL);
1320 if (iFlag) {
1321 ADM_LOG_ERR("input params invalid.");
1322 return HDF_ERR_INVALID_OBJECT;
1323 }
1324
1325 mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
1326 *value = elemValue->value[0];
1327 if (*value < mixerCtrl->min || *value > mixerCtrl->max) {
1328 ADM_LOG_ERR("value is invalid.");
1329 return HDF_ERR_INVALID_OBJECT;
1330 }
1331
1332 if (*value) {
1333 *pathStatus = CONNECT_SINK_AND_SOURCE;
1334 } else {
1335 *pathStatus = UNCONNECT_SINK_AND_SOURCE;
1336 }
1337
1338 if (mixerCtrl->invert) {
1339 *value = mixerCtrl->max - *value;
1340 }
1341
1342 return HDF_SUCCESS;
1343 }
1344
AudioCodecSapmSetCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)1345 int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
1346 {
1347 uint32_t value;
1348 uint32_t pathStatus = 0;
1349 struct CodecDevice *codec = NULL;
1350 struct AudioMixerControl *mixerCtrl = NULL;
1351 if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (kcontrol->pri == NULL)) {
1352 ADM_LOG_ERR("input params: kcontrol is NULL.");
1353 return HDF_ERR_INVALID_OBJECT;
1354 }
1355 if (elemValue == NULL) {
1356 ADM_LOG_ERR("input params: elemValue is NULL.");
1357 return HDF_ERR_INVALID_OBJECT;
1358 }
1359
1360 mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
1361 if (AudioSapmSetCtrlOps(kcontrol, elemValue, &value, &pathStatus) != HDF_SUCCESS) {
1362 ADM_LOG_ERR("Audio sapm put control switch fail!");
1363 }
1364 codec = AudioKcontrolGetCodec(kcontrol);
1365
1366 if (MixerUpdatePowerStatus(kcontrol, pathStatus) != HDF_SUCCESS) {
1367 ADM_LOG_ERR("update power status is failure!");
1368 return HDF_FAILURE;
1369 }
1370
1371 mixerCtrl->value = elemValue->value[0];
1372 if (AudioCodecRegUpdate(codec, mixerCtrl) != HDF_SUCCESS) {
1373 ADM_LOG_ERR("update reg bits fail!");
1374 return HDF_FAILURE;
1375 }
1376 return HDF_SUCCESS;
1377 }
1378
AudioCodecCheckRegIsChange(struct AudioEnumKcontrol * enumCtrl,const struct AudioCtrlElemValue * elemValue,uint32_t curValue,bool * change)1379 static int32_t AudioCodecCheckRegIsChange(struct AudioEnumKcontrol *enumCtrl,
1380 const struct AudioCtrlElemValue *elemValue, uint32_t curValue, bool *change)
1381 {
1382 uint32_t value;
1383 uint32_t mask;
1384 uint32_t oldValue;
1385
1386 if (enumCtrl == NULL || elemValue == NULL || change == NULL) {
1387 ADM_LOG_ERR("input para is null!");
1388 return HDF_FAILURE;
1389 }
1390
1391 *change = false;
1392 if (elemValue->value[0] > enumCtrl->max) {
1393 ADM_LOG_ERR("elemValue value[0] out of range!");
1394 return HDF_FAILURE;
1395 }
1396
1397 if (enumCtrl->values != NULL) {
1398 value = enumCtrl->values[elemValue->value[0]] << enumCtrl->shiftLeft;
1399 mask = enumCtrl->mask << enumCtrl->shiftLeft;
1400 if (enumCtrl->shiftLeft != enumCtrl->shiftRight) {
1401 if (elemValue->value[1] > enumCtrl->max) {
1402 ADM_LOG_ERR("elemValue value[1] out of range!");
1403 return HDF_FAILURE;
1404 }
1405 value |= enumCtrl->values[elemValue->value[1]] << enumCtrl->shiftRight;
1406 mask |= enumCtrl->mask << enumCtrl->shiftRight;
1407 }
1408 } else {
1409 value = elemValue->value[0] << enumCtrl->shiftLeft;
1410 mask = enumCtrl->mask << enumCtrl->shiftLeft;
1411 if (enumCtrl->shiftLeft != enumCtrl->shiftRight) {
1412 if (elemValue->value[1] > enumCtrl->max) {
1413 ADM_LOG_ERR("elemValue value[1] out of range!");
1414 return HDF_FAILURE;
1415 }
1416 value |= elemValue->value[1] << enumCtrl->shiftRight;
1417 mask |= enumCtrl->mask << enumCtrl->shiftRight;
1418 }
1419 }
1420
1421 oldValue = curValue & mask;
1422 if (oldValue != value) {
1423 *change = true;
1424 }
1425 return HDF_SUCCESS;
1426 }
1427
AudioCodecSapmSetEnumCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)1428 int32_t AudioCodecSapmSetEnumCtrlOps(const struct AudioKcontrol *kcontrol,
1429 const struct AudioCtrlElemValue *elemValue)
1430 {
1431 uint32_t curValue;
1432 bool change;
1433 int32_t ret;
1434 struct CodecDevice *codec = NULL;
1435 struct AudioEnumKcontrol *enumCtrl = NULL;
1436
1437 if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)) {
1438 ADM_LOG_ERR("input params: kcontrol is NULL or elemValue is NULL");
1439 return HDF_ERR_INVALID_OBJECT;
1440 }
1441 codec = AudioKcontrolGetCodec(kcontrol);
1442
1443 enumCtrl = (struct AudioEnumKcontrol *)((volatile uintptr_t)kcontrol->privateValue);
1444 if (enumCtrl == NULL) {
1445 ADM_LOG_ERR("privateValue is null");
1446 return HDF_FAILURE;
1447 }
1448
1449 if (AudioCodecReadReg(codec, enumCtrl->reg, &curValue) != HDF_SUCCESS) {
1450 ADM_LOG_ERR("Device read register is failure!");
1451 return HDF_FAILURE;
1452 }
1453
1454 ret = AudioCodecCheckRegIsChange(enumCtrl, elemValue, curValue, &change);
1455 if (ret != HDF_SUCCESS) {
1456 ADM_LOG_ERR("AudioCodecCheckRegIsChange is failure!");
1457 return HDF_FAILURE;
1458 }
1459
1460 if (change) {
1461 if (MuxUpdatePowerStatus(kcontrol, elemValue->value[0], enumCtrl) != HDF_SUCCESS) {
1462 ADM_LOG_ERR("update power status is failure!");
1463 return HDF_FAILURE;
1464 }
1465
1466 ret = AudioCodecMuxRegUpdate(codec, enumCtrl, elemValue->value);
1467 if (ret != HDF_SUCCESS) {
1468 ADM_LOG_ERR("AudioCodecMuxRegUpdate is failure!");
1469 return HDF_FAILURE;
1470 }
1471 }
1472
1473 return HDF_SUCCESS;
1474 }
1475
AudioCodecSapmGetEnumCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)1476 int32_t AudioCodecSapmGetEnumCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
1477 {
1478 if (AudioCodecGetEnumCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
1479 ADM_LOG_ERR("Audio codec sapm get control switch is fail!");
1480 return HDF_FAILURE;
1481 }
1482
1483 return HDF_SUCCESS;
1484 }
1485
AudioSapmRefreshTime(struct AudioCard * audioCard,bool bRefresh)1486 static int32_t AudioSapmRefreshTime(struct AudioCard *audioCard, bool bRefresh)
1487 {
1488 if (audioCard == NULL) {
1489 ADM_LOG_ERR("input params is NULL.");
1490 return HDF_ERR_INVALID_OBJECT;
1491 }
1492
1493 if (bRefresh) {
1494 audioCard->time = 0;
1495 }
1496 return HDF_SUCCESS;
1497 }
1498
AudioSapmCheckTime(struct AudioCard * audioCard,bool * timeoutStatus)1499 static int32_t AudioSapmCheckTime(struct AudioCard *audioCard, bool *timeoutStatus)
1500 {
1501 int32_t ret;
1502
1503 if (audioCard == NULL || timeoutStatus == NULL) {
1504 ADM_LOG_ERR("input params is NULL.");
1505 return HDF_ERR_INVALID_OBJECT;
1506 }
1507
1508 ret = AudioSapmRefreshTime(audioCard, false);
1509 if (ret != HDF_SUCCESS) {
1510 ADM_LOG_ERR("AudioSapmRefreshTime failed.");
1511 return HDF_FAILURE;
1512 }
1513 *timeoutStatus = audioCard->time > SAPM_SLEEP_TIMES ? true : false;
1514
1515 return HDF_SUCCESS;
1516 }
1517
AudioSampPowerUp(const struct AudioCard * card)1518 int32_t AudioSampPowerUp(const struct AudioCard *card)
1519 {
1520 struct DListHead upList;
1521 struct AudioSapmComponent *sapmComponent = NULL;
1522
1523 if (card == NULL) {
1524 ADM_LOG_ERR("input params is null.");
1525 return HDF_ERR_INVALID_OBJECT;
1526 }
1527
1528 DListHeadInit(&upList);
1529 DLIST_FOR_EACH_ENTRY(sapmComponent, &card->components, struct AudioSapmComponent, list) {
1530 if (sapmComponent == NULL) {
1531 break;
1532 }
1533 if (sapmComponent->power == SAPM_POWER_DOWN) {
1534 AudioSapmPowerSeqInsert(sapmComponent, &upList, SAPM_POWER_UP);
1535 }
1536 }
1537
1538 AudioSapmPowerUpSeqRun(&upList);
1539 return HDF_SUCCESS;
1540 }
1541
AudioSampSetPowerMonitor(struct AudioCard * card,bool powerMonitorState)1542 int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState)
1543 {
1544 if (card == NULL) {
1545 ADM_LOG_ERR("input params is null.");
1546 return HDF_ERR_INVALID_OBJECT;
1547 }
1548
1549 card->sapmMonitorState = powerMonitorState;
1550 if (powerMonitorState == false) {
1551 card->sapmSleepState = false;
1552 card->sapmStandbyState = false;
1553 card->sapmStandbyStartTimeFlag = false;
1554 card->sapmSleepStartTimeFlag = false;
1555 }
1556 return HDF_SUCCESS;
1557 }
1558
AudioSapmEnterSleep(struct AudioCard * audioCard)1559 static void AudioSapmEnterSleep(struct AudioCard *audioCard)
1560 {
1561 struct DListHead downList;
1562 struct AudioSapmComponent *sapmComponent = NULL;
1563 ADM_LOG_INFO("entry!");
1564
1565 DListHeadInit(&downList);
1566 if (audioCard == NULL) {
1567 ADM_LOG_ERR("audioCard is null.");
1568 return;
1569 }
1570 DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1571 if (sapmComponent == NULL) {
1572 break;
1573 }
1574 if (sapmComponent->power == SAPM_POWER_UP) {
1575 AudioSapmPowerSeqInsert(sapmComponent, &downList, SAPM_POWER_DOWN);
1576 }
1577 }
1578 AudioSapmPowerDownSeqRun(&downList);
1579 audioCard->sapmStandbyState = false;
1580 audioCard->sapmSleepState = true;
1581 }
1582
AudioSapmEnterStandby(struct AudioCard * audioCard)1583 static bool AudioSapmEnterStandby(struct AudioCard *audioCard)
1584 {
1585 bool timeoutStatus;
1586 struct AudioSapmComponent *sapmComponent = NULL;
1587
1588 if (audioCard == NULL) {
1589 ADM_LOG_ERR("audioCard is null.");
1590 return false;
1591 }
1592
1593 if (audioCard->sapmStandbyStartTimeFlag == false) {
1594 if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
1595 ADM_LOG_ERR("AudioSapmRefreshTime failed.");
1596 return false;
1597 }
1598 audioCard->sapmStandbyStartTimeFlag = true;
1599 }
1600
1601 if (audioCard->standbyMode != AUDIO_SAPM_TURN_STANDBY_NOW) {
1602 if (AudioSapmCheckTime(audioCard, &timeoutStatus) != HDF_SUCCESS) {
1603 ADM_LOG_ERR("AudioSapmCheckTime failed.");
1604 return false;
1605 }
1606
1607 if (!timeoutStatus) {
1608 return false;
1609 }
1610 }
1611
1612 if (audioCard->sapmStandbyState == false) {
1613 DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1614 if (sapmComponent->PowerClockOp != NULL) {
1615 sapmComponent->PowerClockOp(sapmComponent);
1616 }
1617 }
1618 audioCard->sapmStandbyState = true;
1619 }
1620
1621 return true;
1622 }
1623
AudioSapmTimerCallback(struct AudioCard * audioCard)1624 static void AudioSapmTimerCallback(struct AudioCard *audioCard)
1625 {
1626 bool timeoutStatus;
1627 bool standbyEntry;
1628
1629 #ifndef __LITEOS__
1630 ADM_LOG_DEBUG("entry!");
1631 #endif
1632
1633 if (audioCard == NULL) {
1634 return;
1635 }
1636 if (audioCard->sapmSleepState == true) {
1637 return;
1638 }
1639
1640 if (audioCard->sapmMonitorState == false) {
1641 return;
1642 }
1643
1644 standbyEntry = AudioSapmEnterStandby(audioCard);
1645 if (!standbyEntry) {
1646 return;
1647 }
1648
1649 if (audioCard->sapmSleepStartTimeFlag == false) {
1650 if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
1651 ADM_LOG_ERR("AudioSapmRefreshTime failed.");
1652 return;
1653 }
1654 audioCard->sapmSleepStartTimeFlag = true;
1655 }
1656
1657 if (AudioSapmCheckTime(audioCard, &timeoutStatus) != HDF_SUCCESS) {
1658 ADM_LOG_ERR("AudioSapmCheckTime failed.");
1659 return;
1660 }
1661
1662 if (!timeoutStatus) {
1663 return;
1664 }
1665 AudioSapmEnterSleep(audioCard);
1666 }
1667