~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/mt6359-accdet.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 
 54 static struct platform_driver mt6359_accdet_driver;
 55 static const struct snd_soc_component_driver mt6359_accdet_soc_driver;
 56 
 57 /* local function declaration */
 58 static void accdet_set_debounce(struct mt6359_accdet *priv, int state,
 59                                 unsigned int debounce);
 60 static unsigned int adjust_eint_analog_setting(struct mt6359_accdet *priv);
 61 static void config_digital_init_by_mode(struct mt6359_accdet *priv);
 62 static void config_eint_init_by_mode(struct mt6359_accdet *priv);
 63 static inline void mt6359_accdet_init(struct mt6359_accdet *priv);
 64 static unsigned int mt6359_accdet_jd_setting(struct mt6359_accdet *priv);
 65 static void mt6359_accdet_recover_jd_setting(struct mt6359_accdet *priv);
 66 static void mt6359_accdet_jack_report(struct mt6359_accdet *priv);
 67 static void recover_eint_analog_setting(struct mt6359_accdet *priv);
 68 static void recover_eint_digital_setting(struct mt6359_accdet *priv);
 69 static void recover_eint_setting(struct mt6359_accdet *priv);
 70 
 71 static 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(priv->regmap,
 77                                    RG_ACCDETSPARE_ADDR, 1 << 8, 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(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(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(priv->regmap,
 97                                            RG_EINT0HIRENB_ADDR,
 98                                            RG_EINT0HIRENB_MASK_SFT,
 99                                            BIT(RG_EINT0HIRENB_SFT));
100                 }
101         }
102         return 0;
103 }
104 
105 static 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(priv->regmap,
110                                    ACCDET_EINT0_INVERTER_SW_EN_ADDR,
111                                    ACCDET_EINT0_INVERTER_SW_EN_MASK_SFT, 0);
112         } else if (priv->caps & ACCDET_PMIC_EINT1) {
113                 /* disable inverter */
114                 regmap_update_bits(priv->regmap,
115                                    ACCDET_EINT1_INVERTER_SW_EN_ADDR,
116                                    ACCDET_EINT1_INVERTER_SW_EN_MASK_SFT, 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(priv->regmap,
123                                            ACCDET_DA_STABLE_ADDR,
124                                            ACCDET_EINT0_CEN_STABLE_MASK_SFT, 0);
125                 } else if (priv->caps & ACCDET_PMIC_EINT1) {
126                         /* set DA stable signal */
127                         regmap_update_bits(priv->regmap,
128                                            ACCDET_DA_STABLE_ADDR,
129                                            ACCDET_EINT1_CEN_STABLE_MASK_SFT, 0);
130                 }
131         }
132         return 0;
133 }
134 
135 static 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, eint_state000,
145                                     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 
153 static 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(priv->regmap, RG_ACCDETSPARE_ADDR,
159                                    1 << 8, 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(priv->regmap,
165                                            RG_EINT0CONFIGACCDET_ADDR,
166                                            RG_EINT0CONFIGACCDET_MASK_SFT, 0);
167                 } else if (priv->caps & ACCDET_PMIC_EINT1) {
168                         /* disable RG_EINT1CONFIGACCDET */
169                         regmap_update_bits(priv->regmap,
170                                            RG_EINT1CONFIGACCDET_ADDR,
171                                            RG_EINT1CONFIGACCDET_MASK_SFT, 0);
172                 }
173                 regmap_update_bits(priv->regmap, RG_EINT0HIRENB_ADDR,
174                                    RG_EINT0HIRENB_MASK_SFT, 0);
175         }
176 }
177 
178 static void recover_eint_digital_setting(struct mt6359_accdet *priv)
179 {
180         if (priv->caps & ACCDET_PMIC_EINT0) {
181                 regmap_update_bits(priv->regmap,
182                                    ACCDET_EINT0_M_SW_EN_ADDR,
183                                    ACCDET_EINT0_M_SW_EN_MASK_SFT, 0);
184         } else if (priv->caps & ACCDET_PMIC_EINT1) {
185                 regmap_update_bits(priv->regmap,
186                                    ACCDET_EINT1_M_SW_EN_ADDR,
187                                    ACCDET_EINT1_M_SW_EN_MASK_SFT, 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(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(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(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(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 
223 static 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 
231 static void mt6359_accdet_recover_jd_setting(struct mt6359_accdet *priv)
232 {
233         int ret;
234         unsigned int value = 0;
235 
236         regmap_update_bits(priv->regmap, ACCDET_IRQ_ADDR,
237                            ACCDET_IRQ_CLR_MASK_SFT, BIT(ACCDET_IRQ_CLR_SFT));
238         usleep_range(200, 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(priv->regmap, ACCDET_IRQ_ADDR,
249                            ACCDET_IRQ_CLR_MASK_SFT, 0);
250         regmap_update_bits(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, accdet_state000,
256                             priv->data->pwm_deb->debounce0);
257         accdet_set_debounce(priv, accdet_state001,
258                             priv->data->pwm_deb->debounce1);
259         accdet_set_debounce(priv, accdet_state011,
260                             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 
268 static 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(priv->regmap, ACCDET_DEBOUNCE0_ADDR, debounce);
274                 break;
275         case accdet_state001:
276                 regmap_write(priv->regmap, ACCDET_DEBOUNCE1_ADDR, debounce);
277                 break;
278         case accdet_state010:
279                 regmap_write(priv->regmap, ACCDET_DEBOUNCE2_ADDR, debounce);
280                 break;
281         case accdet_state011:
282                 regmap_write(priv->regmap, ACCDET_DEBOUNCE3_ADDR, debounce);
283                 break;
284         case accdet_auxadc:
285                 regmap_write(priv->regmap,
286                              ACCDET_CONNECT_AUXADC_TIME_DIG_ADDR, debounce);
287                 break;
288         case eint_state000:
289                 regmap_update_bits(priv->regmap, ACCDET_EINT_DEBOUNCE0_ADDR,
290                                    0xF << ACCDET_EINT_DEBOUNCE0_SFT,
291                                    debounce << ACCDET_EINT_DEBOUNCE0_SFT);
292                 break;
293         case eint_state001:
294                 regmap_update_bits(priv->regmap, ACCDET_EINT_DEBOUNCE1_ADDR,
295                                    0xF << ACCDET_EINT_DEBOUNCE1_SFT,
296                                    debounce << ACCDET_EINT_DEBOUNCE1_SFT);
297                 break;
298         case eint_state010:
299                 regmap_update_bits(priv->regmap, ACCDET_EINT_DEBOUNCE2_ADDR,
300                                    0xF << ACCDET_EINT_DEBOUNCE2_SFT,
301                                    debounce << ACCDET_EINT_DEBOUNCE2_SFT);
302                 break;
303         case eint_state011:
304                 regmap_update_bits(priv->regmap, ACCDET_EINT_DEBOUNCE3_ADDR,
305                                    0xF << ACCDET_EINT_DEBOUNCE3_SFT,
306                                    debounce << ACCDET_EINT_DEBOUNCE3_SFT);
307                 break;
308         case eint_inverter_state000:
309                 regmap_write(priv->regmap, ACCDET_EINT_INVERTER_DEBOUNCE_ADDR,
310                              debounce);
311                 break;
312         default:
313                 dev_warn(priv->dev, "Error: %s error state (%d)\n", __func__,
314                          state);
315                 break;
316         }
317 }
318 
319 static 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(priv->jack, report, MT6359_ACCDET_JACK_MASK);
328 }
329 
330 static 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 
357 static 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, priv->cali_voltage);
363 }
364 
365 static inline void check_jack_btn_type(struct mt6359_accdet *priv)
366 {
367         unsigned int val = 0;
368 
369         regmap_read(priv->regmap, ACCDET_MEM_IN_ADDR, &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, 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, false);
384                 } else {
385                         priv->jack_type = SND_JACK_HEADSET;
386                         accdet_set_debounce(priv, eint_state011, 0x1);
387                 }
388                 break;
389         case 3:
390         default:
391                 priv->jack_type = 0;
392                 break;
393         }
394 }
395 
396 static 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(&priv->res_lock);
409 }
410 
411 static 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(priv->regmap, ACCDET_SEQ_INIT_ADDR,
425                                    ACCDET_SEQ_INIT_MASK_SFT,
426                                    BIT(ACCDET_SEQ_INIT_SFT));
427                 regmap_update_bits(priv->regmap, ACCDET_SEQ_INIT_ADDR,
428                                    ACCDET_SEQ_INIT_MASK_SFT, 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(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, accdet_state011,
445                                     priv->data->pwm_deb->debounce3);
446                 regmap_update_bits(priv->regmap, ACCDET_SW_EN_ADDR,
447                                    ACCDET_SW_EN_MASK_SFT, 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(&priv->res_lock);
454 }
455 
456 static 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(priv->regmap, ACCDET_IRQ_ADDR, &irq_val);
464 
465         if (irq_val & ACCDET_IRQ_MASK_SFT) {
466                 regmap_update_bits(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(&priv->res_lock);
478                         return IRQ_NONE;
479                 }
480                 regmap_update_bits(priv->regmap, ACCDET_IRQ_ADDR,
481                                    ACCDET_IRQ_CLR_MASK_SFT, 0);
482                 regmap_update_bits(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(priv->accdet_workqueue, &priv->accdet_work);
487         } else {
488                 if (irq_val & ACCDET_EINT0_IRQ_MASK_SFT) {
489                         regmap_update_bits(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(&priv->res_lock);
502                                 return IRQ_NONE;
503                         }
504                         regmap_update_bits(priv->regmap, ACCDET_IRQ_ADDR,
505                                            ACCDET_EINT0_IRQ_CLR_MASK_SFT, 0);
506                         regmap_update_bits(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(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(&priv->res_lock);
525                                 return IRQ_NONE;
526                         }
527                         regmap_update_bits(priv->regmap, ACCDET_IRQ_ADDR,
528                                            ACCDET_EINT1_IRQ_CLR_MASK_SFT, 0);
529                         regmap_update_bits(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(priv->regmap, ACCDET_EINT0_MEM_IN_ADDR, &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(priv->jd_workqueue, &priv->jd_work);
542         }
543         mutex_unlock(&priv->res_lock);
544 
545         return IRQ_HANDLED;
546 }
547 
548 static 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(dev->parent->of_node, "accdet");
557         if (!node)
558                 return -EINVAL;
559 
560         ret = of_property_read_u32(node, "mediatek,mic-vol",
561                                    &priv->data->mic_vol);
562         if (ret)
563                 priv->data->mic_vol = 8;
564 
565         ret = of_property_read_u32(node, "mediatek,plugout-debounce",
566                                    &priv->data->plugout_deb);
567         if (ret)
568                 priv->data->plugout_deb = 1;
569 
570         ret = of_property_read_u32(node, "mediatek,mic-mode",
571                                    &priv->data->mic_mode);
572         if (ret)
573                 priv->data->mic_mode = 2;
574 
575         ret = of_property_read_u32_array(node, "mediatek,pwm-deb-setting",
576                                          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(node, "mediatek,eint-level-pol",
582                                    &priv->data->eint_pol);
583         if (ret)
584                 priv->data->eint_pol = 8;
585 
586         ret = of_property_read_u32(node, "mediatek,eint-use-ap", &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(node, "mediatek,eint-detect-mode",
595                                    &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(node, "mediatek,eint-num", &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(node, "mediatek,eint-trig-mode",
612                                    &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(node, "mediatek,eint-use-ext-res",
621                                    &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(node, "mediatek,eint-comp-vth",
628                                    &priv->data->eint_comp_vth);
629         if (ret)
630                 priv->data->eint_comp_vth = 0x0;
631 
632         ret = of_property_read_u32(node, "mediatek,key-mode", &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(node,
640                                                  "mediatek,three-key-thr",
641                                                  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(node,
651                                                  "mediatek,four-key-thr",
652                                                  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(node,
666                                                  "mediatek,tri-key-cdd-thr",
667                                                  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 
680 static void config_digital_init_by_mode(struct mt6359_accdet *priv)
681 {
682         /* enable eint cmpmem pwm */
683         regmap_write(priv->regmap, ACCDET_EINT_CMPMEN_PWM_THRESH_ADDR,
684                      (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(priv->regmap, ACCDET_DA_STABLE_ADDR,
689                              ACCDET_EINT0_STABLE_VAL);
690         } else if (priv->caps & ACCDET_PMIC_EINT1) {
691                 regmap_write(priv->regmap, ACCDET_DA_STABLE_ADDR,
692                              ACCDET_EINT1_STABLE_VAL);
693         }
694         /* after receive n+1 number, interrupt issued. */
695         regmap_update_bits(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(priv->regmap, ACCDET_HWMODE_EN_ADDR, 0x100);
703 
704         regmap_update_bits(priv->regmap, ACCDET_EINT_M_DETECT_EN_ADDR,
705                            ACCDET_EINT_M_DETECT_EN_MASK_SFT, 0);
706 
707         /* enable PWM */
708         regmap_write(priv->regmap, ACCDET_CMP_PWM_EN_ADDR, 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(priv->regmap,
714                                            ACCDET_EINT0_INVERTER_SW_EN_ADDR,
715                                            ACCDET_EINT0_INVERTER_SW_EN_MASK_SFT,
716                                            0);
717                 } else if (priv->caps & ACCDET_PMIC_EINT1) {
718                         regmap_update_bits(priv->regmap,
719                                            ACCDET_EINT1_INVERTER_SW_EN_ADDR,
720                                            ACCDET_EINT1_INVERTER_SW_EN_MASK_SFT,
721                                            0);
722                 }
723         } else {
724                 if (priv->caps & ACCDET_PMIC_EINT0) {
725                         regmap_update_bits(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(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 
738 static 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(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(priv->regmap, RG_EINT1EN_ADDR,
747                                    RG_EINT1EN_MASK_SFT, BIT(RG_EINT1EN_SFT));
748         }
749         /* ESD switches on */
750         regmap_update_bits(priv->regmap, RG_ACCDETSPARE_ADDR,
751                            1 << 8, 1 << 8);
752         /* before playback, set NCP pull low before nagative voltage */
753         regmap_update_bits(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(priv->regmap,
762                                                    RG_EINT0CONFIGACCDET_ADDR,
763                                                    RG_EINT0CONFIGACCDET_MASK_SFT,
764                                                    0);
765                         } else if (priv->caps & ACCDET_PMIC_EINT1) {
766                                 regmap_update_bits(priv->regmap,
767                                                    RG_EINT1CONFIGACCDET_ADDR,
768                                                    RG_EINT1CONFIGACCDET_MASK_SFT,
769                                                    0);
770                         }
771                 } else {
772                         if (priv->caps & ACCDET_PMIC_EINT0) {
773                                 regmap_update_bits(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(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(priv->regmap, RG_ACCDETSPARE_ADDR,
789                                    0x3 << RG_ACCDETSPARE_SFT,
790                                    0x3 << RG_ACCDETSPARE_SFT);
791         }
792         regmap_write(priv->regmap, RG_EINTCOMPVTH_ADDR,
793                      val | priv->data->eint_comp_vth << RG_EINTCOMPVTH_SFT);
794 }
795 
796 static void mt6359_accdet_init(struct mt6359_accdet *priv)
797 {
798         unsigned int reg = 0;
799 
800         regmap_update_bits(priv->regmap, ACCDET_SEQ_INIT_ADDR,
801                            ACCDET_SEQ_INIT_MASK_SFT, BIT(ACCDET_SEQ_INIT_SFT));
802         mdelay(2);
803         regmap_update_bits(priv->regmap, ACCDET_SEQ_INIT_ADDR,
804                            ACCDET_SEQ_INIT_MASK_SFT, 0);
805         mdelay(1);
806         /* init the debounce time (debounce/32768)sec */
807         accdet_set_debounce(priv, accdet_state000,
808                             priv->data->pwm_deb->debounce0);
809         accdet_set_debounce(priv, accdet_state001,
810                             priv->data->pwm_deb->debounce1);
811         accdet_set_debounce(priv, accdet_state011,
812                             priv->data->pwm_deb->debounce3);
813         accdet_set_debounce(priv, accdet_auxadc,
814                             priv->data->pwm_deb->debounce4);
815 
816         accdet_set_debounce(priv, eint_state000,
817                             priv->data->pwm_deb->eint_debounce0);
818         accdet_set_debounce(priv, eint_state001,
819                             priv->data->pwm_deb->eint_debounce1);
820         accdet_set_debounce(priv, eint_state011,
821                             priv->data->pwm_deb->eint_debounce3);
822         accdet_set_debounce(priv, eint_inverter_state000,
823                             priv->data->pwm_deb->eint_inverter_debounce);
824 
825         regmap_update_bits(priv->regmap, RG_ACCDET_RST_ADDR,
826                            RG_ACCDET_RST_MASK_SFT, BIT(RG_ACCDET_RST_SFT));
827         regmap_update_bits(priv->regmap, RG_ACCDET_RST_ADDR,
828                            RG_ACCDET_RST_MASK_SFT, 0);
829 
830         /* clear high micbias1 voltage setting */
831         regmap_update_bits(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
832                            0x3 << RG_AUDMICBIAS1HVEN_SFT, 0);
833         regmap_update_bits(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
834                            0x7 << RG_AUDMICBIAS1VREF_SFT, 0);
835 
836         /* init pwm frequency, duty & rise/falling delay */
837         regmap_write(priv->regmap, ACCDET_PWM_WIDTH_ADDR,
838                      REGISTER_VAL(priv->data->pwm_deb->pwm_width));
839         regmap_write(priv->regmap, ACCDET_PWM_THRESH_ADDR,
840                      REGISTER_VAL(priv->data->pwm_deb->pwm_thresh));
841         regmap_write(priv->regmap, ACCDET_RISE_DELAY_ADDR,
842                      (priv->data->pwm_deb->fall_delay << 15 |
843                       priv->data->pwm_deb->rise_delay));
844 
845         regmap_read(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR, &reg);
846         if (priv->data->mic_vol <= 7) {
847                 /* micbias1 <= 2.7V */
848                 regmap_write(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
849                              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(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
854                              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(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
859                              reg | (1 << RG_AUDMICBIAS1HVEN_SFT) |
860                              RG_AUDMICBIAS1LOWPEN_MASK_SFT);
861         }
862         /* mic mode setting */
863         regmap_read(priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR, &reg);
864         if (priv->data->mic_mode == HEADSET_MODE_1) {
865                 /* ACC mode*/
866                 regmap_write(priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR,
867                              reg | RG_ACCDET_MODE_ANA11_MODE1);
868                 /* enable analog fast discharge */
869                 regmap_update_bits(priv->regmap, RG_ANALOGFDEN_ADDR,
870                                    RG_ANALOGFDEN_MASK_SFT,
871                                    BIT(RG_ANALOGFDEN_SFT));
872                 regmap_update_bits(priv->regmap, RG_ACCDETSPARE_ADDR,
873                                    0x3 << 11, 0x3 << 11);
874         } else if (priv->data->mic_mode == HEADSET_MODE_2) {
875                 /* DCC mode Low cost mode without internal bias */
876                 regmap_write(priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR,
877                              reg | RG_ACCDET_MODE_ANA11_MODE2);
878                 /* enable analog fast discharge */
879                 regmap_update_bits(priv->regmap, RG_ANALOGFDEN_ADDR,
880                                    0x3 << RG_ANALOGFDEN_SFT,
881                                    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(priv->regmap, RG_AUDACCDETMICBIAS0PULLLOW_ADDR,
887                              reg | RG_ACCDET_MODE_ANA11_MODE6);
888                 regmap_update_bits(priv->regmap, RG_AUDPWDBMICBIAS1_ADDR,
889                                    RG_AUDMICBIAS1DCSW1PEN_MASK_SFT,
890                                    BIT(RG_AUDMICBIAS1DCSW1PEN_SFT));
891                 /* enable analog fast discharge */
892                 regmap_update_bits(priv->regmap, RG_ANALOGFDEN_ADDR,
893                                    0x3 << RG_ANALOGFDEN_SFT,
894                                    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 
903 int 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(component);
908 
909         snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
910         snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEDOWN);
911         snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
912         snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
913 
914         priv->jack = jack;
915 
916         mt6359_accdet_jack_report(priv);
917 
918         return 0;
919 }
920 EXPORT_SYMBOL_GPL(mt6359_accdet_enable_jack_detect);
921 
922 static int mt6359_accdet_probe(struct platform_device *pdev)
923 {
924         struct mt6359_accdet *priv;
925         struct mt6397_chip *mt6397 = dev_get_drvdata(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(&pdev->dev, sizeof(struct mt6359_accdet),
932                             GFP_KERNEL);
933         if (!priv)
934                 return -ENOMEM;
935 
936         priv->data = devm_kzalloc(&pdev->dev, sizeof(struct dts_data),
937                                   GFP_KERNEL);
938         if (!priv->data)
939                 return -ENOMEM;
940 
941         priv->data->pwm_deb = devm_kzalloc(&pdev->dev,
942                                            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(priv->regmap)) {
949                 ret = PTR_ERR(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(&pdev->dev, priv->accdet_irq,
966                                                 NULL, mt6359_accdet_irq,
967                                                 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
968                                                 "ACCDET_IRQ", 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(&pdev->dev,
980                                                         priv->accdet_eint0,
981                                                         NULL, mt6359_accdet_irq,
982                                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
983                                                         "ACCDET_EINT0", 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(&pdev->dev,
995                                                         priv->accdet_eint1,
996                                                         NULL, mt6359_accdet_irq,
997                                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
998                                                         "ACCDET_EINT1", 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, priv);
1025         ret = devm_snd_soc_register_component(&pdev->dev,
1026                                               &mt6359_accdet_soc_driver,
1027                                               NULL, 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 
1043 err_eint_wq:
1044         destroy_workqueue(priv->accdet_workqueue);
1045 err_accdet_wq:
1046         dev_err(&pdev->dev, "%s error. now exit.!\n", __func__);
1047         return ret;
1048 }
1049 
1050 static struct platform_driver mt6359_accdet_driver = {
1051         .driver = {
1052                 .name = "pmic-codec-accdet",
1053         },
1054         .probe = mt6359_accdet_probe,
1055 };
1056 
1057 module_platform_driver(mt6359_accdet_driver)
1058 
1059 /* Module information */
1060 MODULE_DESCRIPTION("MT6359 ALSA SoC codec jack driver");
1061 MODULE_AUTHOR("Argus Lin <argus.lin@mediatek.com>");
1062 MODULE_LICENSE("GPL v2");
1063 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php