Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

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

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