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