Version:  2.0.40 2.2.26 2.4.37 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 3.16 3.17 3.18

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

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