1// SPDX-License-Identifier: GPL-2.0
2//
3// mt6359-accdet.c -- ALSA SoC mt6359 accdet driver
4//
5// Copyright (C) 2021 MediaTek Inc.
6// Author: Argus Lin <argus.lin@mediatek.com>
7//
8
9#include <linux/of.h>
10#include <linux/input.h>
11#include <linux/kthread.h>
12#include <linux/io.h>
13#include <linux/sched/clock.h>
14#include <linux/workqueue.h>
15#include <linux/timer.h>
16#include <linux/delay.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/init.h>
20#include <linux/irqdomain.h>
21#include <linux/irq.h>
22#include <linux/regmap.h>
23#include <sound/soc.h>
24#include <sound/jack.h>
25#include <linux/mfd/mt6397/core.h>
26
27#include "mt6359-accdet.h"
28#include "mt6359.h"
29
30/* global variable definitions */
31#define REGISTER_VAL(x) ((x) - 1)
32
33/* mt6359 accdet capability */
34#define ACCDET_PMIC_EINT_IRQ BIT(0)
35#define ACCDET_AP_GPIO_EINT BIT(1)
36
37#define ACCDET_PMIC_EINT0 BIT(2)
38#define ACCDET_PMIC_EINT1 BIT(3)
39#define ACCDET_PMIC_BI_EINT BIT(4)
40
41#define ACCDET_PMIC_GPIO_TRIG_EINT BIT(5)
42#define ACCDET_PMIC_INVERTER_TRIG_EINT BIT(6)
43#define ACCDET_PMIC_RSV_EINT BIT(7)
44
45#define ACCDET_THREE_KEY BIT(8)
46#define ACCDET_FOUR_KEY BIT(9)
47#define ACCDET_TRI_KEY_CDD BIT(10)
48#define ACCDET_RSV_KEY BIT(11)
49
50#define ACCDET_ANALOG_FASTDISCHARGE BIT(12)
51#define ACCDET_DIGITAL_FASTDISCHARGE BIT(13)
52#define ACCDET_AD_FASTDISCHRAGE BIT(14)
53
54static struct platform_driver mt6359_accdet_driver;
55static const struct snd_soc_component_driver mt6359_accdet_soc_driver;
56
57/* local function declaration */
58static void accdet_set_debounce(struct mt6359_accdet *priv, int state,
59 unsigned int debounce);
60static unsigned int adjust_eint_analog_setting(struct mt6359_accdet *priv);
61static void config_digital_init_by_mode(struct mt6359_accdet *priv);
62static void config_eint_init_by_mode(struct mt6359_accdet *priv);
63static inline void mt6359_accdet_init(struct mt6359_accdet *priv);
64static unsigned int mt6359_accdet_jd_setting(struct mt6359_accdet *priv);
65static void mt6359_accdet_recover_jd_setting(struct mt6359_accdet *priv);
66static void mt6359_accdet_jack_report(struct mt6359_accdet *priv);
67static void recover_eint_analog_setting(struct mt6359_accdet *priv);
68static void recover_eint_digital_setting(struct mt6359_accdet *priv);
69static void recover_eint_setting(struct mt6359_accdet *priv);
70
71static unsigned int adjust_eint_analog_setting(struct mt6359_accdet *priv)
72{
73 if (priv->data->eint_detect_mode == 0x3 ||
74 priv->data->eint_detect_mode == 0x4) {
75 /* ESD switches off */
76 regmap_update_bits(map: priv->regmap,
77 RG_ACCDETSPARE_ADDR, mask: 1 << 8, val: 0);
78 }
79 if (priv->data->eint_detect_mode == 0x4) {
80 if (priv->caps & ACCDET_PMIC_EINT0) {
81 /* enable RG_EINT0CONFIGACCDET */
82 regmap_update_bits(map: priv->regmap,
83 RG_EINT0CONFIGACCDET_ADDR,
84 RG_EINT0CONFIGACCDET_MASK_SFT,
85 BIT(RG_EINT0CONFIGACCDET_SFT));
86 } else if (priv->caps & ACCDET_PMIC_EINT1) {
87 /* enable RG_EINT1CONFIGACCDET */
88 regmap_update_bits(map: priv->regmap,
89 RG_EINT1CONFIGACCDET_ADDR,
90 RG_EINT1CONFIGACCDET_MASK_SFT,
91 BIT(RG_EINT1CONFIGACCDET_SFT));
92 }
93 if (priv->data->eint_use_ext_res == 0x3 ||
94 priv->data->eint_use_ext_res == 0x4) {
95 /*select 500k, use internal resistor */
96 regmap_update_bits(map: priv->regmap,
97 RG_EINT0HIRENB_ADDR,
98 RG_EINT0HIRENB_MASK_SFT,
99 BIT(RG_EINT0HIRENB_SFT));
100 }
101 }
102 return 0;
103}
104
105static unsigned int adjust_eint_digital_setting(struct mt6359_accdet *priv)
106{
107 if (priv->caps & ACCDET_PMIC_EINT0) {
108 /* disable inverter */
109 regmap_update_bits(map: priv->regmap,
110 ACCDET_EINT0_INVERTER_SW_EN_ADDR,
111 ACCDET_EINT0_INVERTER_SW_EN_MASK_SFT, val: 0);
112 } else if (priv->caps & ACCDET_PMIC_EINT1) {
113 /* disable inverter */
114 regmap_update_bits(map: priv->regmap,
115 ACCDET_EINT1_INVERTER_SW_EN_ADDR,
116 ACCDET_EINT1_INVERTER_SW_EN_MASK_SFT, val: 0);
117 }
118
119 if (priv->data->eint_detect_mode == 0x4) {
120 if (priv->caps & ACCDET_PMIC_EINT0) {
121 /* set DA stable signal */
122 regmap_update_bits(map: priv->regmap,
123 ACCDET_DA_STABLE_ADDR,
124 ACCDET_EINT0_CEN_STABLE_MASK_SFT, val: 0);
125 } else if (priv->caps & ACCDET_PMIC_EINT1) {
126 /* set DA stable signal */
127 regmap_update_bits(map: priv->regmap,
128 ACCDET_DA_STABLE_ADDR,
129 ACCDET_EINT1_CEN_STABLE_MASK_SFT, val: 0);
130 }
131 }
132 return 0;
133}
134
135static unsigned int mt6359_accdet_jd_setting(struct mt6359_accdet *priv)
136{
137 if (priv->jd_sts == M_PLUG_IN) {
138 /* adjust digital setting */
139 adjust_eint_digital_setting(priv);
140 /* adjust analog setting */
141 adjust_eint_analog_setting(priv);
142 } else if (priv->jd_sts == M_PLUG_OUT) {
143 /* set debounce to 1ms */
144 accdet_set_debounce(priv, state: eint_state000,
145 debounce: priv->data->pwm_deb->eint_debounce0);
146 } else {
147 dev_dbg(priv->dev, "should not be here %s()\n", __func__);
148 }
149
150 return 0;
151}
152
153static void recover_eint_analog_setting(struct mt6359_accdet *priv)
154{
155 if (priv->data->eint_detect_mode == 0x3 ||
156 priv->data->eint_detect_mode == 0x4) {
157 /* ESD switches on */
158 regmap_update_bits(map: priv->regmap, RG_ACCDETSPARE_ADDR,
159 mask: 1 << 8, val: 1 << 8);
160 }
161 if (priv->data->eint_detect_mode == 0x4) {
162 if (priv->caps & ACCDET_PMIC_EINT0) {
163 /* disable RG_EINT0CONFIGACCDET */
164 regmap_update_bits(map: priv->regmap,
165 RG_EINT0CONFIGACCDET_ADDR,
166 RG_EINT0CONFIGACCDET_MASK_SFT, val: 0);
167 } else if (priv->caps & ACCDET_PMIC_EINT1) {
168 /* disable RG_EINT1CONFIGACCDET */
169 regmap_update_bits(map: priv->regmap,
170 RG_EINT1CONFIGACCDET_ADDR,
171 RG_EINT1CONFIGACCDET_MASK_SFT, val: 0);
172 }
173 regmap_update_bits(map: priv->regmap, RG_EINT0HIRENB_ADDR,
174 RG_EINT0HIRENB_MASK_SFT, val: 0);
175 }
176}
177
178static void recover_eint_digital_setting(struct mt6359_accdet *priv)
179{
180 if (priv->caps & ACCDET_PMIC_EINT0) {
181 regmap_update_bits(map: priv->regmap,
182 ACCDET_EINT0_M_SW_EN_ADDR,
183 ACCDET_EINT0_M_SW_EN_MASK_SFT, val: 0);
184 } else if (priv->caps & ACCDET_PMIC_EINT1) {
185 regmap_update_bits(map: priv->regmap,
186 ACCDET_EINT1_M_SW_EN_ADDR,
187 ACCDET_EINT1_M_SW_EN_MASK_SFT, val: 0);
188 }
189 if (priv->data->eint_detect_mode == 0x4) {
190 /* enable eint0cen */
191 if (priv->caps & ACCDET_PMIC_EINT0) {
192 /* enable eint0cen */
193 regmap_update_bits(map: priv->regmap,
194 ACCDET_DA_STABLE_ADDR,
195 ACCDET_EINT0_CEN_STABLE_MASK_SFT,
196 BIT(ACCDET_EINT0_CEN_STABLE_SFT));
197 } else if (priv->caps & ACCDET_PMIC_EINT1) {
198 /* enable eint1cen */
199 regmap_update_bits(map: priv->regmap,
200 ACCDET_DA_STABLE_ADDR,
201 ACCDET_EINT1_CEN_STABLE_MASK_SFT,
202 BIT(ACCDET_EINT1_CEN_STABLE_SFT));
203 }
204 }
205
206 if (priv->data->eint_detect_mode != 0x1) {
207 if (priv->caps & ACCDET_PMIC_EINT0) {
208 /* enable inverter */
209 regmap_update_bits(map: priv->regmap,
210 ACCDET_EINT0_INVERTER_SW_EN_ADDR,
211 ACCDET_EINT0_INVERTER_SW_EN_MASK_SFT,
212 BIT(ACCDET_EINT0_INVERTER_SW_EN_SFT));
213 } else if (priv->caps & ACCDET_PMIC_EINT1) {
214 /* enable inverter */
215 regmap_update_bits(map: priv->regmap,
216 ACCDET_EINT1_INVERTER_SW_EN_ADDR,
217 ACCDET_EINT1_INVERTER_SW_EN_MASK_SFT,
218 BIT(ACCDET_EINT1_INVERTER_SW_EN_SFT));
219 }
220 }
221}
222
223static void recover_eint_setting(struct mt6359_accdet *priv)
224{
225 if (priv->jd_sts == M_PLUG_OUT) {
226 recover_eint_analog_setting(priv);
227 recover_eint_digital_setting(priv);
228 }
229}
230
231static void mt6359_accdet_recover_jd_setting(struct mt6359_accdet *priv)
232{
233 int ret;
234 unsigned int value = 0;
235
236 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
237 ACCDET_IRQ_CLR_MASK_SFT, BIT(ACCDET_IRQ_CLR_SFT));
238 usleep_range(min: 200, max: 300);
239 ret = regmap_read_poll_timeout(priv->regmap,
240 ACCDET_IRQ_ADDR,
241 value,
242 (value & ACCDET_IRQ_MASK_SFT) == 0,
243 0,
244 1000);
245 if (ret)
246 dev_warn(priv->dev, "%s(), ret %d\n", __func__, ret);
247 /* clear accdet int, modify for fix interrupt trigger twice error */
248 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
249 ACCDET_IRQ_CLR_MASK_SFT, val: 0);
250 regmap_update_bits(map: priv->regmap, RG_INT_STATUS_ACCDET_ADDR,
251 RG_INT_STATUS_ACCDET_MASK_SFT,
252 BIT(RG_INT_STATUS_ACCDET_SFT));
253
254 /* recover accdet debounce0,3 */
255 accdet_set_debounce(priv, state: accdet_state000,
256 debounce: priv->data->pwm_deb->debounce0);
257 accdet_set_debounce(priv, state: accdet_state001,
258 debounce: priv->data->pwm_deb->debounce1);
259 accdet_set_debounce(priv, state: accdet_state011,
260 debounce: priv->data->pwm_deb->debounce3);
261
262 priv->jack_type = 0;
263 priv->btn_type = 0;
264 priv->accdet_status = 0x3;
265 mt6359_accdet_jack_report(priv);
266}
267
268static void accdet_set_debounce(struct mt6359_accdet *priv, int state,
269 unsigned int debounce)
270{
271 switch (state) {
272 case accdet_state000:
273 regmap_write(map: priv->regmap, ACCDET_DEBOUNCE0_ADDR, val: debounce);
274 break;
275 case accdet_state001:
276 regmap_write(map: priv->regmap, ACCDET_DEBOUNCE1_ADDR, val: debounce);
277 break;
278 case accdet_state010:
279 regmap_write(map: priv->regmap, ACCDET_DEBOUNCE2_ADDR, val: debounce);
280 break;
281 case accdet_state011:
282 regmap_write(map: priv->regmap, ACCDET_DEBOUNCE3_ADDR, val: debounce);
283 break;
284 case accdet_auxadc:
285 regmap_write(map: priv->regmap,
286 ACCDET_CONNECT_AUXADC_TIME_DIG_ADDR, val: debounce);
287 break;
288 case eint_state000:
289 regmap_update_bits(map: priv->regmap, ACCDET_EINT_DEBOUNCE0_ADDR,
290 mask: 0xF << ACCDET_EINT_DEBOUNCE0_SFT,
291 val: debounce << ACCDET_EINT_DEBOUNCE0_SFT);
292 break;
293 case eint_state001:
294 regmap_update_bits(map: priv->regmap, ACCDET_EINT_DEBOUNCE1_ADDR,
295 mask: 0xF << ACCDET_EINT_DEBOUNCE1_SFT,
296 val: debounce << ACCDET_EINT_DEBOUNCE1_SFT);
297 break;
298 case eint_state010:
299 regmap_update_bits(map: priv->regmap, ACCDET_EINT_DEBOUNCE2_ADDR,
300 mask: 0xF << ACCDET_EINT_DEBOUNCE2_SFT,
301 val: debounce << ACCDET_EINT_DEBOUNCE2_SFT);
302 break;
303 case eint_state011:
304 regmap_update_bits(map: priv->regmap, ACCDET_EINT_DEBOUNCE3_ADDR,
305 mask: 0xF << ACCDET_EINT_DEBOUNCE3_SFT,
306 val: debounce << ACCDET_EINT_DEBOUNCE3_SFT);
307 break;
308 case eint_inverter_state000:
309 regmap_write(map: priv->regmap, ACCDET_EINT_INVERTER_DEBOUNCE_ADDR,
310 val: debounce);
311 break;
312 default:
313 dev_warn(priv->dev, "Error: %s error state (%d)\n", __func__,
314 state);
315 break;
316 }
317}
318
319static void mt6359_accdet_jack_report(struct mt6359_accdet *priv)
320{
321 int report = 0;
322
323 if (!priv->jack)
324 return;
325
326 report = priv->jack_type | priv->btn_type;
327 snd_soc_jack_report(jack: priv->jack, status: report, MT6359_ACCDET_JACK_MASK);
328}
329
330static unsigned int check_button(struct mt6359_accdet *priv, unsigned int v)
331{
332 if (priv->caps & ACCDET_FOUR_KEY) {
333 if (v < priv->data->four_key.down &&
334 v >= priv->data->four_key.up)
335 priv->btn_type = SND_JACK_BTN_1;
336 if (v < priv->data->four_key.up &&
337 v >= priv->data->four_key.voice)
338 priv->btn_type = SND_JACK_BTN_2;
339 if (v < priv->data->four_key.voice &&
340 v >= priv->data->four_key.mid)
341 priv->btn_type = SND_JACK_BTN_3;
342 if (v < priv->data->four_key.mid)
343 priv->btn_type = SND_JACK_BTN_0;
344 } else {
345 if (v < priv->data->three_key.down &&
346 v >= priv->data->three_key.up)
347 priv->btn_type = SND_JACK_BTN_1;
348 if (v < priv->data->three_key.up &&
349 v >= priv->data->three_key.mid)
350 priv->btn_type = SND_JACK_BTN_2;
351 if (v < priv->data->three_key.mid)
352 priv->btn_type = SND_JACK_BTN_0;
353 }
354 return 0;
355}
356
357static void is_key_pressed(struct mt6359_accdet *priv, bool pressed)
358{
359 priv->btn_type = priv->jack_type & ~MT6359_ACCDET_BTN_MASK;
360
361 if (pressed)
362 check_button(priv, v: priv->cali_voltage);
363}
364
365static inline void check_jack_btn_type(struct mt6359_accdet *priv)
366{
367 unsigned int val = 0;
368
369 regmap_read(map: priv->regmap, ACCDET_MEM_IN_ADDR, val: &val);
370
371 priv->accdet_status =
372 (val >> ACCDET_STATE_MEM_IN_OFFSET) & ACCDET_STATE_AB_MASK;
373
374 switch (priv->accdet_status) {
375 case 0:
376 if (priv->jack_type == SND_JACK_HEADSET)
377 is_key_pressed(priv, pressed: true);
378 else
379 priv->jack_type = SND_JACK_HEADPHONE;
380 break;
381 case 1:
382 if (priv->jack_type == SND_JACK_HEADSET) {
383 is_key_pressed(priv, pressed: false);
384 } else {
385 priv->jack_type = SND_JACK_HEADSET;
386 accdet_set_debounce(priv, state: eint_state011, debounce: 0x1);
387 }
388 break;
389 case 3:
390 default:
391 priv->jack_type = 0;
392 break;
393 }
394}
395
396static void mt6359_accdet_work(struct work_struct *work)
397{
398 struct mt6359_accdet *priv =
399 container_of(work, struct mt6359_accdet, accdet_work);
400
401 mutex_lock(&priv->res_lock);
402 priv->pre_accdet_status = priv->accdet_status;
403 check_jack_btn_type(priv);
404
405 if (priv->jack_plugged &&
406 priv->pre_accdet_status != priv->accdet_status)
407 mt6359_accdet_jack_report(priv);
408 mutex_unlock(lock: &priv->res_lock);
409}
410
411static void mt6359_accdet_jd_work(struct work_struct *work)
412{
413 int ret;
414 unsigned int value = 0;
415
416 struct mt6359_accdet *priv =
417 container_of(work, struct mt6359_accdet, jd_work);
418
419 mutex_lock(&priv->res_lock);
420 if (priv->jd_sts == M_PLUG_IN) {
421 priv->jack_plugged = true;
422
423 /* set and clear initial bit every eint interrupt */
424 regmap_update_bits(map: priv->regmap, ACCDET_SEQ_INIT_ADDR,
425 ACCDET_SEQ_INIT_MASK_SFT,
426 BIT(ACCDET_SEQ_INIT_SFT));
427 regmap_update_bits(map: priv->regmap, ACCDET_SEQ_INIT_ADDR,
428 ACCDET_SEQ_INIT_MASK_SFT, val: 0);
429 ret = regmap_read_poll_timeout(priv->regmap,
430 ACCDET_SEQ_INIT_ADDR,
431 value,
432 (value & ACCDET_SEQ_INIT_MASK_SFT) == 0,
433 0,
434 1000);
435 if (ret)
436 dev_err(priv->dev, "%s(), ret %d\n", __func__, ret);
437
438 /* enable ACCDET unit */
439 regmap_update_bits(map: priv->regmap, ACCDET_SW_EN_ADDR,
440 ACCDET_SW_EN_MASK_SFT, BIT(ACCDET_SW_EN_SFT));
441 } else if (priv->jd_sts == M_PLUG_OUT) {
442 priv->jack_plugged = false;
443
444 accdet_set_debounce(priv, state: accdet_state011,
445 debounce: priv->data->pwm_deb->debounce3);
446 regmap_update_bits(map: priv->regmap, ACCDET_SW_EN_ADDR,
447 ACCDET_SW_EN_MASK_SFT, val: 0);
448 mt6359_accdet_recover_jd_setting(priv);
449 }
450
451 if (priv->caps & ACCDET_PMIC_EINT_IRQ)
452 recover_eint_setting(priv);
453 mutex_unlock(lock: &priv->res_lock);
454}
455
456static irqreturn_t mt6359_accdet_irq(int irq, void *data)
457{
458 struct mt6359_accdet *priv = data;
459 unsigned int irq_val = 0, val = 0, value = 0;
460 int ret;
461
462 mutex_lock(&priv->res_lock);
463 regmap_read(map: priv->regmap, ACCDET_IRQ_ADDR, val: &irq_val);
464
465 if (irq_val & ACCDET_IRQ_MASK_SFT) {
466 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
467 ACCDET_IRQ_CLR_MASK_SFT,
468 BIT(ACCDET_IRQ_CLR_SFT));
469 ret = regmap_read_poll_timeout(priv->regmap,
470 ACCDET_IRQ_ADDR,
471 value,
472 (value & ACCDET_IRQ_MASK_SFT) == 0,
473 0,
474 1000);
475 if (ret) {
476 dev_err(priv->dev, "%s(), ret %d\n", __func__, ret);
477 mutex_unlock(lock: &priv->res_lock);
478 return IRQ_NONE;
479 }
480 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
481 ACCDET_IRQ_CLR_MASK_SFT, val: 0);
482 regmap_update_bits(map: priv->regmap, RG_INT_STATUS_ACCDET_ADDR,
483 RG_INT_STATUS_ACCDET_MASK_SFT,
484 BIT(RG_INT_STATUS_ACCDET_SFT));
485
486 queue_work(wq: priv->accdet_workqueue, work: &priv->accdet_work);
487 } else {
488 if (irq_val & ACCDET_EINT0_IRQ_MASK_SFT) {
489 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
490 ACCDET_EINT0_IRQ_CLR_MASK_SFT,
491 BIT(ACCDET_EINT0_IRQ_CLR_SFT));
492 ret = regmap_read_poll_timeout(priv->regmap,
493 ACCDET_IRQ_ADDR,
494 value,
495 (value & ACCDET_EINT0_IRQ_MASK_SFT) == 0,
496 0,
497 1000);
498 if (ret) {
499 dev_err(priv->dev, "%s(), ret %d\n", __func__,
500 ret);
501 mutex_unlock(lock: &priv->res_lock);
502 return IRQ_NONE;
503 }
504 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
505 ACCDET_EINT0_IRQ_CLR_MASK_SFT, val: 0);
506 regmap_update_bits(map: priv->regmap,
507 RG_INT_STATUS_ACCDET_ADDR,
508 RG_INT_STATUS_ACCDET_EINT0_MASK_SFT,
509 BIT(RG_INT_STATUS_ACCDET_EINT0_SFT));
510 }
511 if (irq_val & ACCDET_EINT1_IRQ_MASK_SFT) {
512 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
513 ACCDET_EINT1_IRQ_CLR_MASK_SFT,
514 BIT(ACCDET_EINT1_IRQ_CLR_SFT));
515 ret = regmap_read_poll_timeout(priv->regmap,
516 ACCDET_IRQ_ADDR,
517 value,
518 (value & ACCDET_EINT1_IRQ_MASK_SFT) == 0,
519 0,
520 1000);
521 if (ret) {
522 dev_err(priv->dev, "%s(), ret %d\n", __func__,
523 ret);
524 mutex_unlock(lock: &priv->res_lock);
525 return IRQ_NONE;
526 }
527 regmap_update_bits(map: priv->regmap, ACCDET_IRQ_ADDR,
528 ACCDET_EINT1_IRQ_CLR_MASK_SFT, val: 0);
529 regmap_update_bits(map: priv->regmap,
530 RG_INT_STATUS_ACCDET_ADDR,
531 RG_INT_STATUS_ACCDET_EINT1_MASK_SFT,
532 BIT(RG_INT_STATUS_ACCDET_EINT1_SFT));
533 }
534 /* get jack detection status */
535 regmap_read(map: priv->regmap, ACCDET_EINT0_MEM_IN_ADDR, val: &val);
536 priv->jd_sts = ((val >> ACCDET_EINT0_MEM_IN_SFT) &
537 ACCDET_EINT0_MEM_IN_MASK);
538 /* adjust eint digital/analog setting */
539 mt6359_accdet_jd_setting(priv);
540
541 queue_work(wq: priv->jd_workqueue, work: &priv->jd_work);
542 }
543 mutex_unlock(lock: &priv->res_lock);
544
545 return IRQ_HANDLED;
546}
547
548static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv)
549{
550 int ret;
551 struct device *dev = priv->dev;
552 struct device_node *node = NULL;
553 int pwm_deb[15] = {0};
554 unsigned int tmp = 0;
555
556 node = of_get_child_by_name(node: dev->parent->of_node, name: "accdet");
557 if (!node)
558 return -EINVAL;
559
560 ret = of_property_read_u32(np: node, propname: "mediatek,mic-vol",
561 out_value: &priv->data->mic_vol);
562 if (ret)
563 priv->data->mic_vol = 8;
564
565 ret = of_property_read_u32(np: node, propname: "mediatek,plugout-debounce",
566 out_value: &priv->data->plugout_deb);
567 if (ret)
568 priv->data->plugout_deb = 1;
569
570 ret = of_property_read_u32(np: node, propname: "mediatek,mic-mode",
571 out_value: &priv->data->mic_mode);
572 if (ret)
573 priv->data->mic_mode = 2;
574
575 ret = of_property_read_u32_array(np: node, propname: "mediatek,pwm-deb-setting",
576 out_values: pwm_deb, ARRAY_SIZE(pwm_deb));
577 /* debounce8(auxadc debounce) is default, needn't get from dts */
578 if (!ret)
579 memcpy(priv->data->pwm_deb, pwm_deb, sizeof(pwm_deb));
580
581 ret = of_property_read_u32(np: node, propname: "mediatek,eint-level-pol",
582 out_value: &priv->data->eint_pol);
583 if (ret)
584 priv->data->eint_pol = 8;
585
586 ret = of_property_read_u32(np: node, propname: "mediatek,eint-use-ap", out_value: &tmp);
587 if (ret)
588 tmp = 0;
589 if (tmp == 0)
590 priv->caps |= ACCDET_PMIC_EINT_IRQ;
591 else if (tmp == 1)
592 priv->caps |= ACCDET_AP_GPIO_EINT;
593
594 ret = of_property_read_u32(np: node, propname: "mediatek,eint-detect-mode",
595 out_value: &priv->data->eint_detect_mode);
596 if (ret) {
597 /* eint detection mode equals to EINT HW Mode */
598 priv->data->eint_detect_mode = 0x4;
599 }
600
601 ret = of_property_read_u32(np: node, propname: "mediatek,eint-num", out_value: &tmp);
602 if (ret)
603 tmp = 0;
604 if (tmp == 0)
605 priv->caps |= ACCDET_PMIC_EINT0;
606 else if (tmp == 1)
607 priv->caps |= ACCDET_PMIC_EINT1;
608 else if (tmp == 2)
609 priv->caps |= ACCDET_PMIC_BI_EINT;
610
611 ret = of_property_read_u32(np: node, propname: "mediatek,eint-trig-mode",
612 out_value: &tmp);
613 if (ret)
614 tmp = 0;
615 if (tmp == 0)
616 priv->caps |= ACCDET_PMIC_GPIO_TRIG_EINT;
617 else if (tmp == 1)
618 priv->caps |= ACCDET_PMIC_INVERTER_TRIG_EINT;
619
620 ret = of_property_read_u32(np: node, propname: "mediatek,eint-use-ext-res",
621 out_value: &priv->data->eint_use_ext_res);
622 if (ret) {
623 /* eint use internal resister */
624 priv->data->eint_use_ext_res = 0x0;
625 }
626
627 ret = of_property_read_u32(np: node, propname: "mediatek,eint-comp-vth",
628 out_value: &priv->data->eint_comp_vth);
629 if (ret)
630 priv->data->eint_comp_vth = 0x0;
631
632 ret = of_property_read_u32(np: node, propname: "mediatek,key-mode", out_value: &tmp);
633 if (ret)
634 tmp = 0;
635 if (tmp == 0) {
636 int three_key[4];
637
638 priv->caps |= ACCDET_THREE_KEY;
639 ret = of_property_read_u32_array(np: node,
640 propname: "mediatek,three-key-thr",
641 out_values: three_key,
642 ARRAY_SIZE(three_key));
643 if (!ret)
644 memcpy(&priv->data->three_key, three_key + 1,
645 sizeof(struct three_key_threshold));
646 } else if (tmp == 1) {
647 int four_key[5];
648
649 priv->caps |= ACCDET_FOUR_KEY;
650 ret = of_property_read_u32_array(np: node,
651 propname: "mediatek,four-key-thr",
652 out_values: four_key,
653 ARRAY_SIZE(four_key));
654 if (!ret) {
655 memcpy(&priv->data->four_key, four_key + 1,
656 sizeof(struct four_key_threshold));
657 } else {
658 dev_warn(priv->dev,
659 "accdet no 4-key-thrsh dts, use efuse\n");
660 }
661 } else if (tmp == 2) {
662 int three_key[4];
663
664 priv->caps |= ACCDET_TRI_KEY_CDD;
665 ret = of_property_read_u32_array(np: node,
666 propname: "mediatek,tri-key-cdd-thr",
667 out_values: three_key,
668 ARRAY_SIZE(three_key));
669 if (!ret)
670 memcpy(&priv->data->three_key, three_key + 1,
671 sizeof(struct three_key_threshold));
672 }
673
674 of_node_put(node);
675 dev_warn(priv->dev, "accdet caps=%x\n", priv->caps);
676
677 return 0;
678}
679
680static void config_digital_init_by_mode(struct mt6359_accdet *priv)
681{
682 /* enable eint cmpmem pwm */
683 regmap_write(map: priv->regmap, ACCDET_EINT_CMPMEN_PWM_THRESH_ADDR,
684 val: (priv->data->pwm_deb->eint_pwm_width << 4 |
685 priv->data->pwm_deb->eint_pwm_thresh));
686 /* DA signal stable */
687 if (priv->caps & ACCDET_PMIC_EINT0) {
688 regmap_write(map: priv->regmap, ACCDET_DA_STABLE_ADDR,
689 ACCDET_EINT0_STABLE_VAL);
690 } else if (priv->caps & ACCDET_PMIC_EINT1) {
691 regmap_write(map: priv->regmap, ACCDET_DA_STABLE_ADDR,
692 ACCDET_EINT1_STABLE_VAL);
693 }
694 /* after receive n+1 number, interrupt issued. */
695 regmap_update_bits(map: priv->regmap, ACCDET_EINT_M_PLUG_IN_NUM_ADDR,
696 ACCDET_EINT_M_PLUG_IN_NUM_MASK_SFT,
697 BIT(ACCDET_EINT_M_PLUG_IN_NUM_SFT));
698 /* setting HW mode, enable digital fast discharge
699 * if use EINT0 & EINT1 detection, please modify
700 * ACCDET_HWMODE_EN_ADDR[2:1]
701 */
702 regmap_write(map: priv->regmap, ACCDET_HWMODE_EN_ADDR, val: 0x100);
703
704 regmap_update_bits(map: priv->regmap, ACCDET_EINT_M_DETECT_EN_ADDR,
705 ACCDET_EINT_M_DETECT_EN_MASK_SFT, val: 0);
706
707 /* enable PWM */
708 regmap_write(map: priv->regmap, ACCDET_CMP_PWM_EN_ADDR, val: 0x67);
709 /* enable inverter detection */
710 if (priv->data->eint_detect_mode == 0x1) {
711 /* disable inverter detection */
712 if (priv->caps & ACCDET_PMIC_EINT0) {
713 regmap_update_bits(map: priv->regmap,
714 ACCDET_EINT0_INVERTER_SW_EN_ADDR,
715 ACCDET_EINT0_INVERTER_SW_EN_MASK_SFT,
716 val: 0);
717 } else if (priv->caps & ACCDET_PMIC_EINT1) {
718 regmap_update_bits(map: priv->regmap,
719 ACCDET_EINT1_INVERTER_SW_EN_ADDR,
720 ACCDET_EINT1_INVERTER_SW_EN_MASK_SFT,
721 val: 0);
722 }
723 } else {
724 if (priv->caps & ACCDET_PMIC_EINT0) {
725 regmap_update_bits(map: priv->regmap,
726 ACCDET_EINT0_INVERTER_SW_EN_ADDR,
727 ACCDET_EINT0_INVERTER_SW_EN_MASK_SFT,
728 BIT(ACCDET_EINT0_INVERTER_SW_EN_SFT));
729 } else if (priv->caps & ACCDET_PMIC_EINT1) {
730 regmap_update_bits(map: priv->regmap,
731 ACCDET_EINT1_INVERTER_SW_EN_ADDR,
732 ACCDET_EINT1_INVERTER_SW_EN_MASK_SFT,
733 BIT(ACCDET_EINT1_INVERTER_SW_EN_SFT));
734 }
735 }
736}
737
738static void config_eint_init_by_mode(struct mt6359_accdet *priv)
739{
740 unsigned int val = 0;
741
742 if (priv->caps & ACCDET_PMIC_EINT0) {
743 regmap_update_bits(map: priv->regmap, RG_EINT0EN_ADDR,
744 RG_EINT0EN_MASK_SFT, BIT(RG_EINT0EN_SFT));
745 } else if (priv->caps & ACCDET_PMIC_EINT1) {
746 regmap_update_bits(map: priv->regmap, RG_EINT1EN_ADDR,
747 RG_EINT1EN_MASK_SFT, BIT(RG_EINT1EN_SFT));
748 }
749 /* ESD switches on */
750 regmap_update_bits(map: priv->regmap, RG_ACCDETSPARE_ADDR,
751 mask: 1 << 8, val: 1 << 8);
752 /* before playback, set NCP pull low before nagative voltage */
753 regmap_update_bits(map: priv->regmap, RG_NCP_PDDIS_EN_ADDR,
754 RG_NCP_PDDIS_EN_MASK_SFT, BIT(RG_NCP_PDDIS_EN_SFT));
755
756 if (priv->data->eint_detect_mode == 0x1 ||
757 priv->data->eint_detect_mode == 0x2 ||
758 priv->data->eint_detect_mode == 0x3) {
759 if (priv->data->eint_use_ext_res == 0x1) {
760 if (priv->caps & ACCDET_PMIC_EINT0) {
761 regmap_update_bits(map: priv->regmap,
762 RG_EINT0CONFIGACCDET_ADDR,
763 RG_EINT0CONFIGACCDET_MASK_SFT,
764 val: 0);
765 } else if (priv->caps & ACCDET_PMIC_EINT1) {
766 regmap_update_bits(map: priv->regmap,
767 RG_EINT1CONFIGACCDET_ADDR,
768 RG_EINT1CONFIGACCDET_MASK_SFT,
769 val: 0);
770 }
771 } else {
772 if (priv->caps & ACCDET_PMIC_EINT0) {
773 regmap_update_bits(map: priv->regmap,
774 RG_EINT0CONFIGACCDET_ADDR,
775 RG_EINT0CONFIGACCDET_MASK_SFT,
776 BIT(RG_EINT0CONFIGACCDET_SFT));
777 } else if (priv->caps & ACCDET_PMIC_EINT1) {
778 regmap_update_bits(map: priv->regmap,
779 RG_EINT1CONFIGACCDET_ADDR,
780 RG_EINT1CONFIGACCDET_MASK_SFT,
781 BIT(RG_EINT1CONFIGACCDET_SFT));
782 }
783 }
784 }
785
786 if (priv->data->eint_detect_mode != 0x1) {
787 /* current detect set 0.25uA */
788 regmap_update_bits(map: priv->regmap, RG_ACCDETSPARE_ADDR,
789 mask: 0x3 << RG_ACCDETSPARE_SFT,
790 val: 0x3 << RG_ACCDETSPARE_SFT);
791 }
792 regmap_write(map: priv->regmap, RG_EINTCOMPVTH_ADDR,
793 val: val | priv->data->eint_comp_vth << RG_EINTCOMPVTH_SFT);
794}
795
796static void mt6359_accdet_init(struct mt6359_accdet *priv)
797{
798 unsigned int reg = 0;
799
800 regmap_update_bits(map: priv->regmap, ACCDET_SEQ_INIT_ADDR,
801 ACCDET_SEQ_INIT_MASK_SFT, BIT(ACCDET_SEQ_INIT_SFT));
802 mdelay(2);
803 regmap_update_bits(map: priv->regmap, ACCDET_SEQ_INIT_ADDR,
804 ACCDET_SEQ_INIT_MASK_SFT, val: 0);
805 mdelay(1);
806 /* init the debounce time (debounce/32768)sec */
807 accdet_set_debounce(priv, state: accdet_state000,
808 debounce: priv->data->pwm_deb->debounce0);
809 accdet_set_debounce(priv, state: accdet_state001,
810 debounce: priv->data->pwm_deb->debounce1);
811 accdet_set_debounce(priv, state: accdet_state011,
812 debounce: priv->data->pwm_deb->debounce3);
813 accdet_set_debounce(priv, state: accdet_auxadc,
814 debounce: priv->data->pwm_deb->debounce4);
815
816 accdet_set_debounce(priv, state: eint_state000,
817 debounce: priv->data->pwm_deb->eint_debounce0);
818 accdet_set_debounce(priv, state: eint_state001,
819 debounce: priv->data->pwm_deb->eint_debounce1);
820 accdet_set_debounce(priv, state: eint_state011,
821 debounce: priv->data->pwm_deb->eint_debounce3);
822 accdet_set_debounce(priv, state: eint_inverter_state000,
823 debounce: priv->data->pwm_deb->eint_inverter_debounce);
824
825 regmap_update_bits(map: priv->regmap, RG_ACCDET_RST_ADDR,
826 RG_ACCDET_RST_MASK_SFT, BIT(RG_ACCDET_RST_SFT));
827 regmap_update_bits(map: priv->regmap, RG_ACCDET_RST_ADDR,
828 RG_ACCDET_RST_MASK_SFT, val: 0);
829
830 /* clear high micbias1 voltage setting */
831 regmap_update_bits(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
832 mask: 0x3 << RG_AUDMICBIAS1HVEN_SFT, val: 0);
833 regmap_update_bits(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
834 mask: 0x7 << RG_AUDMICBIAS1VREF_SFT, val: 0);
835
836 /* init pwm frequency, duty & rise/falling delay */
837 regmap_write(map: priv->regmap, ACCDET_PWM_WIDTH_ADDR,
838 REGISTER_VAL(priv->data->pwm_deb->pwm_width));
839 regmap_write(map: priv->regmap, ACCDET_PWM_THRESH_ADDR,
840 REGISTER_VAL(priv->data->pwm_deb->pwm_thresh));
841 regmap_write(map: priv->regmap, ACCDET_RISE_DELAY_ADDR,
842 val: (priv->data->pwm_deb->fall_delay << 15 |
843 priv->data->pwm_deb->rise_delay));
844
845 regmap_read(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR, val: &reg);
846 if (priv->data->mic_vol <= 7) {
847 /* micbias1 <= 2.7V */
848 regmap_write(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
849 val: reg | (priv->data->mic_vol << RG_AUDMICBIAS1VREF_SFT) |
850 RG_AUDMICBIAS1LOWPEN_MASK_SFT);
851 } else if (priv->data->mic_vol == 8) {
852 /* micbias1 = 2.8v */
853 regmap_write(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
854 val: reg | (3 << RG_AUDMICBIAS1HVEN_SFT) |
855 RG_AUDMICBIAS1LOWPEN_MASK_SFT);
856 } else if (priv->data->mic_vol == 9) {
857 /* micbias1 = 2.85v */
858 regmap_write(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
859 val: reg | (1 << RG_AUDMICBIAS1HVEN_SFT) |
860 RG_AUDMICBIAS1LOWPEN_MASK_SFT);
861 }
862 /* mic mode setting */
863 regmap_read(map: priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR, val: &reg);
864 if (priv->data->mic_mode == HEADSET_MODE_1) {
865 /* ACC mode*/
866 regmap_write(map: priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR,
867 val: reg | RG_ACCDET_MODE_ANA11_MODE1);
868 /* enable analog fast discharge */
869 regmap_update_bits(map: priv->regmap, RG_ANALOGFDEN_ADDR,
870 RG_ANALOGFDEN_MASK_SFT,
871 BIT(RG_ANALOGFDEN_SFT));
872 regmap_update_bits(map: priv->regmap, RG_ACCDETSPARE_ADDR,
873 mask: 0x3 << 11, val: 0x3 << 11);
874 } else if (priv->data->mic_mode == HEADSET_MODE_2) {
875 /* DCC mode Low cost mode without internal bias */
876 regmap_write(map: priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR,
877 val: reg | RG_ACCDET_MODE_ANA11_MODE2);
878 /* enable analog fast discharge */
879 regmap_update_bits(map: priv->regmap, RG_ANALOGFDEN_ADDR,
880 mask: 0x3 << RG_ANALOGFDEN_SFT,
881 val: 0x3 << RG_ANALOGFDEN_SFT);
882 } else if (priv->data->mic_mode == HEADSET_MODE_6) {
883 /* DCC mode Low cost mode with internal bias,
884 * bit8 = 1 to use internal bias
885 */
886 regmap_write(map: priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR,
887 val: reg | RG_ACCDET_MODE_ANA11_MODE6);
888 regmap_update_bits(map: priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
889 RG_AUDMICBIAS1DCSW1PEN_MASK_SFT,
890 BIT(RG_AUDMICBIAS1DCSW1PEN_SFT));
891 /* enable analog fast discharge */
892 regmap_update_bits(map: priv->regmap, RG_ANALOGFDEN_ADDR,
893 mask: 0x3 << RG_ANALOGFDEN_SFT,
894 val: 0x3 << RG_ANALOGFDEN_SFT);
895 }
896
897 if (priv->caps & ACCDET_PMIC_EINT_IRQ) {
898 config_eint_init_by_mode(priv);
899 config_digital_init_by_mode(priv);
900 }
901}
902
903int mt6359_accdet_enable_jack_detect(struct snd_soc_component *component,
904 struct snd_soc_jack *jack)
905{
906 struct mt6359_accdet *priv =
907 snd_soc_component_get_drvdata(c: component);
908
909 snd_jack_set_key(jack: jack->jack, type: SND_JACK_BTN_0, KEY_PLAYPAUSE);
910 snd_jack_set_key(jack: jack->jack, type: SND_JACK_BTN_1, KEY_VOLUMEDOWN);
911 snd_jack_set_key(jack: jack->jack, type: SND_JACK_BTN_2, KEY_VOLUMEUP);
912 snd_jack_set_key(jack: jack->jack, type: SND_JACK_BTN_3, KEY_VOICECOMMAND);
913
914 priv->jack = jack;
915
916 mt6359_accdet_jack_report(priv);
917
918 return 0;
919}
920EXPORT_SYMBOL_GPL(mt6359_accdet_enable_jack_detect);
921
922static int mt6359_accdet_probe(struct platform_device *pdev)
923{
924 struct mt6359_accdet *priv;
925 struct mt6397_chip *mt6397 = dev_get_drvdata(dev: pdev->dev.parent);
926 int ret;
927
928 dev_dbg(&pdev->dev, "%s(), dev name %s\n",
929 __func__, dev_name(&pdev->dev));
930
931 priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct mt6359_accdet),
932 GFP_KERNEL);
933 if (!priv)
934 return -ENOMEM;
935
936 priv->data = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct dts_data),
937 GFP_KERNEL);
938 if (!priv->data)
939 return -ENOMEM;
940
941 priv->data->pwm_deb = devm_kzalloc(dev: &pdev->dev,
942 size: sizeof(struct pwm_deb_settings),
943 GFP_KERNEL);
944 if (!priv->data->pwm_deb)
945 return -ENOMEM;
946
947 priv->regmap = mt6397->regmap;
948 if (IS_ERR(ptr: priv->regmap)) {
949 ret = PTR_ERR(ptr: priv->regmap);
950 dev_err(&pdev->dev, "Failed to allocate register map: %d\n",
951 ret);
952 return ret;
953 }
954 priv->dev = &pdev->dev;
955
956 ret = mt6359_accdet_parse_dt(priv);
957 if (ret) {
958 dev_err(&pdev->dev, "Failed to parse dts\n");
959 return ret;
960 }
961 mutex_init(&priv->res_lock);
962
963 priv->accdet_irq = platform_get_irq(pdev, 0);
964 if (priv->accdet_irq >= 0) {
965 ret = devm_request_threaded_irq(dev: &pdev->dev, irq: priv->accdet_irq,
966 NULL, thread_fn: mt6359_accdet_irq,
967 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
968 devname: "ACCDET_IRQ", dev_id: priv);
969 if (ret) {
970 dev_err(&pdev->dev,
971 "Failed to request IRQ: (%d)\n", ret);
972 return ret;
973 }
974 }
975
976 if (priv->caps & ACCDET_PMIC_EINT0) {
977 priv->accdet_eint0 = platform_get_irq(pdev, 1);
978 if (priv->accdet_eint0 >= 0) {
979 ret = devm_request_threaded_irq(dev: &pdev->dev,
980 irq: priv->accdet_eint0,
981 NULL, thread_fn: mt6359_accdet_irq,
982 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
983 devname: "ACCDET_EINT0", dev_id: priv);
984 if (ret) {
985 dev_err(&pdev->dev,
986 "Failed to request eint0 IRQ (%d)\n",
987 ret);
988 return ret;
989 }
990 }
991 } else if (priv->caps & ACCDET_PMIC_EINT1) {
992 priv->accdet_eint1 = platform_get_irq(pdev, 2);
993 if (priv->accdet_eint1 >= 0) {
994 ret = devm_request_threaded_irq(dev: &pdev->dev,
995 irq: priv->accdet_eint1,
996 NULL, thread_fn: mt6359_accdet_irq,
997 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
998 devname: "ACCDET_EINT1", dev_id: priv);
999 if (ret) {
1000 dev_err(&pdev->dev,
1001 "Failed to request eint1 IRQ (%d)\n",
1002 ret);
1003 return ret;
1004 }
1005 }
1006 }
1007
1008 priv->accdet_workqueue = create_singlethread_workqueue("accdet");
1009 INIT_WORK(&priv->accdet_work, mt6359_accdet_work);
1010 if (!priv->accdet_workqueue) {
1011 dev_err(&pdev->dev, "Failed to create accdet workqueue\n");
1012 ret = -1;
1013 goto err_accdet_wq;
1014 }
1015
1016 priv->jd_workqueue = create_singlethread_workqueue("mt6359_accdet_jd");
1017 INIT_WORK(&priv->jd_work, mt6359_accdet_jd_work);
1018 if (!priv->jd_workqueue) {
1019 dev_err(&pdev->dev, "Failed to create jack detect workqueue\n");
1020 ret = -1;
1021 goto err_eint_wq;
1022 }
1023
1024 platform_set_drvdata(pdev, data: priv);
1025 ret = devm_snd_soc_register_component(dev: &pdev->dev,
1026 component_driver: &mt6359_accdet_soc_driver,
1027 NULL, num_dai: 0);
1028 if (ret) {
1029 dev_err(&pdev->dev, "Failed to register component\n");
1030 return ret;
1031 }
1032
1033 priv->jd_sts = M_PLUG_OUT;
1034 priv->jack_type = 0;
1035 priv->btn_type = 0;
1036 priv->accdet_status = 0x3;
1037 mt6359_accdet_init(priv);
1038
1039 mt6359_accdet_jack_report(priv);
1040
1041 return 0;
1042
1043err_eint_wq:
1044 destroy_workqueue(wq: priv->accdet_workqueue);
1045err_accdet_wq:
1046 dev_err(&pdev->dev, "%s error. now exit.!\n", __func__);
1047 return ret;
1048}
1049
1050static struct platform_driver mt6359_accdet_driver = {
1051 .driver = {
1052 .name = "pmic-codec-accdet",
1053 },
1054 .probe = mt6359_accdet_probe,
1055};
1056
1057module_platform_driver(mt6359_accdet_driver)
1058
1059/* Module information */
1060MODULE_DESCRIPTION("MT6359 ALSA SoC codec jack driver");
1061MODULE_AUTHOR("Argus Lin <argus.lin@mediatek.com>");
1062MODULE_LICENSE("GPL v2");
1063

source code of linux/sound/soc/codecs/mt6359-accdet.c