• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/errno.h>
12 #include <linux/extcon-provider.h>
13 #include <linux/iio/consumer.h>
14 #include <linux/input.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/platform_device.h>
18 #include "analog_headset.h"
19 #include "analog_headset_base.h"
20 #include "hdf_workqueue.h"
21 #include "osal_time.h"
22 #include "osal_mem.h"
23 #include "securec.h"
24 #include "gpio_if.h"
25 #include "osal_irq.h"
26 
27 #define HDF_LOG_TAG analog_headset_adc
28 #define HOOK_ADC_SAMPLE_TIME 100
29 
30 #define HOOK_LEVEL_HIGH 410 // 1V*1024/2.5
31 #define HOOK_LEVEL_LOW 204 // 0.5V*1024/2.5
32 #define HOOK_DEFAULT_VAL 1024
33 
34 #define HEADSET_IN 1
35 #define HEADSET_OUT 0
36 #define HOOK_DOWN 1
37 #define HOOK_UP 0
38 
39 #define HEADSET_TIMER 1
40 #define HOOK_TIMER 2
41 
42 #define WAIT 2
43 #define BUSY 1
44 #define IDLE 0
45 
46 /* headset private data */
47 struct HeadsetPriv {
48     struct input_dev *inDev;
49     struct HeadsetPdata *pdata;
50     uint32_t hsStatus : 1;
51     uint32_t hookStatus : 1;
52     struct iio_channel *chan;
53     /* headset interrupt working will not check hook key  */
54     uint32_t hsIrqWorking;
55     int32_t curHsStatus;
56     HdfWorkQueue workQueue;
57     HdfWork hDelayedWork[HS_HOOK_COUNT];
58     struct extcon_dev *edev;
59     unsigned char *keycodes;
60     HdfWork hHookWork;
61     /* ms */
62     uint32_t hookTime;
63     bool isMic;
64 };
65 
66 static struct HeadsetPriv *g_hsInfo = NULL;
67 
ExtconSetStateSync(struct HeadsetPriv * hs,unsigned int id,bool state)68 static int ExtconSetStateSync(struct HeadsetPriv *hs, unsigned int id, bool state)
69 {
70     if (hs == NULL) {
71         AUDIO_DEVICE_LOG_ERR("hs is NULL!");
72         return -EINVAL;
73     }
74 
75     extcon_set_state_sync(hs->edev, id, state);
76     SetStateSync(id, state);
77     AUDIO_DEVICE_LOG_DEBUG("id = %u, state = %s.", id, state ? "in" : "out");
78 
79     return 0;
80 }
81 
InputReportKeySync(struct HeadsetPriv * hs,unsigned int code,int value)82 static void InputReportKeySync(struct HeadsetPriv *hs, unsigned int code, int value)
83 {
84     if (hs == NULL) {
85         AUDIO_DEVICE_LOG_ERR("hs is NULL!");
86         return;
87     }
88 
89     input_report_key(hs->inDev, code, value);
90     input_sync(hs->inDev);
91     SetStateSync(code, value);
92     AUDIO_DEVICE_LOG_DEBUG("code = %u, value = %s.", code, value ? "in" : "out");
93 }
94 
InitHeadsetPriv(struct HeadsetPriv * hs,struct HeadsetPdata * pdata)95 static void InitHeadsetPriv(struct HeadsetPriv *hs, struct HeadsetPdata *pdata)
96 {
97     if ((hs == NULL) || (pdata == NULL)) {
98         AUDIO_DEVICE_LOG_ERR("hs or pdata is NULL!");
99         return;
100     }
101 
102     hs->pdata = pdata;
103     hs->hsStatus = HEADSET_OUT;
104     hs->hsIrqWorking = IDLE;
105     hs->hookStatus = HOOK_UP;
106     hs->hookTime = HOOK_ADC_SAMPLE_TIME;
107     hs->curHsStatus = BIT_HEADSET_NULL;
108     hs->isMic = false;
109     AUDIO_DEVICE_LOG_DEBUG("isMic = %s.", hs->isMic ? "true" : "false");
110     hs->chan = pdata->chan;
111 }
112 
CheckState(struct HeadsetPriv * hs,bool * beChange)113 static int32_t CheckState(struct HeadsetPriv *hs, bool *beChange)
114 {
115     struct HeadsetPdata *pdata = NULL;
116     static uint32_t oldStatus = 0;
117     int32_t i;
118     int32_t ret;
119     int16_t level = 0;
120 
121     if ((hs == NULL) || (hs->pdata == NULL) || (beChange == NULL)) {
122         AUDIO_DEVICE_LOG_ERR("hs, pdata or beChange is NULL.");
123         return HDF_ERR_INVALID_PARAM;
124     }
125 
126     pdata = hs->pdata;
127     OsalMSleep(IRQ_CONFIRM_MS150);
128     for (i = 0; i < GET_GPIO_REPEAT_TIMES; i++) {
129         ret = GpioRead(pdata->hsGpio, &level);
130         if (ret < 0) {
131             AUDIO_DEVICE_LOG_ERR("get pin level again, pin=%u, i=%d.", pdata->hsGpio, i);
132             OsalMSleep(IRQ_CONFIRM_MS1);
133             continue;
134         }
135         break;
136     }
137     if ((level < 0) || (ret < 0)) {
138         AUDIO_DEVICE_LOG_ERR("get pin level err.");
139         return HDF_FAILURE;
140     }
141 
142     oldStatus = hs->hsStatus;
143     switch (pdata->hsInsertType) {
144         case HEADSET_IN_HIGH:
145             hs->hsStatus = (level > 0) ? HEADSET_IN : HEADSET_OUT;
146             break;
147         case HEADSET_IN_LOW:
148             hs->hsStatus = (level == 0) ? HEADSET_IN : HEADSET_OUT;
149             break;
150         default:
151             AUDIO_DEVICE_LOG_ERR("[hsInsertType] error.");
152             break;
153     }
154     if (oldStatus == hs->hsStatus) {
155         *beChange = false;
156         return HDF_SUCCESS;
157     }
158 
159     *beChange = true;
160     AUDIO_DEVICE_LOG_DEBUG("(headset in is %s)headset status is %s.",
161         pdata->hsInsertType ? "high" : "low", hs->hsStatus ? "in" : "out");
162 
163     return HDF_SUCCESS;
164 }
165 
ReportCurrentState(struct HeadsetPriv * hs)166 static int32_t ReportCurrentState(struct HeadsetPriv *hs)
167 {
168     struct HeadsetPdata *pdata = NULL;
169 
170     if ((hs == NULL) || (hs->pdata == NULL)) {
171         AUDIO_DEVICE_LOG_ERR("hs or pdata is NULL.");
172         return HDF_ERR_INVALID_PARAM;
173     }
174 
175     pdata = hs->pdata;
176     if (hs->hsStatus == HEADSET_IN) {
177         if (pdata->chan != NULL) {
178             /* detect hook key */
179             (void)HdfAddDelayedWork(&hs->workQueue, &hs->hDelayedWork[HOOK], DELAY_WORK_MS200);
180         } else {
181             hs->isMic = false;
182             AUDIO_DEVICE_LOG_DEBUG("isMic = %s.", hs->isMic ? "true" : "false");
183             hs->curHsStatus = BIT_HEADSET_NO_MIC;
184             (void)ExtconSetStateSync(hs, KEY_JACK_HEADPHONE, true);
185             AUDIO_DEVICE_LOG_DEBUG("notice headset status = %d(0: NULL, 1: HEADSET, 2: HEADPHONE).", hs->curHsStatus);
186         }
187     } else {
188         hs->curHsStatus = BIT_HEADSET_NULL;
189         HdfCancelDelayedWorkSync(&hs->hHookWork);
190         if (hs->isMic) {
191             if (hs->hookStatus == HOOK_DOWN) {
192                 hs->hookStatus = HOOK_UP;
193                 InputReportKeySync(hs, HOOK_KEY_CODE, hs->hookStatus);
194             }
195             hs->isMic = false;
196             AUDIO_DEVICE_LOG_DEBUG("isMic = %s.", hs->isMic ? "true" : "false");
197         }
198 
199         // Need judge the type, it is not always microphone.
200         (void)ExtconSetStateSync(hs, KEY_JACK_HEADSET, false);
201         AUDIO_DEVICE_LOG_DEBUG("notice headset status = %d(0: NULL, 1: HEADSET, 2:HEADPHONE).", hs->curHsStatus);
202     }
203 
204     return HDF_SUCCESS;
205 }
206 
HeadsetInterrupt(uint16_t gpio,void * data)207 static int32_t HeadsetInterrupt(uint16_t gpio, void * data)
208 {
209     int32_t ret;
210     struct HeadsetPriv *hs = g_hsInfo;
211     bool beChange = false;
212 
213     (void)data;
214     if (hs == NULL) {
215         AUDIO_DEVICE_LOG_ERR("hs is NULL.");
216         return -EINVAL;
217     }
218 
219     GpioDisableIrq(hs->pdata->hsGpio);
220     if ((hs->hsIrqWorking == BUSY) ||
221         (hs->hsIrqWorking == WAIT)) {
222         AUDIO_DEVICE_LOG_DEBUG("hsIrqWorking is BUSY or WAIT.");
223         return IRQ_HANDLED;
224     }
225 
226     hs->hsIrqWorking = BUSY;
227     ret = CheckState(hs, &beChange);
228     if (ret != HDF_SUCCESS) {
229         AUDIO_DEVICE_LOG_DEBUG("[CheckState] failed.");
230         hs->hsIrqWorking = IDLE;
231         GpioEnableIrq(hs->pdata->hsGpio);
232         return IRQ_HANDLED;
233     }
234     if (!beChange) {
235         hs->hsIrqWorking = IDLE;
236         GpioEnableIrq(hs->pdata->hsGpio);
237         return IRQ_HANDLED;
238     }
239 
240     (void)ReportCurrentState(hs);
241     hs->hsIrqWorking = IDLE;
242     GpioEnableIrq(hs->pdata->hsGpio);
243     return IRQ_HANDLED;
244 }
245 
246 #ifdef TEST_FOR_CHANGE_IRQTYPE /* not actived. */
HeadsetChangeIrqtype(int type,unsigned int irqType)247 static int32_t HeadsetChangeIrqtype(int type, unsigned int irqType)
248 {
249     int32_t ret;
250 
251     free_irq(g_hsInfo->irq[type], NULL);
252 
253     AUDIO_DEVICE_LOG_DEBUG("type is %s irqtype is %s.", type ? "hook" : "headset",
254         (irqType == IRQF_TRIGGER_RISING) ? "RISING" : "FALLING");
255     AUDIO_DEVICE_LOG_DEBUG("type is %s irqtype is %s.",
256         type ? "hook" : "headset", (irqType == IRQF_TRIGGER_LOW) ? "LOW" : "HIGH");
257     switch (type) {
258         case HEADSET:
259             ret = request_threaded_irq(g_hsInfo->irq[type], NULL, HeadsetInterrupt, irqType, "headset_input", NULL);
260             if (ret < 0) {
261                 AUDIO_DEVICE_LOG_DEBUG("HeadsetChangeIrqtype: request irq failed.");
262             }
263             break;
264         default:
265             ret = -EINVAL;
266             break;
267     }
268     return ret;
269 }
270 #endif
271 
HookOnceWork(void * arg)272 static void HookOnceWork(void *arg)
273 {
274     int32_t ret;
275     int32_t val;
276     uint32_t type;
277     struct HeadsetPriv *hs = (struct HeadsetPriv *)arg;
278 
279     if (hs == NULL) {
280         AUDIO_DEVICE_LOG_ERR("hs is NULL.");
281         return;
282     }
283     ret = iio_read_channel_raw(hs->chan, &val);
284     if (ret < 0) {
285         AUDIO_DEVICE_LOG_ERR("read HookOnceWork adc channel() error: %d.", ret);
286     } else {
287         AUDIO_DEVICE_LOG_DEBUG("HookOnceWork read adc value: %d.", val);
288     }
289 
290     if (val >= 0 && val < HOOK_LEVEL_LOW) {
291         hs->isMic = false;
292     } else if (val >= HOOK_LEVEL_HIGH) {
293         hs->isMic = true;
294         (void)HdfAddDelayedWork(&hs->workQueue, &hs->hHookWork, DELAY_WORK_MS100);
295     } else {
296         ; // do nothing.
297     }
298     AUDIO_DEVICE_LOG_DEBUG("isMic = %s.", g_hsInfo->isMic ? "true" : "false");
299     hs->curHsStatus = hs->isMic ? BIT_HEADSET : BIT_HEADSET_NO_MIC;
300 
301     if (hs->curHsStatus != BIT_HEADSET_NULL) {
302         type = (hs->isMic) ? KEY_JACK_HEADSET : KEY_JACK_HEADPHONE;
303         (void)ExtconSetStateSync(hs, type, true);
304     }
305     AUDIO_DEVICE_LOG_DEBUG("notice headset status = %d(0: NULL, 1: HEADSET, 2:HEADPHONE).", hs->curHsStatus);
306 }
307 
CheckInsertType(struct HeadsetPdata * pdata)308 static int32_t CheckInsertType(struct HeadsetPdata *pdata)
309 {
310     int32_t i;
311     int32_t ret;
312     int16_t level = 0;
313 
314     for (i = 0; i < GET_GPIO_REPEAT_TIMES; i++) {
315         ret = GpioRead(pdata->hsGpio, &level);
316         if (ret < 0) {
317             AUDIO_DEVICE_LOG_ERR("get pin level again, pin=%u, i=%d.", pdata->hsGpio, i);
318             OsalMSleep(IRQ_CONFIRM_MS1);
319             continue;
320         }
321         break;
322     }
323 
324     if ((level < 0) || (ret < 0)) {
325         AUDIO_DEVICE_LOG_ERR("get pin level err.");
326         return HDF_FAILURE;
327     }
328 
329     switch (pdata->hsInsertType) {
330         case HEADSET_IN_HIGH:
331             ret = (level > 0) ? HEADSET_IN : HEADSET_OUT;
332             break;
333         case HEADSET_IN_LOW:
334             ret = (level == 0) ? HEADSET_IN : HEADSET_OUT;
335             break;
336         default:
337             ret = HDF_FAILURE;
338             AUDIO_DEVICE_LOG_ERR("[hsInsertType] error.");
339             break;
340     }
341 
342     return ret;
343 }
344 
HookWorkCallback(void * arg)345 static void HookWorkCallback(void * arg)
346 {
347     int32_t ret;
348     int32_t val;
349     struct HeadsetPriv *hs = (struct HeadsetPriv *)arg;
350     static uint32_t oldStatus = HOOK_UP;
351     static int32_t oldVal = -1; // Invalid initial value
352 
353     if ((hs == NULL) || (hs->pdata == NULL)) {
354         AUDIO_DEVICE_LOG_ERR("hs or hs->pdata is NULL.");
355         return;
356     }
357 
358     ret = iio_read_channel_raw(hs->chan, &val);
359     if (ret < 0) {
360         AUDIO_DEVICE_LOG_ERR("read hook adc channel() error: %d.", ret);
361         return;
362     }
363 
364     ret = CheckInsertType(hs->pdata);
365     if ((hs->hsStatus == HEADSET_OUT) || (hs->hsIrqWorking == BUSY) || (hs->hsIrqWorking == WAIT) ||
366         (ret != HEADSET_IN)) {
367         AUDIO_DEVICE_LOG_DEBUG("Headset is out or waiting for headset is in or out, after same time check HOOK key.");
368         return;
369     }
370     oldStatus = hs->hookStatus;
371     if (val < HOOK_LEVEL_LOW && val >= 0) {
372         hs->hookStatus = HOOK_DOWN;
373     } else if (val > HOOK_LEVEL_HIGH && val < HOOK_DEFAULT_VAL) {
374         hs->hookStatus = HOOK_UP;
375     } else {
376         ; // do nothing.
377     }
378     if (oldVal != val) {
379         AUDIO_DEVICE_LOG_DEBUG("HOOK status is %s , adc value = %d, hookTime = %u.",
380             hs->hookStatus ? "down" : "up", val, hs->hookTime);
381         oldVal = val;
382     }
383     if (oldStatus == hs->hookStatus) {
384         (void)HdfAddDelayedWork(&hs->workQueue, &hs->hHookWork, DELAY_WORK_MS100);
385         return;
386     }
387 
388     ret = CheckInsertType(hs->pdata);
389     if ((hs->hsStatus == HEADSET_OUT) || (hs->hsIrqWorking == BUSY) || (hs->hsIrqWorking == WAIT) ||
390         (ret != HEADSET_IN)) {
391         AUDIO_DEVICE_LOG_DEBUG("headset is out, HOOK status must discard.");
392         return;
393     }
394     InputReportKeySync(hs, HOOK_KEY_CODE, hs->hookStatus);
395     (void)HdfAddDelayedWork(&hs->workQueue, &hs->hHookWork, DELAY_WORK_MS100);
396 }
397 
AnalogHskeyOpen(struct input_dev * dev)398 static int AnalogHskeyOpen(struct input_dev *dev)
399 {
400     (void)dev;
401     return 0;
402 }
403 
AnalogHskeyClose(struct input_dev * dev)404 static void AnalogHskeyClose(struct input_dev *dev)
405 {
406     (void)dev;
407 }
408 
409 static const unsigned int g_hsCable[] = {
410     KEY_JACK_HEADSET,
411     KEY_JACK_HEADPHONE,
412     EXTCON_NONE,
413 };
414 
InitWorkData(struct HeadsetPriv * hs)415 static int32_t InitWorkData(struct HeadsetPriv *hs)
416 {
417     struct HeadsetPdata *pdata = NULL;
418     if ((hs == NULL) || (hs->pdata == NULL)) {
419         AUDIO_DEVICE_LOG_ERR("hs or pdata is NULL.");
420         return HDF_ERR_INVALID_PARAM;
421     }
422     pdata = hs->pdata;
423     if (HdfWorkQueueInit(&hs->workQueue, HDF_HEADSET_WORK_QUEUE_NAME) != HDF_SUCCESS) {
424         AUDIO_DEVICE_LOG_ERR("Init work queue failed");
425         return HDF_FAILURE;
426     }
427     HdfDelayedWorkInit(&hs->hDelayedWork[HOOK], HookOnceWork, hs);
428     if (pdata->chan != NULL) { // this is always true.
429         HdfDelayedWorkInit(&hs->hHookWork, HookWorkCallback, hs);
430     }
431 
432     return HDF_SUCCESS;
433 }
434 
CreateAndRegisterInputDevice(struct platform_device * pdev,struct HeadsetPriv * hs)435 static int32_t CreateAndRegisterInputDevice(struct platform_device *pdev, struct HeadsetPriv *hs)
436 {
437     int32_t ret;
438 
439     AUDIO_DEVICE_LOG_INFO("enter.");
440     if ((hs == NULL) || (pdev == NULL)) {
441         AUDIO_DEVICE_LOG_ERR("hs or pdev is NULL.");
442         return -EINVAL;
443     }
444 
445     hs->inDev = devm_input_allocate_device(&pdev->dev);
446     if (hs->inDev == NULL) {
447         AUDIO_DEVICE_LOG_ERR("failed to allocate input device.");
448         ret = -ENOMEM;
449         return ret;
450     }
451 
452     hs->inDev->name = pdev->name;
453     hs->inDev->open = AnalogHskeyOpen;
454     hs->inDev->close = AnalogHskeyClose;
455     hs->inDev->dev.parent = &pdev->dev;
456 
457     hs->inDev->id.vendor = INPUT_DEVID_VENDOR;
458     hs->inDev->id.product = INPUT_DEVID_PRODUCT;
459     hs->inDev->id.version = INPUT_DEVID_VERSION;
460     // register the input device
461     ret = input_register_device(hs->inDev);
462     if (ret) {
463         AUDIO_DEVICE_LOG_ERR("failed to register input device.");
464         return ret;
465     }
466     input_set_capability(hs->inDev, EV_KEY, HOOK_KEY_CODE);
467     AUDIO_DEVICE_LOG_INFO("%s: done.");
468 
469     return ret;
470 }
471 
SetHeadsetIrqEnable(struct device * dev,struct HeadsetPriv * hs)472 static int32_t SetHeadsetIrqEnable(struct device *dev, struct HeadsetPriv *hs)
473 {
474     int32_t ret;
475     struct HeadsetPdata *pdata = NULL;
476     uint32_t irqType;
477     uint32_t irq;
478 
479     if ((hs == NULL) || (hs->pdata == NULL) || (dev == NULL)) {
480         AUDIO_DEVICE_LOG_ERR("hs, pdata or dev is NULL.");
481         return HDF_ERR_INVALID_PARAM;
482     }
483 
484     pdata = hs->pdata;
485     if (pdata->hsGpio) {
486         irqType = GPIO_IRQ_TRIGGER_RISING | GPIO_IRQ_TRIGGER_FALLING | GPIO_IRQ_USING_THREAD;
487         ret = GpioSetIrq(pdata->hsGpio, irqType, HeadsetInterrupt, NULL);
488         if (ret != HDF_SUCCESS) {
489             AUDIO_DEVICE_LOG_ERR("failed headset adc probe ret=%d.", ret);
490             return ret;
491         }
492 
493         ret = GpioEnableIrq(pdata->hsGpio);
494         if (ret != HDF_SUCCESS) {
495             AUDIO_DEVICE_LOG_ERR("enable irq fail! ret:%d\n", ret);
496             (void)GpioUnsetIrq(pdata->hsGpio, NULL);
497             return ret;
498         }
499 
500         if (pdata->hsWakeup) {
501             irq = gpio_to_irq(pdata->hsGpio);
502             enable_irq_wake(irq);
503         }
504     } else {
505         AUDIO_DEVICE_LOG_ERR("failed init headset,please full hook_io_init function in board.");
506         ret = -EEXIST;
507         return ret;
508     }
509 
510     return 0;
511 }
512 
AnalogHeadsetAdcInit(struct platform_device * pdev,struct HeadsetPdata * pdata)513 int32_t AnalogHeadsetAdcInit(struct platform_device *pdev, struct HeadsetPdata *pdata)
514 {
515     int32_t ret;
516     struct HeadsetPriv *hs;
517 
518     AUDIO_DEVICE_LOG_INFO("%s: enter.");
519     hs = (struct HeadsetPriv *)OsalMemCalloc(sizeof(*hs));
520     if (hs == NULL) {
521         AUDIO_DEVICE_LOG_ERR("failed to allocate driver data.");
522         return HDF_ERR_MALLOC_FAIL;
523     }
524     g_hsInfo = hs;
525     InitHeadsetPriv(hs, pdata);
526     hs->edev = devm_extcon_dev_allocate(&pdev->dev, g_hsCable);
527     if (IS_ERR(hs->edev)) {
528         AUDIO_DEVICE_LOG_ERR("failed to allocate extcon device.");
529         return-ENOMEM;
530     }
531     ret = devm_extcon_dev_register(&pdev->dev, hs->edev);
532     if (ret < 0) {
533         AUDIO_DEVICE_LOG_ERR("extcon_dev_register() failed: %d.", ret);
534         return ret;
535     }
536     ret = InitWorkData(hs);
537     if (ret != HDF_SUCCESS) {
538         AUDIO_DEVICE_LOG_ERR("[InitWorkData] failed");
539         return ret;
540     }
541     // Create and register the input driver
542     ret = CreateAndRegisterInputDevice(pdev, hs);
543     if (ret != 0) {
544         AUDIO_DEVICE_LOG_ERR("[CreateAndRegisterInputDevice] failed");
545         return ret;
546     }
547     ret = CreateAndRegisterHdfInputDevice((void *)hs, pdata->device);
548     if (ret != 0) {
549         AUDIO_DEVICE_LOG_DEBUG("[CreateAndRegisterHdfInputDevice] failed");
550     }
551     ret = SetHeadsetIrqEnable(&pdev->dev, hs);
552     if (ret != 0) {
553         AUDIO_DEVICE_LOG_ERR("[SetHeadsetIrqEnable] failed");
554         return ret;
555     }
556     AUDIO_DEVICE_LOG_INFO("%s: success.");
557     return ret;
558 }
559 
AnalogHeadsetAdcSuspend(struct platform_device * pdev,pm_message_t state)560 int AnalogHeadsetAdcSuspend(struct platform_device *pdev, pm_message_t state)
561 {
562     AUDIO_DEVICE_LOG_DEBUG("%d enter.");
563     (void)pdev;
564     (void)state;
565 
566     return 0;
567 }
568 
AnalogHeadsetAdcResume(struct platform_device * pdev)569 int AnalogHeadsetAdcResume(struct platform_device *pdev)
570 {
571     AUDIO_DEVICE_LOG_DEBUG("%d enter.");
572     (void)pdev;
573 
574     return 0;
575 }
576 
AnalogHeadsetAdcRelease(struct HeadsetPdata * pdata)577 void AnalogHeadsetAdcRelease(struct HeadsetPdata *pdata)
578 {
579     struct HeadsetPriv *hs = g_hsInfo;
580     if (hs == NULL) {
581         AUDIO_DEVICE_LOG_ERR("hs is NULL.");
582         return;
583     }
584     (void)pdata;
585     HdfWorkDestroy(&hs->hDelayedWork[HOOK]);
586     HdfCancelDelayedWorkSync(&hs->hHookWork);
587     HdfWorkDestroy(&hs->hHookWork);
588     HdfWorkQueueDestroy(&hs->workQueue);
589     DestroyHdfInputDevice();
590     OsalMemFree(hs);
591     g_hsInfo = NULL;
592 }