Version:  2.0.40 2.2.26 2.4.37 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1

Linux/drivers/extcon/extcon-arizona.c

  1 /*
  2  * extcon-arizona.c - Extcon driver Wolfson Arizona devices
  3  *
  4  *  Copyright (C) 2012 Wolfson Microelectronics plc
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License as published by
  8  * the Free Software Foundation; either version 2 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * This program is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  * GNU General Public License for more details.
 15  */
 16 
 17 #include <linux/kernel.h>
 18 #include <linux/module.h>
 19 #include <linux/i2c.h>
 20 #include <linux/slab.h>
 21 #include <linux/interrupt.h>
 22 #include <linux/err.h>
 23 #include <linux/gpio.h>
 24 #include <linux/input.h>
 25 #include <linux/platform_device.h>
 26 #include <linux/pm_runtime.h>
 27 #include <linux/regulator/consumer.h>
 28 #include <linux/extcon.h>
 29 
 30 #include <sound/soc.h>
 31 
 32 #include <linux/mfd/arizona/core.h>
 33 #include <linux/mfd/arizona/pdata.h>
 34 #include <linux/mfd/arizona/registers.h>
 35 
 36 #define ARIZONA_MAX_MICD_RANGE 8
 37 
 38 #define ARIZONA_ACCDET_MODE_MIC 0
 39 #define ARIZONA_ACCDET_MODE_HPL 1
 40 #define ARIZONA_ACCDET_MODE_HPR 2
 41 
 42 #define ARIZONA_MICD_CLAMP_MODE_JDL      0x4
 43 #define ARIZONA_MICD_CLAMP_MODE_JDH      0x5
 44 #define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
 45 #define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
 46 
 47 #define ARIZONA_HPDET_MAX 10000
 48 
 49 #define HPDET_DEBOUNCE 500
 50 #define DEFAULT_MICD_TIMEOUT 2000
 51 
 52 #define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \
 53                          ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \
 54                          ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \
 55                          ARIZONA_MICD_LVL_7)
 56 
 57 #define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)
 58 
 59 #define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)
 60 
 61 struct arizona_extcon_info {
 62         struct device *dev;
 63         struct arizona *arizona;
 64         struct mutex lock;
 65         struct regulator *micvdd;
 66         struct input_dev *input;
 67 
 68         u16 last_jackdet;
 69 
 70         int micd_mode;
 71         const struct arizona_micd_config *micd_modes;
 72         int micd_num_modes;
 73 
 74         const struct arizona_micd_range *micd_ranges;
 75         int num_micd_ranges;
 76 
 77         int micd_timeout;
 78 
 79         bool micd_reva;
 80         bool micd_clamp;
 81 
 82         struct delayed_work hpdet_work;
 83         struct delayed_work micd_detect_work;
 84         struct delayed_work micd_timeout_work;
 85 
 86         bool hpdet_active;
 87         bool hpdet_done;
 88         bool hpdet_retried;
 89 
 90         int num_hpdet_res;
 91         unsigned int hpdet_res[3];
 92 
 93         bool mic;
 94         bool detecting;
 95         int jack_flips;
 96 
 97         int hpdet_ip;
 98 
 99         struct extcon_dev *edev;
100 };
101 
102 static const struct arizona_micd_config micd_default_modes[] = {
103         { ARIZONA_ACCDET_SRC, 1, 0 },
104         { 0,                  2, 1 },
105 };
106 
107 static const struct arizona_micd_range micd_default_ranges[] = {
108         { .max =  11, .key = BTN_0 },
109         { .max =  28, .key = BTN_1 },
110         { .max =  54, .key = BTN_2 },
111         { .max = 100, .key = BTN_3 },
112         { .max = 186, .key = BTN_4 },
113         { .max = 430, .key = BTN_5 },
114 };
115 
116 static const int arizona_micd_levels[] = {
117         3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
118         49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
119         105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
120         270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
121         1257,
122 };
123 
124 #define ARIZONA_CABLE_MECHANICAL 0
125 #define ARIZONA_CABLE_MICROPHONE 1
126 #define ARIZONA_CABLE_HEADPHONE  2
127 #define ARIZONA_CABLE_LINEOUT    3
128 
129 static const char *arizona_cable[] = {
130         "Mechanical",
131         "Microphone",
132         "Headphone",
133         "Line-out",
134         NULL,
135 };
136 
137 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
138 
139 static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info,
140                                     bool clamp)
141 {
142         struct arizona *arizona = info->arizona;
143         unsigned int mask = 0, val = 0;
144         int ret;
145 
146         switch (arizona->type) {
147         case WM5110:
148                 mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |
149                        ARIZONA_HP1L_SHRTI;
150                 if (clamp)
151                         val = ARIZONA_HP1L_SHRTO;
152                 else
153                         val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI;
154                 break;
155         default:
156                 mask = ARIZONA_RMV_SHRT_HP1L;
157                 if (clamp)
158                         val = ARIZONA_RMV_SHRT_HP1L;
159                 break;
160         };
161 
162         mutex_lock(&arizona->dapm->card->dapm_mutex);
163 
164         arizona->hpdet_clamp = clamp;
165 
166         /* Keep the HP output stages disabled while doing the clamp */
167         if (clamp) {
168                 ret = regmap_update_bits(arizona->regmap,
169                                          ARIZONA_OUTPUT_ENABLES_1,
170                                          ARIZONA_OUT1L_ENA |
171                                          ARIZONA_OUT1R_ENA, 0);
172                 if (ret != 0)
173                         dev_warn(arizona->dev,
174                                 "Failed to disable headphone outputs: %d\n",
175                                  ret);
176         }
177 
178         ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L,
179                                  mask, val);
180         if (ret != 0)
181                 dev_warn(arizona->dev, "Failed to do clamp: %d\n",
182                                  ret);
183 
184         ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R,
185                                  mask, val);
186         if (ret != 0)
187                 dev_warn(arizona->dev, "Failed to do clamp: %d\n",
188                          ret);
189 
190         /* Restore the desired state while not doing the clamp */
191         if (!clamp) {
192                 ret = regmap_update_bits(arizona->regmap,
193                                          ARIZONA_OUTPUT_ENABLES_1,
194                                          ARIZONA_OUT1L_ENA |
195                                          ARIZONA_OUT1R_ENA, arizona->hp_ena);
196                 if (ret != 0)
197                         dev_warn(arizona->dev,
198                                  "Failed to restore headphone outputs: %d\n",
199                                  ret);
200         }
201 
202         mutex_unlock(&arizona->dapm->card->dapm_mutex);
203 }
204 
205 static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
206 {
207         struct arizona *arizona = info->arizona;
208 
209         mode %= info->micd_num_modes;
210 
211         if (arizona->pdata.micd_pol_gpio > 0)
212                 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
213                                         info->micd_modes[mode].gpio);
214         regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
215                            ARIZONA_MICD_BIAS_SRC_MASK,
216                            info->micd_modes[mode].bias <<
217                            ARIZONA_MICD_BIAS_SRC_SHIFT);
218         regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
219                            ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
220 
221         info->micd_mode = mode;
222 
223         dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
224 }
225 
226 static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
227 {
228         switch (info->micd_modes[0].bias) {
229         case 1:
230                 return "MICBIAS1";
231         case 2:
232                 return "MICBIAS2";
233         case 3:
234                 return "MICBIAS3";
235         default:
236                 return "MICVDD";
237         }
238 }
239 
240 static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
241 {
242         struct arizona *arizona = info->arizona;
243         const char *widget = arizona_extcon_get_micbias(info);
244         struct snd_soc_dapm_context *dapm = arizona->dapm;
245         int ret;
246 
247         ret = snd_soc_dapm_force_enable_pin(dapm, widget);
248         if (ret != 0)
249                 dev_warn(arizona->dev, "Failed to enable %s: %d\n",
250                          widget, ret);
251 
252         snd_soc_dapm_sync(dapm);
253 
254         if (!arizona->pdata.micd_force_micbias) {
255                 ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
256                 if (ret != 0)
257                         dev_warn(arizona->dev, "Failed to disable %s: %d\n",
258                                  widget, ret);
259 
260                 snd_soc_dapm_sync(dapm);
261         }
262 }
263 
264 static void arizona_start_mic(struct arizona_extcon_info *info)
265 {
266         struct arizona *arizona = info->arizona;
267         bool change;
268         int ret;
269 
270         /* Microphone detection can't use idle mode */
271         pm_runtime_get(info->dev);
272 
273         if (info->detecting) {
274                 ret = regulator_allow_bypass(info->micvdd, false);
275                 if (ret != 0) {
276                         dev_err(arizona->dev,
277                                 "Failed to regulate MICVDD: %d\n",
278                                 ret);
279                 }
280         }
281 
282         ret = regulator_enable(info->micvdd);
283         if (ret != 0) {
284                 dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
285                         ret);
286         }
287 
288         if (info->micd_reva) {
289                 regmap_write(arizona->regmap, 0x80, 0x3);
290                 regmap_write(arizona->regmap, 0x294, 0);
291                 regmap_write(arizona->regmap, 0x80, 0x0);
292         }
293 
294         regmap_update_bits(arizona->regmap,
295                            ARIZONA_ACCESSORY_DETECT_MODE_1,
296                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
297 
298         arizona_extcon_pulse_micbias(info);
299 
300         regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
301                                  ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
302                                  &change);
303         if (!change) {
304                 regulator_disable(info->micvdd);
305                 pm_runtime_put_autosuspend(info->dev);
306         }
307 }
308 
309 static void arizona_stop_mic(struct arizona_extcon_info *info)
310 {
311         struct arizona *arizona = info->arizona;
312         const char *widget = arizona_extcon_get_micbias(info);
313         struct snd_soc_dapm_context *dapm = arizona->dapm;
314         bool change;
315         int ret;
316 
317         regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
318                                  ARIZONA_MICD_ENA, 0,
319                                  &change);
320 
321         ret = snd_soc_dapm_disable_pin(dapm, widget);
322         if (ret != 0)
323                 dev_warn(arizona->dev,
324                          "Failed to disable %s: %d\n",
325                          widget, ret);
326 
327         snd_soc_dapm_sync(dapm);
328 
329         if (info->micd_reva) {
330                 regmap_write(arizona->regmap, 0x80, 0x3);
331                 regmap_write(arizona->regmap, 0x294, 2);
332                 regmap_write(arizona->regmap, 0x80, 0x0);
333         }
334 
335         ret = regulator_allow_bypass(info->micvdd, true);
336         if (ret != 0) {
337                 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
338                         ret);
339         }
340 
341         if (change) {
342                 regulator_disable(info->micvdd);
343                 pm_runtime_mark_last_busy(info->dev);
344                 pm_runtime_put_autosuspend(info->dev);
345         }
346 }
347 
348 static struct {
349         unsigned int threshold;
350         unsigned int factor_a;
351         unsigned int factor_b;
352 } arizona_hpdet_b_ranges[] = {
353         { 100,  5528,   362464 },
354         { 169, 11084,  6186851 },
355         { 169, 11065, 65460395 },
356 };
357 
358 #define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
359 
360 static struct {
361         int min;
362         int max;
363 } arizona_hpdet_c_ranges[] = {
364         { 0,       30 },
365         { 8,      100 },
366         { 100,   1000 },
367         { 1000, 10000 },
368 };
369 
370 static int arizona_hpdet_read(struct arizona_extcon_info *info)
371 {
372         struct arizona *arizona = info->arizona;
373         unsigned int val, range;
374         int ret;
375 
376         ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
377         if (ret != 0) {
378                 dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
379                         ret);
380                 return ret;
381         }
382 
383         switch (info->hpdet_ip) {
384         case 0:
385                 if (!(val & ARIZONA_HP_DONE)) {
386                         dev_err(arizona->dev, "HPDET did not complete: %x\n",
387                                 val);
388                         return -EAGAIN;
389                 }
390 
391                 val &= ARIZONA_HP_LVL_MASK;
392                 break;
393 
394         case 1:
395                 if (!(val & ARIZONA_HP_DONE_B)) {
396                         dev_err(arizona->dev, "HPDET did not complete: %x\n",
397                                 val);
398                         return -EAGAIN;
399                 }
400 
401                 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
402                 if (ret != 0) {
403                         dev_err(arizona->dev, "Failed to read HP value: %d\n",
404                                 ret);
405                         return -EAGAIN;
406                 }
407 
408                 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
409                             &range);
410                 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
411                            >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
412 
413                 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
414                     (val < arizona_hpdet_b_ranges[range].threshold ||
415                      val >= ARIZONA_HPDET_B_RANGE_MAX)) {
416                         range++;
417                         dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
418                                 range);
419                         regmap_update_bits(arizona->regmap,
420                                            ARIZONA_HEADPHONE_DETECT_1,
421                                            ARIZONA_HP_IMPEDANCE_RANGE_MASK,
422                                            range <<
423                                            ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
424                         return -EAGAIN;
425                 }
426 
427                 /* If we go out of range report top of range */
428                 if (val < arizona_hpdet_b_ranges[range].threshold ||
429                     val >= ARIZONA_HPDET_B_RANGE_MAX) {
430                         dev_dbg(arizona->dev, "Measurement out of range\n");
431                         return ARIZONA_HPDET_MAX;
432                 }
433 
434                 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
435                         val, range);
436 
437                 val = arizona_hpdet_b_ranges[range].factor_b
438                         / ((val * 100) -
439                            arizona_hpdet_b_ranges[range].factor_a);
440                 break;
441 
442         default:
443                 dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
444                          info->hpdet_ip);
445         case 2:
446                 if (!(val & ARIZONA_HP_DONE_B)) {
447                         dev_err(arizona->dev, "HPDET did not complete: %x\n",
448                                 val);
449                         return -EAGAIN;
450                 }
451 
452                 val &= ARIZONA_HP_LVL_B_MASK;
453                 /* Convert to ohms, the value is in 0.5 ohm increments */
454                 val /= 2;
455 
456                 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
457                             &range);
458                 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
459                            >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
460 
461                 /* Skip up a range, or report? */
462                 if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
463                     (val >= arizona_hpdet_c_ranges[range].max)) {
464                         range++;
465                         dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
466                                 arizona_hpdet_c_ranges[range].min,
467                                 arizona_hpdet_c_ranges[range].max);
468                         regmap_update_bits(arizona->regmap,
469                                            ARIZONA_HEADPHONE_DETECT_1,
470                                            ARIZONA_HP_IMPEDANCE_RANGE_MASK,
471                                            range <<
472                                            ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
473                         return -EAGAIN;
474                 }
475 
476                 if (range && (val < arizona_hpdet_c_ranges[range].min)) {
477                         dev_dbg(arizona->dev, "Reporting range boundary %d\n",
478                                 arizona_hpdet_c_ranges[range].min);
479                         val = arizona_hpdet_c_ranges[range].min;
480                 }
481         }
482 
483         dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
484         return val;
485 }
486 
487 static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
488                                bool *mic)
489 {
490         struct arizona *arizona = info->arizona;
491         int id_gpio = arizona->pdata.hpdet_id_gpio;
492 
493         /*
494          * If we're using HPDET for accessory identification we need
495          * to take multiple measurements, step through them in sequence.
496          */
497         if (arizona->pdata.hpdet_acc_id) {
498                 info->hpdet_res[info->num_hpdet_res++] = *reading;
499 
500                 /* Only check the mic directly if we didn't already ID it */
501                 if (id_gpio && info->num_hpdet_res == 1) {
502                         dev_dbg(arizona->dev, "Measuring mic\n");
503 
504                         regmap_update_bits(arizona->regmap,
505                                            ARIZONA_ACCESSORY_DETECT_MODE_1,
506                                            ARIZONA_ACCDET_MODE_MASK |
507                                            ARIZONA_ACCDET_SRC,
508                                            ARIZONA_ACCDET_MODE_HPR |
509                                            info->micd_modes[0].src);
510 
511                         gpio_set_value_cansleep(id_gpio, 1);
512 
513                         regmap_update_bits(arizona->regmap,
514                                            ARIZONA_HEADPHONE_DETECT_1,
515                                            ARIZONA_HP_POLL, ARIZONA_HP_POLL);
516                         return -EAGAIN;
517                 }
518 
519                 /* OK, got both.  Now, compare... */
520                 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
521                         info->hpdet_res[0], info->hpdet_res[1]);
522 
523                 /* Take the headphone impedance for the main report */
524                 *reading = info->hpdet_res[0];
525 
526                 /* Sometimes we get false readings due to slow insert */
527                 if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
528                         dev_dbg(arizona->dev, "Retrying high impedance\n");
529                         info->num_hpdet_res = 0;
530                         info->hpdet_retried = true;
531                         arizona_start_hpdet_acc_id(info);
532                         pm_runtime_put(info->dev);
533                         return -EAGAIN;
534                 }
535 
536                 /*
537                  * If we measure the mic as high impedance
538                  */
539                 if (!id_gpio || info->hpdet_res[1] > 50) {
540                         dev_dbg(arizona->dev, "Detected mic\n");
541                         *mic = true;
542                         info->detecting = true;
543                 } else {
544                         dev_dbg(arizona->dev, "Detected headphone\n");
545                 }
546 
547                 /* Make sure everything is reset back to the real polarity */
548                 regmap_update_bits(arizona->regmap,
549                                    ARIZONA_ACCESSORY_DETECT_MODE_1,
550                                    ARIZONA_ACCDET_SRC,
551                                    info->micd_modes[0].src);
552         }
553 
554         return 0;
555 }
556 
557 static irqreturn_t arizona_hpdet_irq(int irq, void *data)
558 {
559         struct arizona_extcon_info *info = data;
560         struct arizona *arizona = info->arizona;
561         int id_gpio = arizona->pdata.hpdet_id_gpio;
562         int report = ARIZONA_CABLE_HEADPHONE;
563         int ret, reading;
564         bool mic = false;
565 
566         mutex_lock(&info->lock);
567 
568         /* If we got a spurious IRQ for some reason then ignore it */
569         if (!info->hpdet_active) {
570                 dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
571                 mutex_unlock(&info->lock);
572                 return IRQ_NONE;
573         }
574 
575         /* If the cable was removed while measuring ignore the result */
576         ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL);
577         if (ret < 0) {
578                 dev_err(arizona->dev, "Failed to check cable state: %d\n",
579                         ret);
580                 goto out;
581         } else if (!ret) {
582                 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
583                 goto done;
584         }
585 
586         ret = arizona_hpdet_read(info);
587         if (ret == -EAGAIN)
588                 goto out;
589         else if (ret < 0)
590                 goto done;
591         reading = ret;
592 
593         /* Reset back to starting range */
594         regmap_update_bits(arizona->regmap,
595                            ARIZONA_HEADPHONE_DETECT_1,
596                            ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
597                            0);
598 
599         ret = arizona_hpdet_do_id(info, &reading, &mic);
600         if (ret == -EAGAIN)
601                 goto out;
602         else if (ret < 0)
603                 goto done;
604 
605         /* Report high impedence cables as line outputs */
606         if (reading >= 5000)
607                 report = ARIZONA_CABLE_LINEOUT;
608         else
609                 report = ARIZONA_CABLE_HEADPHONE;
610 
611         ret = extcon_set_cable_state_(info->edev, report, true);
612         if (ret != 0)
613                 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
614                         ret);
615 
616 done:
617         /* Reset back to starting range */
618         regmap_update_bits(arizona->regmap,
619                            ARIZONA_HEADPHONE_DETECT_1,
620                            ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
621                            0);
622 
623         arizona_extcon_hp_clamp(info, false);
624 
625         if (id_gpio)
626                 gpio_set_value_cansleep(id_gpio, 0);
627 
628         /* Revert back to MICDET mode */
629         regmap_update_bits(arizona->regmap,
630                            ARIZONA_ACCESSORY_DETECT_MODE_1,
631                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
632 
633         /* If we have a mic then reenable MICDET */
634         if (mic || info->mic)
635                 arizona_start_mic(info);
636 
637         if (info->hpdet_active) {
638                 pm_runtime_put_autosuspend(info->dev);
639                 info->hpdet_active = false;
640         }
641 
642         info->hpdet_done = true;
643 
644 out:
645         mutex_unlock(&info->lock);
646 
647         return IRQ_HANDLED;
648 }
649 
650 static void arizona_identify_headphone(struct arizona_extcon_info *info)
651 {
652         struct arizona *arizona = info->arizona;
653         int ret;
654 
655         if (info->hpdet_done)
656                 return;
657 
658         dev_dbg(arizona->dev, "Starting HPDET\n");
659 
660         /* Make sure we keep the device enabled during the measurement */
661         pm_runtime_get(info->dev);
662 
663         info->hpdet_active = true;
664 
665         if (info->mic)
666                 arizona_stop_mic(info);
667 
668         arizona_extcon_hp_clamp(info, true);
669 
670         ret = regmap_update_bits(arizona->regmap,
671                                  ARIZONA_ACCESSORY_DETECT_MODE_1,
672                                  ARIZONA_ACCDET_MODE_MASK,
673                                  ARIZONA_ACCDET_MODE_HPL);
674         if (ret != 0) {
675                 dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
676                 goto err;
677         }
678 
679         ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
680                                  ARIZONA_HP_POLL, ARIZONA_HP_POLL);
681         if (ret != 0) {
682                 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
683                         ret);
684                 goto err;
685         }
686 
687         return;
688 
689 err:
690         regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
691                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
692 
693         /* Just report headphone */
694         ret = extcon_set_cable_state_(info->edev,
695                                       ARIZONA_CABLE_HEADPHONE, true);
696         if (ret != 0)
697                 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
698 
699         if (info->mic)
700                 arizona_start_mic(info);
701 
702         info->hpdet_active = false;
703 }
704 
705 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
706 {
707         struct arizona *arizona = info->arizona;
708         int hp_reading = 32;
709         bool mic;
710         int ret;
711 
712         dev_dbg(arizona->dev, "Starting identification via HPDET\n");
713 
714         /* Make sure we keep the device enabled during the measurement */
715         pm_runtime_get_sync(info->dev);
716 
717         info->hpdet_active = true;
718 
719         arizona_extcon_hp_clamp(info, true);
720 
721         ret = regmap_update_bits(arizona->regmap,
722                                  ARIZONA_ACCESSORY_DETECT_MODE_1,
723                                  ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
724                                  info->micd_modes[0].src |
725                                  ARIZONA_ACCDET_MODE_HPL);
726         if (ret != 0) {
727                 dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
728                 goto err;
729         }
730 
731         if (arizona->pdata.hpdet_acc_id_line) {
732                 ret = regmap_update_bits(arizona->regmap,
733                                          ARIZONA_HEADPHONE_DETECT_1,
734                                          ARIZONA_HP_POLL, ARIZONA_HP_POLL);
735                 if (ret != 0) {
736                         dev_err(arizona->dev,
737                                 "Can't start HPDETL measurement: %d\n",
738                                 ret);
739                         goto err;
740                 }
741         } else {
742                 arizona_hpdet_do_id(info, &hp_reading, &mic);
743         }
744 
745         return;
746 
747 err:
748         regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
749                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
750 
751         /* Just report headphone */
752         ret = extcon_set_cable_state_(info->edev,
753                                       ARIZONA_CABLE_HEADPHONE, true);
754         if (ret != 0)
755                 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
756 
757         info->hpdet_active = false;
758 }
759 
760 static void arizona_micd_timeout_work(struct work_struct *work)
761 {
762         struct arizona_extcon_info *info = container_of(work,
763                                                 struct arizona_extcon_info,
764                                                 micd_timeout_work.work);
765 
766         mutex_lock(&info->lock);
767 
768         dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
769         arizona_identify_headphone(info);
770 
771         info->detecting = false;
772 
773         arizona_stop_mic(info);
774 
775         mutex_unlock(&info->lock);
776 }
777 
778 static void arizona_micd_detect(struct work_struct *work)
779 {
780         struct arizona_extcon_info *info = container_of(work,
781                                                 struct arizona_extcon_info,
782                                                 micd_detect_work.work);
783         struct arizona *arizona = info->arizona;
784         unsigned int val = 0, lvl;
785         int ret, i, key;
786 
787         cancel_delayed_work_sync(&info->micd_timeout_work);
788 
789         mutex_lock(&info->lock);
790 
791         /* If the cable was removed while measuring ignore the result */
792         ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL);
793         if (ret < 0) {
794                 dev_err(arizona->dev, "Failed to check cable state: %d\n",
795                                 ret);
796                 mutex_unlock(&info->lock);
797                 return;
798         } else if (!ret) {
799                 dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
800                 mutex_unlock(&info->lock);
801                 return;
802         }
803 
804         for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
805                 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
806                 if (ret != 0) {
807                         dev_err(arizona->dev,
808                                 "Failed to read MICDET: %d\n", ret);
809                         mutex_unlock(&info->lock);
810                         return;
811                 }
812 
813                 dev_dbg(arizona->dev, "MICDET: %x\n", val);
814 
815                 if (!(val & ARIZONA_MICD_VALID)) {
816                         dev_warn(arizona->dev,
817                                  "Microphone detection state invalid\n");
818                         mutex_unlock(&info->lock);
819                         return;
820                 }
821         }
822 
823         if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
824                 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
825                 mutex_unlock(&info->lock);
826                 return;
827         }
828 
829         /* Due to jack detect this should never happen */
830         if (!(val & ARIZONA_MICD_STS)) {
831                 dev_warn(arizona->dev, "Detected open circuit\n");
832                 info->detecting = false;
833                 goto handled;
834         }
835 
836         /* If we got a high impedence we should have a headset, report it. */
837         if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
838                 arizona_identify_headphone(info);
839 
840                 ret = extcon_set_cable_state_(info->edev,
841                                               ARIZONA_CABLE_MICROPHONE, true);
842 
843                 if (ret != 0)
844                         dev_err(arizona->dev, "Headset report failed: %d\n",
845                                 ret);
846 
847                 /* Don't need to regulate for button detection */
848                 ret = regulator_allow_bypass(info->micvdd, true);
849                 if (ret != 0) {
850                         dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
851                                 ret);
852                 }
853 
854                 info->mic = true;
855                 info->detecting = false;
856                 goto handled;
857         }
858 
859         /* If we detected a lower impedence during initial startup
860          * then we probably have the wrong polarity, flip it.  Don't
861          * do this for the lowest impedences to speed up detection of
862          * plain headphones.  If both polarities report a low
863          * impedence then give up and report headphones.
864          */
865         if (info->detecting && (val & MICD_LVL_1_TO_7)) {
866                 if (info->jack_flips >= info->micd_num_modes * 10) {
867                         dev_dbg(arizona->dev, "Detected HP/line\n");
868                         arizona_identify_headphone(info);
869 
870                         info->detecting = false;
871 
872                         arizona_stop_mic(info);
873                 } else {
874                         info->micd_mode++;
875                         if (info->micd_mode == info->micd_num_modes)
876                                 info->micd_mode = 0;
877                         arizona_extcon_set_mode(info, info->micd_mode);
878 
879                         info->jack_flips++;
880                 }
881 
882                 goto handled;
883         }
884 
885         /*
886          * If we're still detecting and we detect a short then we've
887          * got a headphone.  Otherwise it's a button press.
888          */
889         if (val & MICD_LVL_0_TO_7) {
890                 if (info->mic) {
891                         dev_dbg(arizona->dev, "Mic button detected\n");
892 
893                         lvl = val & ARIZONA_MICD_LVL_MASK;
894                         lvl >>= ARIZONA_MICD_LVL_SHIFT;
895 
896                         for (i = 0; i < info->num_micd_ranges; i++)
897                                 input_report_key(info->input,
898                                                  info->micd_ranges[i].key, 0);
899 
900                         WARN_ON(!lvl);
901                         WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
902                         if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
903                                 key = info->micd_ranges[ffs(lvl) - 1].key;
904                                 input_report_key(info->input, key, 1);
905                                 input_sync(info->input);
906                         }
907 
908                 } else if (info->detecting) {
909                         dev_dbg(arizona->dev, "Headphone detected\n");
910                         info->detecting = false;
911                         arizona_stop_mic(info);
912 
913                         arizona_identify_headphone(info);
914                 } else {
915                         dev_warn(arizona->dev, "Button with no mic: %x\n",
916                                  val);
917                 }
918         } else {
919                 dev_dbg(arizona->dev, "Mic button released\n");
920                 for (i = 0; i < info->num_micd_ranges; i++)
921                         input_report_key(info->input,
922                                          info->micd_ranges[i].key, 0);
923                 input_sync(info->input);
924                 arizona_extcon_pulse_micbias(info);
925         }
926 
927 handled:
928         if (info->detecting)
929                 queue_delayed_work(system_power_efficient_wq,
930                                    &info->micd_timeout_work,
931                                    msecs_to_jiffies(info->micd_timeout));
932 
933         pm_runtime_mark_last_busy(info->dev);
934         mutex_unlock(&info->lock);
935 }
936 
937 static irqreturn_t arizona_micdet(int irq, void *data)
938 {
939         struct arizona_extcon_info *info = data;
940         struct arizona *arizona = info->arizona;
941         int debounce = arizona->pdata.micd_detect_debounce;
942 
943         cancel_delayed_work_sync(&info->micd_detect_work);
944         cancel_delayed_work_sync(&info->micd_timeout_work);
945 
946         mutex_lock(&info->lock);
947         if (!info->detecting)
948                 debounce = 0;
949         mutex_unlock(&info->lock);
950 
951         if (debounce)
952                 queue_delayed_work(system_power_efficient_wq,
953                                    &info->micd_detect_work,
954                                    msecs_to_jiffies(debounce));
955         else
956                 arizona_micd_detect(&info->micd_detect_work.work);
957 
958         return IRQ_HANDLED;
959 }
960 
961 static void arizona_hpdet_work(struct work_struct *work)
962 {
963         struct arizona_extcon_info *info = container_of(work,
964                                                 struct arizona_extcon_info,
965                                                 hpdet_work.work);
966 
967         mutex_lock(&info->lock);
968         arizona_start_hpdet_acc_id(info);
969         mutex_unlock(&info->lock);
970 }
971 
972 static irqreturn_t arizona_jackdet(int irq, void *data)
973 {
974         struct arizona_extcon_info *info = data;
975         struct arizona *arizona = info->arizona;
976         unsigned int val, present, mask;
977         bool cancelled_hp, cancelled_mic;
978         int ret, i;
979 
980         cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
981         cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
982 
983         pm_runtime_get_sync(info->dev);
984 
985         mutex_lock(&info->lock);
986 
987         if (arizona->pdata.jd_gpio5) {
988                 mask = ARIZONA_MICD_CLAMP_STS;
989                 if (arizona->pdata.jd_invert)
990                         present = ARIZONA_MICD_CLAMP_STS;
991                 else
992                         present = 0;
993         } else {
994                 mask = ARIZONA_JD1_STS;
995                 if (arizona->pdata.jd_invert)
996                         present = 0;
997                 else
998                         present = ARIZONA_JD1_STS;
999         }
1000 
1001         ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
1002         if (ret != 0) {
1003                 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
1004                         ret);
1005                 mutex_unlock(&info->lock);
1006                 pm_runtime_put_autosuspend(info->dev);
1007                 return IRQ_NONE;
1008         }
1009 
1010         val &= mask;
1011         if (val == info->last_jackdet) {
1012                 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
1013                 if (cancelled_hp)
1014                         queue_delayed_work(system_power_efficient_wq,
1015                                            &info->hpdet_work,
1016                                            msecs_to_jiffies(HPDET_DEBOUNCE));
1017 
1018                 if (cancelled_mic) {
1019                         int micd_timeout = info->micd_timeout;
1020 
1021                         queue_delayed_work(system_power_efficient_wq,
1022                                            &info->micd_timeout_work,
1023                                            msecs_to_jiffies(micd_timeout));
1024                 }
1025 
1026                 goto out;
1027         }
1028         info->last_jackdet = val;
1029 
1030         if (info->last_jackdet == present) {
1031                 dev_dbg(arizona->dev, "Detected jack\n");
1032                 ret = extcon_set_cable_state_(info->edev,
1033                                               ARIZONA_CABLE_MECHANICAL, true);
1034 
1035                 if (ret != 0)
1036                         dev_err(arizona->dev, "Mechanical report failed: %d\n",
1037                                 ret);
1038 
1039                 if (!arizona->pdata.hpdet_acc_id) {
1040                         info->detecting = true;
1041                         info->mic = false;
1042                         info->jack_flips = 0;
1043 
1044                         arizona_start_mic(info);
1045                 } else {
1046                         queue_delayed_work(system_power_efficient_wq,
1047                                            &info->hpdet_work,
1048                                            msecs_to_jiffies(HPDET_DEBOUNCE));
1049                 }
1050 
1051                 regmap_update_bits(arizona->regmap,
1052                                    ARIZONA_JACK_DETECT_DEBOUNCE,
1053                                    ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
1054         } else {
1055                 dev_dbg(arizona->dev, "Detected jack removal\n");
1056 
1057                 arizona_stop_mic(info);
1058 
1059                 info->num_hpdet_res = 0;
1060                 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1061                         info->hpdet_res[i] = 0;
1062                 info->mic = false;
1063                 info->hpdet_done = false;
1064                 info->hpdet_retried = false;
1065 
1066                 for (i = 0; i < info->num_micd_ranges; i++)
1067                         input_report_key(info->input,
1068                                          info->micd_ranges[i].key, 0);
1069                 input_sync(info->input);
1070 
1071                 ret = extcon_update_state(info->edev, 0xffffffff, 0);
1072                 if (ret != 0)
1073                         dev_err(arizona->dev, "Removal report failed: %d\n",
1074                                 ret);
1075 
1076                 regmap_update_bits(arizona->regmap,
1077                                    ARIZONA_JACK_DETECT_DEBOUNCE,
1078                                    ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1079                                    ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
1080         }
1081 
1082         if (arizona->pdata.micd_timeout)
1083                 info->micd_timeout = arizona->pdata.micd_timeout;
1084         else
1085                 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1086 
1087 out:
1088         /* Clear trig_sts to make sure DCVDD is not forced up */
1089         regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1090                      ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1091                      ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1092                      ARIZONA_JD1_FALL_TRIG_STS |
1093                      ARIZONA_JD1_RISE_TRIG_STS);
1094 
1095         mutex_unlock(&info->lock);
1096 
1097         pm_runtime_mark_last_busy(info->dev);
1098         pm_runtime_put_autosuspend(info->dev);
1099 
1100         return IRQ_HANDLED;
1101 }
1102 
1103 /* Map a level onto a slot in the register bank */
1104 static void arizona_micd_set_level(struct arizona *arizona, int index,
1105                                    unsigned int level)
1106 {
1107         int reg;
1108         unsigned int mask;
1109 
1110         reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1111 
1112         if (!(index % 2)) {
1113                 mask = 0x3f00;
1114                 level <<= 8;
1115         } else {
1116                 mask = 0x3f;
1117         }
1118 
1119         /* Program the level itself */
1120         regmap_update_bits(arizona->regmap, reg, mask, level);
1121 }
1122 
1123 static int arizona_extcon_probe(struct platform_device *pdev)
1124 {
1125         struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1126         struct arizona_pdata *pdata = &arizona->pdata;
1127         struct arizona_extcon_info *info;
1128         unsigned int val;
1129         unsigned int clamp_mode;
1130         int jack_irq_fall, jack_irq_rise;
1131         int ret, mode, i, j;
1132 
1133         if (!arizona->dapm || !arizona->dapm->card)
1134                 return -EPROBE_DEFER;
1135 
1136         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1137         if (!info)
1138                 return -ENOMEM;
1139 
1140         info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
1141         if (IS_ERR(info->micvdd)) {
1142                 ret = PTR_ERR(info->micvdd);
1143                 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
1144                 return ret;
1145         }
1146 
1147         mutex_init(&info->lock);
1148         info->arizona = arizona;
1149         info->dev = &pdev->dev;
1150         info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
1151         INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
1152         INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
1153         INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
1154         platform_set_drvdata(pdev, info);
1155 
1156         switch (arizona->type) {
1157         case WM5102:
1158                 switch (arizona->rev) {
1159                 case 0:
1160                         info->micd_reva = true;
1161                         break;
1162                 default:
1163                         info->micd_clamp = true;
1164                         info->hpdet_ip = 1;
1165                         break;
1166                 }
1167                 break;
1168         case WM5110:
1169         case WM8280:
1170                 switch (arizona->rev) {
1171                 case 0 ... 2:
1172                         break;
1173                 default:
1174                         info->micd_clamp = true;
1175                         info->hpdet_ip = 2;
1176                         break;
1177                 }
1178                 break;
1179         default:
1180                 break;
1181         }
1182 
1183         info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
1184         if (IS_ERR(info->edev)) {
1185                 dev_err(&pdev->dev, "failed to allocate extcon device\n");
1186                 return -ENOMEM;
1187         }
1188         info->edev->name = "Headset Jack";
1189 
1190         ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1191         if (ret < 0) {
1192                 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
1193                         ret);
1194                 return ret;
1195         }
1196 
1197         info->input = devm_input_allocate_device(&pdev->dev);
1198         if (!info->input) {
1199                 dev_err(arizona->dev, "Can't allocate input dev\n");
1200                 ret = -ENOMEM;
1201                 goto err_register;
1202         }
1203 
1204         info->input->name = "Headset";
1205         info->input->phys = "arizona/extcon";
1206 
1207         if (pdata->num_micd_configs) {
1208                 info->micd_modes = pdata->micd_configs;
1209                 info->micd_num_modes = pdata->num_micd_configs;
1210         } else {
1211                 info->micd_modes = micd_default_modes;
1212                 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1213         }
1214 
1215         if (arizona->pdata.micd_pol_gpio > 0) {
1216                 if (info->micd_modes[0].gpio)
1217                         mode = GPIOF_OUT_INIT_HIGH;
1218                 else
1219                         mode = GPIOF_OUT_INIT_LOW;
1220 
1221                 ret = devm_gpio_request_one(&pdev->dev,
1222                                             arizona->pdata.micd_pol_gpio,
1223                                             mode,
1224                                             "MICD polarity");
1225                 if (ret != 0) {
1226                         dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1227                                 arizona->pdata.micd_pol_gpio, ret);
1228                         goto err_register;
1229                 }
1230         }
1231 
1232         if (arizona->pdata.hpdet_id_gpio > 0) {
1233                 ret = devm_gpio_request_one(&pdev->dev,
1234                                             arizona->pdata.hpdet_id_gpio,
1235                                             GPIOF_OUT_INIT_LOW,
1236                                             "HPDET");
1237                 if (ret != 0) {
1238                         dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1239                                 arizona->pdata.hpdet_id_gpio, ret);
1240                         goto err_register;
1241                 }
1242         }
1243 
1244         if (arizona->pdata.micd_bias_start_time)
1245                 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1246                                    ARIZONA_MICD_BIAS_STARTTIME_MASK,
1247                                    arizona->pdata.micd_bias_start_time
1248                                    << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1249 
1250         if (arizona->pdata.micd_rate)
1251                 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1252                                    ARIZONA_MICD_RATE_MASK,
1253                                    arizona->pdata.micd_rate
1254                                    << ARIZONA_MICD_RATE_SHIFT);
1255 
1256         if (arizona->pdata.micd_dbtime)
1257                 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1258                                    ARIZONA_MICD_DBTIME_MASK,
1259                                    arizona->pdata.micd_dbtime
1260                                    << ARIZONA_MICD_DBTIME_SHIFT);
1261 
1262         BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1263 
1264         if (arizona->pdata.num_micd_ranges) {
1265                 info->micd_ranges = pdata->micd_ranges;
1266                 info->num_micd_ranges = pdata->num_micd_ranges;
1267         } else {
1268                 info->micd_ranges = micd_default_ranges;
1269                 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1270         }
1271 
1272         if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1273                 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1274                         arizona->pdata.num_micd_ranges);
1275         }
1276 
1277         if (info->num_micd_ranges > 1) {
1278                 for (i = 1; i < info->num_micd_ranges; i++) {
1279                         if (info->micd_ranges[i - 1].max >
1280                             info->micd_ranges[i].max) {
1281                                 dev_err(arizona->dev,
1282                                         "MICD ranges must be sorted\n");
1283                                 ret = -EINVAL;
1284                                 goto err_input;
1285                         }
1286                 }
1287         }
1288 
1289         /* Disable all buttons by default */
1290         regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1291                            ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1292 
1293         /* Set up all the buttons the user specified */
1294         for (i = 0; i < info->num_micd_ranges; i++) {
1295                 for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1296                         if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1297                                 break;
1298 
1299                 if (j == ARRAY_SIZE(arizona_micd_levels)) {
1300                         dev_err(arizona->dev, "Unsupported MICD level %d\n",
1301                                 info->micd_ranges[i].max);
1302                         ret = -EINVAL;
1303                         goto err_input;
1304                 }
1305 
1306                 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1307                         arizona_micd_levels[j], i);
1308 
1309                 arizona_micd_set_level(arizona, i, j);
1310                 input_set_capability(info->input, EV_KEY,
1311                                      info->micd_ranges[i].key);
1312 
1313                 /* Enable reporting of that range */
1314                 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1315                                    1 << i, 1 << i);
1316         }
1317 
1318         /* Set all the remaining keys to a maximum */
1319         for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1320                 arizona_micd_set_level(arizona, i, 0x3f);
1321 
1322         /*
1323          * If we have a clamp use it, activating in conjunction with
1324          * GPIO5 if that is connected for jack detect operation.
1325          */
1326         if (info->micd_clamp) {
1327                 if (arizona->pdata.jd_gpio5) {
1328                         /* Put the GPIO into input mode with optional pull */
1329                         val = 0xc101;
1330                         if (arizona->pdata.jd_gpio5_nopull)
1331                                 val &= ~ARIZONA_GPN_PU;
1332 
1333                         regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1334                                      val);
1335 
1336                         if (arizona->pdata.jd_invert)
1337                                 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
1338                         else
1339                                 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
1340                 } else {
1341                         if (arizona->pdata.jd_invert)
1342                                 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
1343                         else
1344                                 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
1345                 }
1346 
1347                 regmap_update_bits(arizona->regmap,
1348                                    ARIZONA_MICD_CLAMP_CONTROL,
1349                                    ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
1350 
1351                 regmap_update_bits(arizona->regmap,
1352                                    ARIZONA_JACK_DETECT_DEBOUNCE,
1353                                    ARIZONA_MICD_CLAMP_DB,
1354                                    ARIZONA_MICD_CLAMP_DB);
1355         }
1356 
1357         arizona_extcon_set_mode(info, 0);
1358 
1359         pm_runtime_enable(&pdev->dev);
1360         pm_runtime_idle(&pdev->dev);
1361         pm_runtime_get_sync(&pdev->dev);
1362 
1363         if (arizona->pdata.jd_gpio5) {
1364                 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1365                 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1366         } else {
1367                 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1368                 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1369         }
1370 
1371         ret = arizona_request_irq(arizona, jack_irq_rise,
1372                                   "JACKDET rise", arizona_jackdet, info);
1373         if (ret != 0) {
1374                 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1375                         ret);
1376                 goto err_input;
1377         }
1378 
1379         ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
1380         if (ret != 0) {
1381                 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1382                         ret);
1383                 goto err_rise;
1384         }
1385 
1386         ret = arizona_request_irq(arizona, jack_irq_fall,
1387                                   "JACKDET fall", arizona_jackdet, info);
1388         if (ret != 0) {
1389                 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1390                 goto err_rise_wake;
1391         }
1392 
1393         ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
1394         if (ret != 0) {
1395                 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1396                         ret);
1397                 goto err_fall;
1398         }
1399 
1400         ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1401                                   "MICDET", arizona_micdet, info);
1402         if (ret != 0) {
1403                 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1404                 goto err_fall_wake;
1405         }
1406 
1407         ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1408                                   "HPDET", arizona_hpdet_irq, info);
1409         if (ret != 0) {
1410                 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1411                 goto err_micdet;
1412         }
1413 
1414         arizona_clk32k_enable(arizona);
1415         regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1416                            ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1417         regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1418                            ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1419 
1420         ret = regulator_allow_bypass(info->micvdd, true);
1421         if (ret != 0)
1422                 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1423                          ret);
1424 
1425         pm_runtime_put(&pdev->dev);
1426 
1427         ret = input_register_device(info->input);
1428         if (ret) {
1429                 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
1430                 goto err_hpdet;
1431         }
1432 
1433         return 0;
1434 
1435 err_hpdet:
1436         arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1437 err_micdet:
1438         arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1439 err_fall_wake:
1440         arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1441 err_fall:
1442         arizona_free_irq(arizona, jack_irq_fall, info);
1443 err_rise_wake:
1444         arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1445 err_rise:
1446         arizona_free_irq(arizona, jack_irq_rise, info);
1447 err_input:
1448 err_register:
1449         pm_runtime_disable(&pdev->dev);
1450         return ret;
1451 }
1452 
1453 static int arizona_extcon_remove(struct platform_device *pdev)
1454 {
1455         struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1456         struct arizona *arizona = info->arizona;
1457         int jack_irq_rise, jack_irq_fall;
1458 
1459         pm_runtime_disable(&pdev->dev);
1460 
1461         regmap_update_bits(arizona->regmap,
1462                            ARIZONA_MICD_CLAMP_CONTROL,
1463                            ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1464 
1465         if (arizona->pdata.jd_gpio5) {
1466                 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1467                 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1468         } else {
1469                 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1470                 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1471         }
1472 
1473         arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1474         arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1475         arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1476         arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1477         arizona_free_irq(arizona, jack_irq_rise, info);
1478         arizona_free_irq(arizona, jack_irq_fall, info);
1479         cancel_delayed_work_sync(&info->hpdet_work);
1480         regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1481                            ARIZONA_JD1_ENA, 0);
1482         arizona_clk32k_disable(arizona);
1483 
1484         return 0;
1485 }
1486 
1487 static struct platform_driver arizona_extcon_driver = {
1488         .driver         = {
1489                 .name   = "arizona-extcon",
1490         },
1491         .probe          = arizona_extcon_probe,
1492         .remove         = arizona_extcon_remove,
1493 };
1494 
1495 module_platform_driver(arizona_extcon_driver);
1496 
1497 MODULE_DESCRIPTION("Arizona Extcon driver");
1498 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1499 MODULE_LICENSE("GPL");
1500 MODULE_ALIAS("platform:extcon-arizona");
1501 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us