• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: sapmComponent=%p, enumKtl=%p.",
417             sapmComponent, enumKtl);
418         return;
419     }
420     if (path == NULL || path->name == NULL) {
421         ADM_LOG_ERR("input params check error: path is NULL.");
422         return;
423     }
424     if (enumKtl == NULL) {
425         ADM_LOG_ERR("input params check error: enumKtl is NULL.");
426         return;
427     }
428 
429     shift = enumKtl->shiftLeft;
430     ret = AudioCodecReadReg(sapmComponent->codec, enumKtl->reg, &val);
431     if (ret != HDF_SUCCESS) {
432         ADM_LOG_ERR("codec read reg fail!");
433         return;
434     }
435 
436     curValue = (val >> shift) & enumKtl->mask;
437     path->connect = UNCONNECT_SINK_AND_SOURCE;
438 
439     if (enumKtl->texts != NULL) {
440         for (i = 0; i < enumKtl->max; i++) {
441             if (enumKtl->texts[i] == NULL) {
442                 ADM_LOG_ERR("enumKtl->texts[%d] is NULL", i);
443                 continue;
444             }
445 
446             if ((strcmp(path->name, enumKtl->texts[i]) == 0) && curValue == i) {
447                 path->connect = CONNECT_SINK_AND_SOURCE;
448             }
449         }
450     } else {
451         if (curValue) {
452             path->connect = CONNECT_SINK_AND_SOURCE;
453         }
454     }
455 
456     return;
457 }
458 
MuxValueSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,const struct AudioEnumKcontrol * enumKtl,int32_t i)459 static void MuxValueSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
460     const struct AudioEnumKcontrol *enumKtl, int32_t i)
461 {
462     int32_t ret;
463     uint32_t val = 0;
464     uint32_t item;
465     uint32_t shift;
466     if (sapmComponent == NULL || sapmComponent->codec == NULL) {
467         ADM_LOG_ERR("input muxValueSet params check error: cpt=%p.", sapmComponent);
468         return;
469     }
470     if (path == NULL || path->name == NULL) {
471         ADM_LOG_ERR("input MuxValueSet params check error: path is NULL.");
472         return;
473     }
474     if (enumKtl == NULL) {
475         ADM_LOG_ERR("input MuxValueSet params check error: enumKtl is NULL.");
476         return;
477     }
478     shift = enumKtl->shiftLeft;
479     ret = AudioCodecReadReg(sapmComponent->codec, enumKtl->reg, &val);
480     if (ret != HDF_SUCCESS) {
481         ADM_LOG_ERR("muxValueSet read reg fail!");
482         return;
483     }
484 
485     val = (val >> shift) & enumKtl->mask;
486     path->connect = UNCONNECT_SINK_AND_SOURCE;
487 
488     if (enumKtl->values != NULL && enumKtl->texts != NULL) {
489         for (item = 0; item < enumKtl->max; item++) {
490             if (val == enumKtl->values[item]) {
491                 break;
492             }
493         }
494 
495         for (i = 0; i < enumKtl->max; i++) {
496             if (enumKtl->texts[i] == NULL) {
497                 continue;
498             }
499             if ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) {
500                 path->connect = CONNECT_SINK_AND_SOURCE;
501             }
502         }
503     } else {
504         if (val) {
505             path->connect = CONNECT_SINK_AND_SOURCE;
506         }
507     }
508 
509     return;
510 }
511 
MixerSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,const struct AudioMixerControl * mixerCtrl)512 static void MixerSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
513     const struct AudioMixerControl *mixerCtrl)
514 {
515     int32_t ret;
516     uint32_t reg;
517     uint32_t mask;
518     uint32_t shift;
519     uint32_t invert;
520     uint32_t curValue = 0;
521 
522     if (sapmComponent == NULL) {
523         ADM_LOG_ERR("input params check error: sapmComponent is NULL.");
524         return;
525     }
526     if (path == NULL) {
527         ADM_LOG_ERR("input params check error: path is NULL.");
528         return;
529     }
530     if (mixerCtrl == NULL) {
531         ADM_LOG_ERR("input params check error: mixerCtrl is NULL.");
532         return;
533     }
534 
535     reg = mixerCtrl->reg;
536     shift = mixerCtrl->shift;
537     mask = mixerCtrl->mask;
538     invert = mixerCtrl->invert;
539 
540     if (sapmComponent->codec != NULL) {
541         ret = AudioCodecReadReg(sapmComponent->codec, reg, &curValue);
542         if (ret != HDF_SUCCESS) {
543             ADM_LOG_ERR("read reg fail!");
544             return;
545         }
546     } else {
547         ADM_LOG_ERR("codec is null!");
548         return;
549     }
550 
551     curValue = (curValue >> shift) & mask;
552     if ((invert && !curValue) || (!invert && curValue)) {
553         path->connect = CONNECT_SINK_AND_SOURCE;
554     } else {
555         path->connect = UNCONNECT_SINK_AND_SOURCE;
556     }
557 
558     return;
559 }
560 
AudioSapmSetPathStatus(const struct AudioSapmComponent * sapmComponent,struct AudioSapmpath * path,int32_t i)561 static int32_t AudioSapmSetPathStatus(const struct AudioSapmComponent *sapmComponent,
562     struct AudioSapmpath *path, int32_t i)
563 {
564     if ((sapmComponent == NULL) || (path == NULL)) {
565         ADM_LOG_ERR("input params check error: sapmComponent=%p, path=%p.", sapmComponent, path);
566         return HDF_FAILURE;
567     }
568     switch (sapmComponent->sapmType) {
569         case AUDIO_SAPM_MIXER:
570         case AUDIO_SAPM_ANALOG_SWITCH:
571         case AUDIO_SAPM_MIXER_NAMED_CTRL:
572             MixerSetPathStatus(sapmComponent, path,
573                 (struct AudioMixerControl *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue));
574             break;
575         case AUDIO_SAPM_MUX:
576             MuxSetPathStatus(sapmComponent, path,
577                 (struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
578             break;
579         case AUDIO_SAPM_VALUE_MUX:
580             MuxValueSetPathStatus(sapmComponent, path,
581                 (struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
582             break;
583         default:
584             path->connect = CONNECT_SINK_AND_SOURCE;
585             break;
586     }
587 
588     return HDF_SUCCESS;
589 }
590 
AudioSapmConnectMux(struct AudioCard * audioCard,struct AudioSapmComponent * source,struct AudioSapmComponent * sink,struct AudioSapmpath * path,const char * controlName)591 static int32_t AudioSapmConnectMux(struct AudioCard *audioCard,
592     struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
593     struct AudioSapmpath *path, const char *controlName)
594 {
595     int32_t i;
596     struct AudioEnumKcontrol *enumKtl = NULL;
597 
598     if ((audioCard == NULL) || (source == NULL) || (sink == NULL) ||
599         (path == NULL) || (controlName == NULL)) {
600         ADM_LOG_ERR("input params check error: audioCard=%p, source=%p, sink=%p, path=%p, controlName=%p.",
601             audioCard, source, sink, path, controlName);
602         return HDF_FAILURE;
603     }
604 
605     if (sink->kcontrolNews == NULL) {
606         ADM_LOG_ERR("input params sink kcontrolNews is null.");
607         return HDF_FAILURE;
608     }
609     enumKtl = (struct AudioEnumKcontrol *)&sink->kcontrolNews[0].privateValue;
610     if (enumKtl == NULL || enumKtl->texts == NULL) {
611         ADM_LOG_ERR("kcontrolNews privateValue is null.");
612         return HDF_FAILURE;
613     }
614 
615     for (i = 0; i < enumKtl->max; i++) {
616         if (strcmp(controlName, enumKtl->texts[i]) == 0) {
617             DListInsertHead(&path->list, &audioCard->paths);
618             DListInsertHead(&path->listSink, &sink->sources);
619             DListInsertHead(&path->listSource, &source->sinks);
620             path->name = (char*)enumKtl->texts[i];
621             AudioSapmSetPathStatus(sink, path, i);
622 
623             return HDF_SUCCESS;
624         }
625     }
626 
627     return HDF_FAILURE;
628 }
629 
AudioSapmConnectMixer(struct AudioCard * audioCard,struct AudioSapmComponent * source,struct AudioSapmComponent * sink,struct AudioSapmpath * path,const char * controlName)630 static int32_t AudioSapmConnectMixer(struct AudioCard *audioCard,
631     struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
632     struct AudioSapmpath *path, const char *controlName)
633 {
634     int32_t i;
635 
636     if ((audioCard == NULL) || (source == NULL) || (sink == NULL) ||
637         (path == NULL) || (controlName == NULL)) {
638         ADM_LOG_ERR("input params check error: audioCard=%p, source=%p, sink=%p, path=%p, controlName=%p.",
639             audioCard, source, sink, path, controlName);
640         return HDF_FAILURE;
641     }
642 
643     for (i = 0; i < sink->kcontrolsNum; i++) {
644         if (sink->kcontrolNews[i].name == NULL) {
645             continue;
646         }
647 
648         if (strcmp(controlName, sink->kcontrolNews[i].name) == 0) {
649             path->name = (char *)OsalMemCalloc(strlen(sink->kcontrolNews[i].name) + 1);
650             if (path->name == NULL) {
651                 ADM_LOG_ERR("malloc path->name fail!");
652                 return HDF_FAILURE;
653             }
654             if (memcpy_s(path->name, strlen(sink->kcontrolNews[i].name) + 1, sink->kcontrolNews[i].name,
655                 strlen(sink->kcontrolNews[i].name) + 1) != EOK) {
656                 OsalMemFree(path->name);
657                 ADM_LOG_ERR("memcpy cpt->componentName fail!");
658                 return HDF_FAILURE;
659             }
660             DListInsertHead(&path->list, &audioCard->paths);
661             DListInsertHead(&path->listSink, &sink->sources);
662             DListInsertHead(&path->listSource, &source->sinks);
663 
664             AudioSapmSetPathStatus(sink, path, i);
665 
666             return HDF_SUCCESS;
667         }
668     }
669 
670     return HDF_FAILURE;
671 }
672 
AudioSampStaticOrDynamicPath(struct AudioCard * audioCard,struct AudioSapmComponent * source,struct AudioSapmComponent * sink,struct AudioSapmpath * path,const struct AudioSapmRoute * route)673 static int32_t AudioSampStaticOrDynamicPath(struct AudioCard *audioCard,
674     struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
675     struct AudioSapmpath *path, const struct AudioSapmRoute *route)
676 {
677     int32_t ret;
678 
679     if (route->control == NULL) {
680         DListInsertHead(&path->list, &audioCard->paths);
681         DListInsertHead(&path->listSink, &sink->sources);
682         DListInsertHead(&path->listSource, &source->sinks);
683         path->connect = CONNECT_SINK_AND_SOURCE;
684         return HDF_SUCCESS;
685     }
686 
687     switch (sink->sapmType) {
688         case AUDIO_SAPM_MUX:
689         case AUDIO_SAPM_VIRT_MUX:
690         case AUDIO_SAPM_VALUE_MUX:
691             ret = AudioSapmConnectMux(audioCard, source, sink, path, route->control);
692             if (ret != HDF_SUCCESS) {
693                 ADM_LOG_ERR("connect mux fail!");
694                 return HDF_FAILURE;
695             }
696             break;
697         case AUDIO_SAPM_ANALOG_SWITCH:
698         case AUDIO_SAPM_MIXER:
699         case AUDIO_SAPM_MIXER_NAMED_CTRL:
700         case AUDIO_SAPM_PGA:
701         case AUDIO_SAPM_SPK:
702             ret = AudioSapmConnectMixer(audioCard, source, sink, path, route->control);
703             if (ret != HDF_SUCCESS) {
704                 ADM_LOG_ERR("connect mixer fail!");
705                 return HDF_FAILURE;
706             }
707             break;
708         case AUDIO_SAPM_HP:
709         case AUDIO_SAPM_MIC:
710         case AUDIO_SAPM_LINE:
711             DListInsertHead(&path->list, &audioCard->paths);
712             DListInsertHead(&path->listSink, &sink->sources);
713             DListInsertHead(&path->listSource, &source->sinks);
714             path->connect = CONNECT_SINK_AND_SOURCE;
715             break;
716         default:
717             DListInsertHead(&path->list, &audioCard->paths);
718             DListInsertHead(&path->listSink, &sink->sources);
719             DListInsertHead(&path->listSource, &source->sinks);
720             path->connect = CONNECT_SINK_AND_SOURCE;
721             break;
722     }
723 
724     return HDF_SUCCESS;
725 }
726 
AudioSampExtComponentsCheck(struct AudioSapmComponent * cptSource,struct AudioSapmComponent * cptSink)727 static void AudioSampExtComponentsCheck(struct AudioSapmComponent *cptSource, struct AudioSapmComponent *cptSink)
728 {
729     if ((cptSource == NULL) || (cptSink == NULL)) {
730         ADM_LOG_ERR("input params check error: cptSource=%p, cptSink=%p.", cptSource, cptSink);
731         return;
732     }
733 
734     /* check for external components */
735     if (cptSink->sapmType == AUDIO_SAPM_INPUT) {
736         if (cptSource->sapmType == AUDIO_SAPM_MICBIAS || cptSource->sapmType == AUDIO_SAPM_MIC ||
737             cptSource->sapmType == AUDIO_SAPM_LINE || cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
738             cptSink->external = EXIST_EXTERNAL_WIDGET;
739         }
740     }
741     if (cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
742         if (cptSink->sapmType == AUDIO_SAPM_SPK || cptSink->sapmType == AUDIO_SAPM_HP ||
743             cptSink->sapmType == AUDIO_SAPM_LINE || cptSink->sapmType == AUDIO_SAPM_INPUT) {
744             cptSource->external = EXIST_EXTERNAL_WIDGET;
745         }
746     }
747 
748     return;
749 }
750 
AudioSapmAddRoute(struct AudioCard * audioCard,const struct AudioSapmRoute * route)751 static int32_t AudioSapmAddRoute(struct AudioCard *audioCard, const struct AudioSapmRoute *route)
752 {
753     struct AudioSapmpath *path = NULL;
754     struct AudioSapmComponent *cptSource = NULL;
755     struct AudioSapmComponent *cptSink = NULL;
756     struct AudioSapmComponent *sapmComponent = NULL;
757     int32_t ret;
758 
759     if (route == NULL || route->source == NULL || route->sink == NULL) {
760         ADM_LOG_ERR("input params check error: route is NULL.");
761         return HDF_FAILURE;
762     }
763 
764     DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
765         if (sapmComponent->componentName == NULL) {
766             continue;
767         }
768         if ((cptSource == NULL) && (strcmp(sapmComponent->componentName, route->source) == 0)) {
769             cptSource = sapmComponent;
770             continue;
771         }
772         if ((cptSink == NULL) && (strcmp(sapmComponent->componentName, route->sink) == 0)) {
773             cptSink = sapmComponent;
774         }
775         if ((cptSource != NULL) && (cptSink != NULL)) {
776             break;
777         }
778     }
779     if ((cptSource == NULL) || (cptSink == NULL)) {
780         ADM_LOG_ERR("find component fail!");
781         return HDF_FAILURE;
782     }
783 
784     path = (struct AudioSapmpath *)OsalMemCalloc(sizeof(struct AudioSapmpath));
785     if (path == NULL) {
786         ADM_LOG_ERR("malloc path fail!");
787         return HDF_FAILURE;
788     }
789     path->source = cptSource;
790     path->sink = cptSink;
791     DListHeadInit(&path->list);
792     DListHeadInit(&path->listSink);
793     DListHeadInit(&path->listSource);
794 
795     /* check for external components */
796     AudioSampExtComponentsCheck(cptSource, cptSink);
797 
798     ret = AudioSampStaticOrDynamicPath(audioCard, cptSource, cptSink, path, route);
799     if (ret != HDF_SUCCESS) {
800         OsalMemFree(path);
801         ADM_LOG_ERR("static or dynamic path fail!");
802         return HDF_FAILURE;
803     }
804     return HDF_SUCCESS;
805 }
806 
AudioSapmAddRoutes(struct AudioCard * audioCard,const struct AudioSapmRoute * route,int32_t routeMaxNum)807 int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, const struct AudioSapmRoute *route, int32_t routeMaxNum)
808 {
809     int32_t i;
810     int32_t ret;
811 
812     if (audioCard == NULL) {
813         ADM_LOG_ERR("input params check error: audioCard is NULL.");
814         return HDF_FAILURE;
815     }
816     if (route == NULL) {
817         ADM_LOG_ERR("input params check error: route is NULL.");
818         return HDF_FAILURE;
819     }
820 
821     for (i = 0; i < routeMaxNum; i++) {
822         ret = AudioSapmAddRoute(audioCard, route);
823         if (ret != HDF_SUCCESS) {
824             ADM_LOG_ERR("AudioSapmAddRoute failed!");
825             return HDF_FAILURE;
826         }
827         route++;
828     }
829     return HDF_SUCCESS;
830 }
831 
AudioSapmNewMixerControls(const struct AudioSapmComponent * sapmComponent,struct AudioCard * audioCard)832 static int32_t AudioSapmNewMixerControls(
833     const struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
834 {
835     struct AudioSapmpath *path = NULL;
836     int32_t i;
837 
838     if (sapmComponent == NULL || sapmComponent->kcontrols == NULL) {
839         ADM_LOG_ERR("input params check error: sapmComponent is NULL.");
840         return HDF_FAILURE;
841     }
842     if (audioCard == NULL) {
843         ADM_LOG_ERR("input params check error: audioCard is NULL.");
844         return HDF_FAILURE;
845     }
846 
847     for (i = 0; i < sapmComponent->kcontrolsNum; i++) {
848         DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
849             if (path->name == NULL || sapmComponent->kcontrolNews == NULL
850                 || sapmComponent->kcontrolNews[i].name == NULL) {
851                 continue;
852             }
853 
854             if (strcmp(path->name, sapmComponent->kcontrolNews[i].name) != 0) {
855                 continue;
856             }
857 
858             path->kcontrol = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[i]);
859             if (path->kcontrol == NULL) {
860                 ADM_LOG_ERR("add control fail!");
861                 return HDF_FAILURE;
862             }
863             sapmComponent->kcontrols[i] = path->kcontrol;
864             DListInsertHead(&sapmComponent->kcontrols[i]->list, &audioCard->controls);
865         }
866     }
867 
868     return HDF_SUCCESS;
869 }
870 
AudioSapmNewMuxControls(struct AudioSapmComponent * sapmComponent,struct AudioCard * audioCard)871 static int32_t AudioSapmNewMuxControls(struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
872 {
873     struct AudioKcontrol *kctrl = NULL;
874 
875     if (sapmComponent == NULL || sapmComponent->kcontrolNews == NULL || audioCard == NULL) {
876         ADM_LOG_ERR("input param is NULL.");
877         return HDF_FAILURE;
878     }
879 
880     if (sapmComponent->kcontrolsNum != 1) {
881         ADM_LOG_ERR("incorrect number of controls.");
882         return HDF_FAILURE;
883     }
884 
885     kctrl = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[0]);
886     if (kctrl == NULL) {
887         ADM_LOG_ERR("add control fail!");
888         return HDF_FAILURE;
889     }
890 
891     if (sapmComponent->kcontrols == NULL) {
892         OsalMemFree(kctrl);
893         kctrl = NULL;
894         ADM_LOG_ERR("sapmComponent->kcontrols is NULL!");
895         return HDF_FAILURE;
896     }
897     sapmComponent->kcontrols[0] = kctrl;
898     DListInsertHead(&sapmComponent->kcontrols[0]->list, &audioCard->controls);
899 
900     return HDF_SUCCESS;
901 }
902 
AudioSapmPowerSeqInsert(struct AudioSapmComponent * newSapmComponent,struct DListHead * list,int8_t isPowerUp)903 static void AudioSapmPowerSeqInsert(struct AudioSapmComponent *newSapmComponent,
904     struct DListHead *list, int8_t isPowerUp)
905 {
906     struct AudioSapmComponent *sapmComponent = NULL;
907     int32_t *seq = {0};
908 
909     if (newSapmComponent == NULL || list == NULL || newSapmComponent->componentName == NULL) {
910         ADM_LOG_ERR("input param newCpt is NULL.");
911         return;
912     }
913 
914     if (isPowerUp) {
915         seq = g_audioSapmPowerUpSeq;
916     } else {
917         seq = g_audioSapmPowerDownSeq;
918     }
919 
920     DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
921         if ((seq[newSapmComponent->sapmType] - seq[sapmComponent->sapmType]) < 0) {
922             DListInsertTail(&newSapmComponent->powerList, &sapmComponent->powerList);
923             return;
924         }
925     }
926     DListInsertTail(&newSapmComponent->powerList, list);
927 
928     ADM_LOG_DEBUG("[%s] success.", newSapmComponent->componentName);
929     return;
930 }
931 
AudioSapmSetPower(struct AudioCard * audioCard,struct AudioSapmComponent * sapmComponent,uint8_t power,struct DListHead * upList,struct DListHead * downList)932 static void AudioSapmSetPower(struct AudioCard *audioCard, struct AudioSapmComponent *sapmComponent,
933     uint8_t power, struct DListHead *upList, struct DListHead *downList)
934 {
935     struct AudioSapmpath *path = NULL;
936 
937     if (sapmComponent == NULL) {
938         ADM_LOG_ERR("input param sapmComponent is NULL.");
939         return;
940     }
941 
942     DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
943         if (path->source != NULL) {
944             if ((path->source->power != power) && path->connect) {
945                 if (DListIsEmpty(&path->source->dirty)) {
946                     DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
947                 }
948             }
949         }
950     }
951     DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
952         if (path->sink != NULL) {
953             if ((path->sink->power != power) && path->connect) {
954                 if (DListIsEmpty(&path->sink->dirty)) {
955                     DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
956                 }
957             }
958         }
959     }
960 
961     if (power) {
962         AudioSapmPowerSeqInsert(sapmComponent, upList, power);
963     } else {
964         AudioSapmPowerSeqInsert(sapmComponent, downList, power);
965     }
966 
967     return;
968 }
969 
AudioSapmPowerUpSeqRun(const struct DListHead * list)970 static void AudioSapmPowerUpSeqRun(const struct DListHead *list)
971 {
972     uint32_t val;
973     struct AudioMixerControl mixerControl;
974     struct AudioSapmComponent *sapmComponent = NULL;
975     ADM_LOG_DEBUG("entry!");
976     if (list == NULL) {
977         ADM_LOG_ERR("input param list is NULL.");
978         return;
979     }
980 
981     DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
982         if (sapmComponent->power == SAPM_POWER_DOWN) {
983             val = SAPM_POWER_UP;
984             if (sapmComponent->invert) {
985                 val = !val;
986             }
987             sapmComponent->power = SAPM_POWER_UP;
988             if (sapmComponent->reg != AUDIO_NO_SAPM_REG) {
989                 mixerControl.reg = sapmComponent->reg;
990                 mixerControl.mask = sapmComponent->mask;
991                 mixerControl.shift = sapmComponent->shift;
992                 AudioUpdateCodecRegBits(sapmComponent->codec, mixerControl.reg, mixerControl.mask,
993                     mixerControl.shift, val);
994                 ADM_LOG_INFO("Sapm Codec %s Power Up.", sapmComponent->componentName);
995             }
996         }
997     }
998 
999     return;
1000 }
1001 
AudioSapmPowerDownSeqRun(const struct DListHead * list)1002 static void AudioSapmPowerDownSeqRun(const struct DListHead *list)
1003 {
1004     uint32_t val;
1005     struct AudioMixerControl mixerControl;
1006     struct AudioSapmComponent *sapmComponent = NULL;
1007     ADM_LOG_DEBUG("entry!");
1008 
1009     if (list == NULL) {
1010         ADM_LOG_ERR("sapm input param list is NULL.");
1011         return;
1012     }
1013     DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
1014         if (sapmComponent->power == SAPM_POWER_UP) {
1015             val = SAPM_POWER_DOWN;
1016             if (sapmComponent->invert) {
1017                 val = !val;
1018             }
1019             sapmComponent->power = SAPM_POWER_DOWN;
1020 
1021             if (sapmComponent->reg != AUDIO_NO_SAPM_REG) {
1022                 mixerControl.mask = sapmComponent->mask;
1023                 mixerControl.reg = sapmComponent->reg;
1024                 mixerControl.shift = sapmComponent->shift;
1025 
1026                 AudioUpdateCodecRegBits(sapmComponent->codec, mixerControl.reg, mixerControl.mask,
1027                     mixerControl.shift, val);
1028                 ADM_LOG_INFO("Sapm Codec %s Power Down.", sapmComponent->componentName);
1029             }
1030         }
1031     }
1032 
1033     return;
1034 }
1035 
AudioSapmPowerComponents(struct AudioCard * audioCard)1036 static void AudioSapmPowerComponents(struct AudioCard *audioCard)
1037 {
1038     int32_t ret;
1039     struct AudioSapmComponent *sapmComponent = NULL;
1040     struct DListHead upList;
1041     struct DListHead downList;
1042     ADM_LOG_DEBUG("entry!");
1043 
1044     if (audioCard == NULL) {
1045         ADM_LOG_ERR("input param audioCard is NULL.");
1046         return;
1047     }
1048 
1049     DListHeadInit(&upList);
1050     DListHeadInit(&downList);
1051 
1052     DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->sapmDirty, struct AudioSapmComponent, dirty) {
1053         sapmComponent->newPower = sapmComponent->PowerCheck(sapmComponent);
1054         if (sapmComponent->newPower == sapmComponent->power) {
1055             continue;
1056         }
1057 
1058         if (audioCard->sapmStandbyState && sapmComponent->PowerClockOp != NULL) {
1059             ret = sapmComponent->PowerClockOp(sapmComponent);
1060             if (ret != HDF_SUCCESS) {
1061                 continue;
1062             }
1063         }
1064 
1065         AudioSapmSetPower(audioCard, sapmComponent, sapmComponent->newPower, &upList, &downList);
1066     }
1067 
1068     DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1069         DListRemove(&sapmComponent->dirty);
1070         DListHeadInit(&sapmComponent->dirty);
1071     }
1072 
1073     AudioSapmPowerDownSeqRun(&downList);
1074     AudioSapmPowerUpSeqRun(&upList);
1075 }
1076 
ReadInitComponentPowerStatus(struct AudioSapmComponent * sapmComponent)1077 static void ReadInitComponentPowerStatus(struct AudioSapmComponent *sapmComponent)
1078 {
1079     int32_t ret;
1080     uint32_t regVal = 0;
1081 
1082     if (sapmComponent == NULL || sapmComponent->codec == NULL) {
1083         ADM_LOG_ERR("input param sapmComponent is NULL.");
1084         return;
1085     }
1086 
1087     if (sapmComponent->reg != AUDIO_NO_SAPM_REG) {
1088         ret = AudioCodecReadReg(sapmComponent->codec, sapmComponent->reg, &regVal);
1089         if (ret != HDF_SUCCESS) {
1090             ADM_LOG_ERR("read reg fail!");
1091             return;
1092         }
1093         regVal &= 1 << sapmComponent->shift;
1094 
1095         if (sapmComponent->invert) {
1096             regVal = !regVal;
1097         }
1098 
1099         if (regVal) {
1100             sapmComponent->power = SAPM_POWER_UP;
1101         } else {
1102             sapmComponent->power = SAPM_POWER_DOWN;
1103         }
1104     }
1105 
1106     return;
1107 }
1108 
AudioSapmThread(void * data)1109 static int AudioSapmThread(void *data)
1110 {
1111     struct AudioCard *audioCard = (struct AudioCard *)data;
1112     audioCard->time = 0;
1113 
1114     while (true) {
1115         OsalSleep(SAPM_POLL_TIME);
1116         AudioSapmTimerCallback(audioCard);
1117         audioCard->time++;
1118     }
1119 
1120     return 0;
1121 }
1122 
AudioSapmSleep(struct AudioCard * audioCard)1123 int32_t AudioSapmSleep(struct AudioCard *audioCard)
1124 {
1125     int32_t ret;
1126     char *sapmThreadName = NULL;
1127     struct OsalThreadParam threadCfg;
1128     OSAL_DECLARE_THREAD(audioSapmThread);
1129 
1130     if (audioCard == NULL) {
1131         ADM_LOG_ERR("input param audioCard is NULL.");
1132         return HDF_ERR_INVALID_OBJECT;
1133     }
1134 
1135     (void)AudioSapmRefreshTime(audioCard, true);
1136     sapmThreadName = OsalMemCalloc(SAPM_THREAD_NAME);
1137     if (sapmThreadName == NULL) {
1138         return HDF_ERR_MALLOC_FAIL;
1139     }
1140     if (snprintf_s(sapmThreadName, SAPM_THREAD_NAME, SAPM_THREAD_NAME - 1, "AudioSapmThread%u", g_cardNum) < 0) {
1141         ADM_LOG_ERR("snprintf_s failed.");
1142         OsalMemFree(sapmThreadName);
1143         return HDF_FAILURE;
1144     }
1145 
1146     ret = OsalThreadCreate(&audioSapmThread, (OsalThreadEntry)AudioSapmThread, (void *)audioCard);
1147     if (ret != HDF_SUCCESS) {
1148         ADM_LOG_ERR("create sapm thread fail, ret=%d", ret);
1149         OsalMemFree(sapmThreadName);
1150         return HDF_FAILURE;
1151     }
1152 
1153     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
1154     threadCfg.name = sapmThreadName;
1155     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
1156     threadCfg.stackSize = SAPM_STACK_SIZE;
1157     ret = OsalThreadStart(&audioSapmThread, &threadCfg);
1158     if (ret != HDF_SUCCESS) {
1159         ADM_LOG_ERR("start sapm thread fail, ret=%d", ret);
1160         OsalThreadDestroy(&audioSapmThread);
1161         OsalMemFree(sapmThreadName);
1162         return HDF_FAILURE;
1163     }
1164 
1165     g_cardNum++;
1166     audioCard->sapmStandbyState = false;
1167     audioCard->sapmSleepState = false;
1168     OsalMemFree(sapmThreadName);
1169 
1170     return HDF_SUCCESS;
1171 }
1172 
AudioSapmNewControls(struct AudioCard * audioCard)1173 int32_t AudioSapmNewControls(struct AudioCard *audioCard)
1174 {
1175     struct AudioSapmComponent *sapmComponent = NULL;
1176     int32_t ret = HDF_SUCCESS;
1177 
1178     if (audioCard == NULL) {
1179         ADM_LOG_ERR("input param audioCard is NULL.");
1180         return HDF_ERR_INVALID_OBJECT;
1181     }
1182 
1183     DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1184         if (sapmComponent->newCpt) {
1185             continue;
1186         }
1187         if (sapmComponent->kcontrolsNum > 0) {
1188             sapmComponent->kcontrols = OsalMemCalloc(sizeof(struct AudioKcontrol*) * sapmComponent->kcontrolsNum);
1189             if (sapmComponent->kcontrols == NULL) {
1190                 ADM_LOG_ERR("malloc kcontrols fail!");
1191                 return HDF_FAILURE;
1192             }
1193         }
1194 
1195         switch (sapmComponent->sapmType) {
1196             case AUDIO_SAPM_ANALOG_SWITCH:
1197             case AUDIO_SAPM_MIXER:
1198             case AUDIO_SAPM_MIXER_NAMED_CTRL:
1199                 ret = AudioSapmNewMixerControls(sapmComponent, audioCard);
1200                 break;
1201             case AUDIO_SAPM_MUX:
1202             case AUDIO_SAPM_VIRT_MUX:
1203             case AUDIO_SAPM_VALUE_MUX:
1204                 ret = AudioSapmNewMuxControls(sapmComponent, audioCard);
1205                 break;
1206             default:
1207                 ret = HDF_SUCCESS;
1208                 break;
1209         }
1210         if (ret != HDF_SUCCESS) {
1211             OsalMemFree(sapmComponent->kcontrols);
1212             ADM_LOG_ERR("sapm new mixer or mux controls fail!");
1213             return HDF_FAILURE;
1214         }
1215 
1216         ReadInitComponentPowerStatus(sapmComponent);
1217         sapmComponent->newCpt = 1;
1218         DListInsertTail(&sapmComponent->dirty, &audioCard->sapmDirty);
1219     }
1220 
1221     AudioSapmPowerComponents(audioCard);
1222 
1223     return HDF_SUCCESS;
1224 }
1225 
MixerUpdatePowerStatus(const struct AudioKcontrol * kcontrol,uint32_t pathStatus)1226 static int32_t MixerUpdatePowerStatus(const struct AudioKcontrol *kcontrol, uint32_t pathStatus)
1227 {
1228     struct AudioCard *audioCard = NULL;
1229     struct AudioSapmpath *path = NULL;
1230 
1231     if (kcontrol == NULL || kcontrol->pri == NULL) {
1232         ADM_LOG_ERR("Mixer input param kcontrol is NULL.");
1233         return HDF_ERR_INVALID_OBJECT;
1234     }
1235     audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
1236 
1237     DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) {
1238         if (path->kcontrol != kcontrol) {
1239             continue;
1240         }
1241         if (path->sink == NULL || path->source == NULL) {
1242             ADM_LOG_ERR("get path sink or source fail!");
1243             return HDF_FAILURE;
1244         }
1245         if (path->sink->sapmType != AUDIO_SAPM_MIXER &&
1246             path->sink->sapmType != AUDIO_SAPM_MIXER_NAMED_CTRL &&
1247             path->sink->sapmType != AUDIO_SAPM_PGA &&
1248             path->sink->sapmType != AUDIO_SAPM_SPK &&
1249             path->sink->sapmType != AUDIO_SAPM_ANALOG_SWITCH) {
1250             ADM_LOG_DEBUG("no mixer device.");
1251             return HDF_DEV_ERR_NO_DEVICE;
1252         }
1253 
1254         path->connect = pathStatus;
1255         DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
1256         DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
1257         break;
1258     }
1259 
1260     AudioSapmPowerComponents(audioCard);
1261 
1262     return HDF_SUCCESS;
1263 }
1264 
MuxUpdatePowerStatus(const struct AudioKcontrol * kcontrol,int32_t i,struct AudioEnumKcontrol * enumKtl)1265 static int32_t MuxUpdatePowerStatus(const struct AudioKcontrol *kcontrol, int32_t i, struct AudioEnumKcontrol *enumKtl)
1266 {
1267     struct AudioCard *audioCard = NULL;
1268     struct AudioSapmpath *path = NULL;
1269 
1270     if (kcontrol == NULL || kcontrol->pri == NULL) {
1271         ADM_LOG_ERR("Mux input param kcontrol is NULL.");
1272         return HDF_ERR_INVALID_OBJECT;
1273     }
1274     audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
1275 
1276     DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) {
1277         if (path->kcontrol != kcontrol) {
1278             continue;
1279         }
1280         if (path->name == NULL || enumKtl->texts[i] == NULL) {
1281             continue;
1282         }
1283 
1284         if (path->sink->sapmType != AUDIO_SAPM_MUX &&
1285             path->sink->sapmType != AUDIO_SAPM_VIRT_MUX &&
1286             path->sink->sapmType != AUDIO_SAPM_VALUE_MUX) {
1287             ADM_LOG_ERR("no mux device.");
1288             return HDF_DEV_ERR_NO_DEVICE;
1289         }
1290 
1291         if (strcmp(path->name, enumKtl->texts[i]) == 0) {
1292             path->connect = 1;
1293         } else {
1294             if (path->connect == 1) {
1295                 path->connect = 0;
1296             }
1297         }
1298 
1299         DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
1300         DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
1301         break;
1302     }
1303 
1304     AudioSapmPowerComponents(audioCard);
1305     return HDF_SUCCESS;
1306 }
1307 
AudioCodecSapmGetCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)1308 int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
1309 {
1310     if (AudioCodecGetCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
1311         ADM_LOG_ERR("Audio codec sapm get control switch is fail!");
1312         return HDF_FAILURE;
1313     }
1314 
1315     return HDF_SUCCESS;
1316 }
1317 
1318 /* 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)1319 static int32_t AudioSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue,
1320     uint32_t *value, uint32_t *pathStatus)
1321 {
1322     struct AudioMixerControl *mixerCtrl = NULL;
1323     int32_t iFlag = (kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)
1324         || (value == NULL) || (pathStatus == NULL);
1325     if (iFlag) {
1326         ADM_LOG_ERR("input params invalid.");
1327         return HDF_ERR_INVALID_OBJECT;
1328     }
1329 
1330     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
1331     *value = elemValue->value[0];
1332     if (*value < mixerCtrl->min || *value > mixerCtrl->max) {
1333         ADM_LOG_ERR("value is invalid.");
1334         return HDF_ERR_INVALID_OBJECT;
1335     }
1336 
1337     if (*value) {
1338         *pathStatus = CONNECT_SINK_AND_SOURCE;
1339     } else {
1340         *pathStatus = UNCONNECT_SINK_AND_SOURCE;
1341     }
1342 
1343     if (mixerCtrl->invert) {
1344         *value = mixerCtrl->max - *value;
1345     }
1346 
1347     return HDF_SUCCESS;
1348 }
1349 
AudioCodecSapmSetCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)1350 int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
1351 {
1352     uint32_t value;
1353     uint32_t pathStatus = 0;
1354     struct CodecDevice *codec = NULL;
1355     struct AudioMixerControl *mixerCtrl = NULL;
1356     if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (kcontrol->pri == NULL)) {
1357         ADM_LOG_ERR("input params: kcontrol is NULL.");
1358         return HDF_ERR_INVALID_OBJECT;
1359     }
1360     if (elemValue == NULL) {
1361         ADM_LOG_ERR("input params: elemValue is NULL.");
1362         return HDF_ERR_INVALID_OBJECT;
1363     }
1364 
1365     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
1366     if (AudioSapmSetCtrlOps(kcontrol, elemValue, &value, &pathStatus) != HDF_SUCCESS) {
1367         ADM_LOG_ERR("Audio sapm put control switch fail!");
1368     }
1369     codec = AudioKcontrolGetCodec(kcontrol);
1370 
1371     if (MixerUpdatePowerStatus(kcontrol, pathStatus) != HDF_SUCCESS) {
1372         ADM_LOG_ERR("update power status is failure!");
1373         return HDF_FAILURE;
1374     }
1375 
1376     mixerCtrl->value = elemValue->value[0];
1377     if (AudioCodecRegUpdate(codec, mixerCtrl) != HDF_SUCCESS) {
1378         ADM_LOG_ERR("update reg bits fail!");
1379         return HDF_FAILURE;
1380     }
1381     return HDF_SUCCESS;
1382 }
1383 
AudioCodecCheckRegIsChange(struct AudioEnumKcontrol * enumCtrl,const struct AudioCtrlElemValue * elemValue,uint32_t curValue,bool * change)1384 static int32_t AudioCodecCheckRegIsChange(struct AudioEnumKcontrol *enumCtrl,
1385     const struct AudioCtrlElemValue *elemValue, uint32_t curValue, bool *change)
1386 {
1387     uint32_t value;
1388     uint32_t mask;
1389     uint32_t oldValue;
1390 
1391     if (enumCtrl == NULL || elemValue == NULL || change == NULL) {
1392         ADM_LOG_ERR("input para is null!");
1393         return HDF_FAILURE;
1394     }
1395 
1396     *change = false;
1397     if (elemValue->value[0] > enumCtrl->max) {
1398         ADM_LOG_ERR("elemValue value[0] out of range!");
1399         return HDF_FAILURE;
1400     }
1401 
1402     if (enumCtrl->values != NULL) {
1403         value = enumCtrl->values[elemValue->value[0]] << enumCtrl->shiftLeft;
1404         mask = enumCtrl->mask << enumCtrl->shiftLeft;
1405         if (enumCtrl->shiftLeft != enumCtrl->shiftRight) {
1406             if (elemValue->value[1] > enumCtrl->max) {
1407                 ADM_LOG_ERR("elemValue value[1] out of range!");
1408                 return HDF_FAILURE;
1409             }
1410             value |= enumCtrl->values[elemValue->value[1]] << enumCtrl->shiftRight;
1411             mask |= enumCtrl->mask << enumCtrl->shiftRight;
1412         }
1413     } else {
1414         value = elemValue->value[0] << enumCtrl->shiftLeft;
1415         mask = enumCtrl->mask << enumCtrl->shiftLeft;
1416         if (enumCtrl->shiftLeft != enumCtrl->shiftRight) {
1417             if (elemValue->value[1] > enumCtrl->max) {
1418                 ADM_LOG_ERR("elemValue value[1] out of range!");
1419                 return HDF_FAILURE;
1420             }
1421             value |= elemValue->value[1] << enumCtrl->shiftRight;
1422             mask |= enumCtrl->mask << enumCtrl->shiftRight;
1423         }
1424     }
1425 
1426     oldValue = curValue & mask;
1427     if (oldValue != value) {
1428         *change = true;
1429     }
1430     return HDF_SUCCESS;
1431 }
1432 
AudioCodecSapmSetEnumCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)1433 int32_t AudioCodecSapmSetEnumCtrlOps(const struct AudioKcontrol *kcontrol,
1434     const struct AudioCtrlElemValue *elemValue)
1435 {
1436     uint32_t curValue;
1437     bool change;
1438     int32_t ret;
1439     struct CodecDevice *codec = NULL;
1440     struct AudioEnumKcontrol *enumCtrl = NULL;
1441 
1442     if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)) {
1443         ADM_LOG_ERR("input params: kcontrol is NULL or elemValue=%p.", elemValue);
1444         return HDF_ERR_INVALID_OBJECT;
1445     }
1446     codec = AudioKcontrolGetCodec(kcontrol);
1447 
1448     enumCtrl = (struct AudioEnumKcontrol *)((volatile uintptr_t)kcontrol->privateValue);
1449     if (enumCtrl == NULL) {
1450         ADM_LOG_ERR("privateValue is null");
1451         return HDF_FAILURE;
1452     }
1453 
1454     if (AudioCodecReadReg(codec, enumCtrl->reg, &curValue) != HDF_SUCCESS) {
1455         ADM_LOG_ERR("Device read register is failure!");
1456         return HDF_FAILURE;
1457     }
1458 
1459     ret = AudioCodecCheckRegIsChange(enumCtrl, elemValue, curValue, &change);
1460     if (ret != HDF_SUCCESS) {
1461         ADM_LOG_ERR("AudioCodecCheckRegIsChange is failure!");
1462         return HDF_FAILURE;
1463     }
1464 
1465     if (change) {
1466         if (MuxUpdatePowerStatus(kcontrol, elemValue->value[0], enumCtrl) != HDF_SUCCESS) {
1467             ADM_LOG_ERR("update power status is failure!");
1468             return HDF_FAILURE;
1469         }
1470 
1471         ret = AudioCodecMuxRegUpdate(codec, enumCtrl, elemValue->value);
1472         if (ret != HDF_SUCCESS) {
1473             ADM_LOG_ERR("AudioCodecMuxRegUpdate is failure!");
1474             return HDF_FAILURE;
1475         }
1476     }
1477 
1478     return HDF_SUCCESS;
1479 }
1480 
AudioCodecSapmGetEnumCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)1481 int32_t AudioCodecSapmGetEnumCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
1482 {
1483     if (AudioCodecGetEnumCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
1484         ADM_LOG_ERR("Audio codec sapm get control switch is fail!");
1485         return HDF_FAILURE;
1486     }
1487 
1488     return HDF_SUCCESS;
1489 }
1490 
AudioSapmRefreshTime(struct AudioCard * audioCard,bool bRefresh)1491 static int32_t AudioSapmRefreshTime(struct AudioCard *audioCard, bool bRefresh)
1492 {
1493     if (audioCard == NULL) {
1494         ADM_LOG_ERR("input params is NULL.");
1495         return HDF_ERR_INVALID_OBJECT;
1496     }
1497 
1498     if (bRefresh) {
1499         audioCard->time = 0;
1500     }
1501     return HDF_SUCCESS;
1502 }
1503 
AudioSapmCheckTime(struct AudioCard * audioCard,bool * timeoutStatus)1504 static int32_t AudioSapmCheckTime(struct AudioCard *audioCard, bool *timeoutStatus)
1505 {
1506     int32_t ret;
1507 
1508     if (audioCard == NULL || timeoutStatus == NULL) {
1509         ADM_LOG_ERR("input params is NULL.");
1510         return HDF_ERR_INVALID_OBJECT;
1511     }
1512 
1513     ret = AudioSapmRefreshTime(audioCard, false);
1514     if (ret != HDF_SUCCESS) {
1515         ADM_LOG_ERR("AudioSapmRefreshTime failed.");
1516         return HDF_FAILURE;
1517     }
1518     *timeoutStatus = audioCard->time > SAPM_SLEEP_TIMES ? true : false;
1519 
1520     return HDF_SUCCESS;
1521 }
1522 
AudioSampPowerUp(const struct AudioCard * card)1523 int32_t AudioSampPowerUp(const struct AudioCard *card)
1524 {
1525     struct DListHead upList;
1526     struct AudioSapmComponent *sapmComponent = NULL;
1527 
1528     if (card == NULL) {
1529         ADM_LOG_ERR("input params is null.");
1530         return HDF_ERR_INVALID_OBJECT;
1531     }
1532 
1533     DListHeadInit(&upList);
1534     DLIST_FOR_EACH_ENTRY(sapmComponent, &card->components, struct AudioSapmComponent, list) {
1535         if (sapmComponent == NULL) {
1536             break;
1537         }
1538         if (sapmComponent->power == SAPM_POWER_DOWN) {
1539             AudioSapmPowerSeqInsert(sapmComponent, &upList, SAPM_POWER_UP);
1540         }
1541     }
1542 
1543     AudioSapmPowerUpSeqRun(&upList);
1544     return HDF_SUCCESS;
1545 }
1546 
AudioSampSetPowerMonitor(struct AudioCard * card,bool powerMonitorState)1547 int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState)
1548 {
1549     if (card == NULL) {
1550         ADM_LOG_ERR("input params is null.");
1551         return HDF_ERR_INVALID_OBJECT;
1552     }
1553 
1554     card->sapmMonitorState = powerMonitorState;
1555     if (powerMonitorState == false) {
1556         card->sapmSleepState = false;
1557         card->sapmStandbyState = false;
1558         card->sapmStandbyStartTimeFlag = false;
1559         card->sapmSleepStartTimeFlag = false;
1560     }
1561     return HDF_SUCCESS;
1562 }
1563 
AudioSapmEnterSleep(struct AudioCard * audioCard)1564 static void AudioSapmEnterSleep(struct AudioCard *audioCard)
1565 {
1566     struct DListHead downList;
1567     struct AudioSapmComponent *sapmComponent = NULL;
1568     ADM_LOG_INFO("entry!");
1569 
1570     DListHeadInit(&downList);
1571     if (audioCard == NULL) {
1572         ADM_LOG_ERR("audioCard is null.");
1573         return;
1574     }
1575     DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1576         if (sapmComponent == NULL) {
1577             break;
1578         }
1579         if (sapmComponent->power == SAPM_POWER_UP) {
1580             AudioSapmPowerSeqInsert(sapmComponent, &downList, SAPM_POWER_DOWN);
1581         }
1582     }
1583     AudioSapmPowerDownSeqRun(&downList);
1584     audioCard->sapmStandbyState = false;
1585     audioCard->sapmSleepState = true;
1586 }
1587 
AudioSapmEnterStandby(struct AudioCard * audioCard)1588 static bool AudioSapmEnterStandby(struct AudioCard *audioCard)
1589 {
1590     bool timeoutStatus;
1591     struct AudioSapmComponent *sapmComponent = NULL;
1592 
1593     if (audioCard == NULL) {
1594         ADM_LOG_ERR("audioCard is null.");
1595         return false;
1596     }
1597 
1598     if (audioCard->sapmStandbyStartTimeFlag == false) {
1599         if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
1600             ADM_LOG_ERR("AudioSapmRefreshTime failed.");
1601             return false;
1602         }
1603         audioCard->sapmStandbyStartTimeFlag = true;
1604     }
1605 
1606     if (audioCard->standbyMode != AUDIO_SAPM_TURN_STANDBY_NOW) {
1607         if (AudioSapmCheckTime(audioCard, &timeoutStatus) != HDF_SUCCESS) {
1608             ADM_LOG_ERR("AudioSapmCheckTime failed.");
1609             return false;
1610         }
1611 
1612         if (!timeoutStatus) {
1613             return false;
1614         }
1615     }
1616 
1617     if (audioCard->sapmStandbyState == false) {
1618         DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
1619             if (sapmComponent->PowerClockOp != NULL) {
1620                     sapmComponent->PowerClockOp(sapmComponent);
1621                 }
1622         }
1623         audioCard->sapmStandbyState = true;
1624     }
1625 
1626     return true;
1627 }
1628 
AudioSapmTimerCallback(struct AudioCard * audioCard)1629 static void AudioSapmTimerCallback(struct AudioCard *audioCard)
1630 {
1631     bool timeoutStatus;
1632     bool standbyEntry;
1633 
1634 #ifndef __LITEOS__
1635     ADM_LOG_DEBUG("entry!");
1636 #endif
1637 
1638     if (audioCard == NULL) {
1639         return;
1640     }
1641     if (audioCard->sapmSleepState == true) {
1642         return;
1643     }
1644 
1645     if (audioCard->sapmMonitorState == false) {
1646         return;
1647     }
1648 
1649     standbyEntry = AudioSapmEnterStandby(audioCard);
1650     if (!standbyEntry) {
1651         return;
1652     }
1653 
1654     if (audioCard->sapmSleepStartTimeFlag == false) {
1655         if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
1656             ADM_LOG_ERR("AudioSapmRefreshTime failed.");
1657             return;
1658         }
1659         audioCard->sapmSleepStartTimeFlag = true;
1660     }
1661 
1662     if (AudioSapmCheckTime(audioCard, &timeoutStatus) != HDF_SUCCESS) {
1663         ADM_LOG_ERR("AudioSapmCheckTime failed.");
1664         return;
1665     }
1666 
1667     if (!timeoutStatus) {
1668         return;
1669     }
1670     AudioSapmEnterSleep(audioCard);
1671 }
1672