• 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_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, &regVal);
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