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, ®Val);
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