]> Pileus Git - ~andy/linux/blob - drivers/extcon/extcon-arizona.c
extcon: arizona: Support HPDET based accessory identification
[~andy/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 <linux/mfd/arizona/core.h>
31 #include <linux/mfd/arizona/pdata.h>
32 #include <linux/mfd/arizona/registers.h>
33
34 #define ARIZONA_DEFAULT_HP 32
35
36 #define ARIZONA_NUM_BUTTONS 6
37
38 #define ARIZONA_ACCDET_MODE_MIC 0
39 #define ARIZONA_ACCDET_MODE_HPL 1
40 #define ARIZONA_ACCDET_MODE_HPR 2
41
42 struct arizona_extcon_info {
43         struct device *dev;
44         struct arizona *arizona;
45         struct mutex lock;
46         struct regulator *micvdd;
47         struct input_dev *input;
48
49         int micd_mode;
50         const struct arizona_micd_config *micd_modes;
51         int micd_num_modes;
52
53         bool micd_reva;
54         bool micd_clamp;
55
56         bool hpdet_active;
57
58         int num_hpdet_res;
59         unsigned int hpdet_res[2];
60
61         bool mic;
62         bool detecting;
63         int jack_flips;
64
65         int hpdet_ip;
66
67         struct extcon_dev edev;
68 };
69
70 static const struct arizona_micd_config micd_default_modes[] = {
71         { 0,                  2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
72         { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
73 };
74
75 static struct {
76         u16 status;
77         int report;
78 } arizona_lvl_to_key[ARIZONA_NUM_BUTTONS] = {
79         {  0x1, BTN_0 },
80         {  0x2, BTN_1 },
81         {  0x4, BTN_2 },
82         {  0x8, BTN_3 },
83         { 0x10, BTN_4 },
84         { 0x20, BTN_5 },
85 };
86
87 #define ARIZONA_CABLE_MECHANICAL 0
88 #define ARIZONA_CABLE_MICROPHONE 1
89 #define ARIZONA_CABLE_HEADPHONE  2
90 #define ARIZONA_CABLE_LINEOUT    3
91
92 static const char *arizona_cable[] = {
93         "Mechanical",
94         "Microphone",
95         "Headphone",
96         "Line-out",
97         NULL,
98 };
99
100 static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
101 {
102         struct arizona *arizona = info->arizona;
103
104         if (arizona->pdata.micd_pol_gpio > 0)
105                 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
106                                         info->micd_modes[mode].gpio);
107         regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
108                            ARIZONA_MICD_BIAS_SRC_MASK,
109                            info->micd_modes[mode].bias);
110         regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
111                            ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
112
113         info->micd_mode = mode;
114
115         dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
116 }
117
118 static void arizona_start_mic(struct arizona_extcon_info *info)
119 {
120         struct arizona *arizona = info->arizona;
121         bool change;
122         int ret;
123
124         /* Microphone detection can't use idle mode */
125         pm_runtime_get(info->dev);
126
127         ret = regulator_enable(info->micvdd);
128         if (ret != 0) {
129                 dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
130                         ret);
131         }
132
133         if (info->micd_reva) {
134                 regmap_write(arizona->regmap, 0x80, 0x3);
135                 regmap_write(arizona->regmap, 0x294, 0);
136                 regmap_write(arizona->regmap, 0x80, 0x0);
137         }
138
139         regmap_update_bits(arizona->regmap,
140                            ARIZONA_ACCESSORY_DETECT_MODE_1,
141                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
142
143         regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
144                                  ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
145                                  &change);
146         if (!change) {
147                 regulator_disable(info->micvdd);
148                 pm_runtime_put_autosuspend(info->dev);
149         }
150 }
151
152 static void arizona_stop_mic(struct arizona_extcon_info *info)
153 {
154         struct arizona *arizona = info->arizona;
155         bool change;
156
157         regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
158                                  ARIZONA_MICD_ENA, 0,
159                                  &change);
160
161         if (info->micd_reva) {
162                 regmap_write(arizona->regmap, 0x80, 0x3);
163                 regmap_write(arizona->regmap, 0x294, 2);
164                 regmap_write(arizona->regmap, 0x80, 0x0);
165         }
166
167         if (change) {
168                 regulator_disable(info->micvdd);
169                 pm_runtime_mark_last_busy(info->dev);
170                 pm_runtime_put_autosuspend(info->dev);
171         }
172 }
173
174 static struct {
175         unsigned int factor_a;
176         unsigned int factor_b;
177 } arizona_hpdet_b_ranges[] = {
178         {  5528,   362464 },
179         { 11084,  6186851 },
180         { 11065, 65460395 },
181 };
182
183 static struct {
184         int min;
185         int max;
186 } arizona_hpdet_c_ranges[] = {
187         { 0,       30 },
188         { 8,      100 },
189         { 100,   1000 },
190         { 1000, 10000 },
191 };
192
193 static int arizona_hpdet_read(struct arizona_extcon_info *info)
194 {
195         struct arizona *arizona = info->arizona;
196         unsigned int val, range;
197         int ret;
198
199         ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
200         if (ret != 0) {
201                 dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
202                         ret);
203                 return ret;
204         }
205
206         switch (info->hpdet_ip) {
207         case 0:
208                 if (!(val & ARIZONA_HP_DONE)) {
209                         dev_err(arizona->dev, "HPDET did not complete: %x\n",
210                                 val);
211                         val = ARIZONA_DEFAULT_HP;
212                 }
213
214                 val &= ARIZONA_HP_LVL_MASK;
215                 break;
216
217         case 1:
218                 if (!(val & ARIZONA_HP_DONE_B)) {
219                         dev_err(arizona->dev, "HPDET did not complete: %x\n",
220                                 val);
221                         return ARIZONA_DEFAULT_HP;
222                 }
223
224                 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
225                 if (ret != 0) {
226                         dev_err(arizona->dev, "Failed to read HP value: %d\n",
227                                 ret);
228                         return ARIZONA_DEFAULT_HP;
229                 }
230
231                 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
232                             &range);
233                 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
234                            >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
235
236                 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
237                     (val < 100 || val > 0x3fb)) {
238                         range++;
239                         dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
240                                 range);
241                         regmap_update_bits(arizona->regmap,
242                                            ARIZONA_HEADPHONE_DETECT_1,
243                                            ARIZONA_HP_IMPEDANCE_RANGE_MASK,
244                                            range <<
245                                            ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
246                         return -EAGAIN;
247                 }
248
249                 /* If we go out of range report top of range */
250                 if (val < 100 || val > 0x3fb) {
251                         dev_dbg(arizona->dev, "Measurement out of range\n");
252                         return 10000;
253                 }
254
255                 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
256                         val, range);
257
258                 val = arizona_hpdet_b_ranges[range].factor_b
259                         / ((val * 100) -
260                            arizona_hpdet_b_ranges[range].factor_a);
261                 break;
262
263         default:
264                 dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
265                          info->hpdet_ip);
266         case 2:
267                 if (!(val & ARIZONA_HP_DONE_B)) {
268                         dev_err(arizona->dev, "HPDET did not complete: %x\n",
269                                 val);
270                         return ARIZONA_DEFAULT_HP;
271                 }
272
273                 val &= ARIZONA_HP_LVL_B_MASK;
274
275                 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
276                             &range);
277                 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
278                            >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
279
280                 /* Skip up or down a range? */
281                 if (range && (val < arizona_hpdet_c_ranges[range].min)) {
282                         range--;
283                         dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
284                                 arizona_hpdet_c_ranges[range].min,
285                                 arizona_hpdet_c_ranges[range].max);
286                         regmap_update_bits(arizona->regmap,
287                                            ARIZONA_HEADPHONE_DETECT_1,
288                                            ARIZONA_HP_IMPEDANCE_RANGE_MASK,
289                                            range <<
290                                            ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
291                         return -EAGAIN;
292                 }
293
294                 if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
295                     (val >= arizona_hpdet_c_ranges[range].max)) {
296                         range++;
297                         dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
298                                 arizona_hpdet_c_ranges[range].min,
299                                 arizona_hpdet_c_ranges[range].max);
300                         regmap_update_bits(arizona->regmap,
301                                            ARIZONA_HEADPHONE_DETECT_1,
302                                            ARIZONA_HP_IMPEDANCE_RANGE_MASK,
303                                            range <<
304                                            ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
305                         return -EAGAIN;
306                 }
307         }
308
309         dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
310         return val;
311 }
312
313 static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
314 {
315         struct arizona *arizona = info->arizona;
316         int ret;
317
318         /*
319          * If we're using HPDET for accessory identification we need
320          * to take multiple measurements, step through them in sequence.
321          */
322         if (arizona->pdata.hpdet_acc_id) {
323                 info->hpdet_res[info->num_hpdet_res++] = *reading;
324
325                 /*
326                  * If the impedence is too high don't measure the
327                  * second ground.
328                  */
329                 if (info->num_hpdet_res == 1 && *reading >= 45) {
330                         dev_dbg(arizona->dev, "Skipping ground flip\n");
331                         info->hpdet_res[info->num_hpdet_res++] = *reading;
332                 }
333
334                 if (info->num_hpdet_res == 1) {
335                         dev_dbg(arizona->dev, "Flipping ground\n");
336
337                         regmap_update_bits(arizona->regmap,
338                                            ARIZONA_ACCESSORY_DETECT_MODE_1,
339                                            ARIZONA_ACCDET_SRC,
340                                            ~info->micd_modes[0].src);
341                         regmap_update_bits(arizona->regmap,
342                                            ARIZONA_HEADPHONE_DETECT_1,
343                                            ARIZONA_HP_POLL, 0);
344                         regmap_update_bits(arizona->regmap,
345                                            ARIZONA_HEADPHONE_DETECT_1,
346                                            ARIZONA_HP_POLL, ARIZONA_HP_POLL);
347                         return -EAGAIN;
348                 }
349
350                 /* OK, got both.  Now, compare... */
351                 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
352                         info->hpdet_res[0], info->hpdet_res[1]);
353
354                 if (info->hpdet_res[0] > info->hpdet_res[1] * 2) {
355                         dev_dbg(arizona->dev, "Detected mic\n");
356                         info->mic = true;
357                         ret = extcon_set_cable_state_(&info->edev,
358                                                       ARIZONA_CABLE_MICROPHONE,
359                                                       true);
360                         if (ret != 0) {
361                                 dev_err(arizona->dev,
362                                         "Failed to report mic: %d\n", ret);
363                         }
364
365                         /* Take the headphone impedance for the main report */
366                         *reading = info->hpdet_res[1];
367                 } else {
368                         dev_dbg(arizona->dev, "Detected headphone\n");
369                 }
370
371                 /* Make sure everything is reset back to the real polarity */
372                 regmap_update_bits(arizona->regmap,
373                                    ARIZONA_ACCESSORY_DETECT_MODE_1,
374                                    ARIZONA_ACCDET_SRC,
375                                    info->micd_modes[0].src);
376         }
377
378         return 0;
379 }
380
381 static irqreturn_t arizona_hpdet_irq(int irq, void *data)
382 {
383         struct arizona_extcon_info *info = data;
384         struct arizona *arizona = info->arizona;
385         int report = ARIZONA_CABLE_HEADPHONE;
386         int ret, reading;
387
388         mutex_lock(&info->lock);
389
390         /* If we got a spurious IRQ for some reason then ignore it */
391         if (!info->hpdet_active) {
392                 dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
393                 mutex_unlock(&info->lock);
394                 return IRQ_NONE;
395         }
396
397         /* If the cable was removed while measuring ignore the result */
398         ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL);
399         if (ret < 0) {
400                 dev_err(arizona->dev, "Failed to check cable state: %d\n",
401                         ret);
402                 goto out;
403         } else if (!ret) {
404                 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
405                 goto done;
406         }
407
408         ret = arizona_hpdet_read(info);
409         if (ret == -EAGAIN) {
410                 goto out;
411         } else if (ret < 0) {
412                 goto done;
413         }
414         reading = ret;
415
416         /* Reset back to starting range */
417         regmap_update_bits(arizona->regmap,
418                            ARIZONA_HEADPHONE_DETECT_1,
419                            ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
420                            0);
421
422         ret = arizona_hpdet_do_id(info, &reading);
423         if (ret == -EAGAIN) {
424                 goto out;
425         } else if (ret < 0) {
426                 goto done;
427         }
428
429         /* Report high impedence cables as line outputs */
430         if (reading >= 5000)
431                 report = ARIZONA_CABLE_LINEOUT;
432         else
433                 report = ARIZONA_CABLE_HEADPHONE;
434
435         ret = extcon_set_cable_state_(&info->edev, report, true);
436         if (ret != 0)
437                 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
438                         ret);
439
440         ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0);
441         if (ret != 0)
442                 dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret);
443
444         ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0);
445         if (ret != 0)
446                 dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret);
447
448 done:
449
450         /* Revert back to MICDET mode */
451         regmap_update_bits(arizona->regmap,
452                            ARIZONA_ACCESSORY_DETECT_MODE_1,
453                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
454
455         /* If we have a mic then reenable MICDET */
456         if (info->mic)
457                 arizona_start_mic(info);
458
459         if (info->hpdet_active) {
460                 pm_runtime_put_autosuspend(info->dev);
461                 info->hpdet_active = false;
462         }
463
464 out:
465         mutex_unlock(&info->lock);
466
467         return IRQ_HANDLED;
468 }
469
470 static void arizona_identify_headphone(struct arizona_extcon_info *info)
471 {
472         struct arizona *arizona = info->arizona;
473         int ret;
474
475         dev_dbg(arizona->dev, "Starting HPDET\n");
476
477         /* Make sure we keep the device enabled during the measurement */
478         pm_runtime_get(info->dev);
479
480         info->hpdet_active = true;
481
482         if (info->mic)
483                 arizona_stop_mic(info);
484
485         ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000);
486         if (ret != 0)
487                 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
488
489         ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
490         if (ret != 0)
491                 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
492
493         ret = regmap_update_bits(arizona->regmap,
494                                  ARIZONA_ACCESSORY_DETECT_MODE_1,
495                                  ARIZONA_ACCDET_MODE_MASK,
496                                  ARIZONA_ACCDET_MODE_HPL);
497         if (ret != 0) {
498                 dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
499                 goto err;
500         }
501
502         ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
503                                  ARIZONA_HP_POLL, ARIZONA_HP_POLL);
504         if (ret != 0) {
505                 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
506                         ret);
507                 goto err;
508         }
509
510         return;
511
512 err:
513         regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
514                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
515
516         /* Just report headphone */
517         ret = extcon_update_state(&info->edev,
518                                   1 << ARIZONA_CABLE_HEADPHONE,
519                                   1 << ARIZONA_CABLE_HEADPHONE);
520         if (ret != 0)
521                 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
522
523         if (info->mic)
524                 arizona_start_mic(info);
525
526         info->hpdet_active = false;
527 }
528
529 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
530 {
531         struct arizona *arizona = info->arizona;
532         int ret;
533
534         dev_dbg(arizona->dev, "Starting identification via HPDET\n");
535
536         /* Make sure we keep the device enabled during the measurement */
537         pm_runtime_get(info->dev);
538
539         info->hpdet_active = true;
540
541         ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000);
542         if (ret != 0)
543                 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
544
545         ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
546         if (ret != 0)
547                 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
548
549         ret = regmap_update_bits(arizona->regmap,
550                                  ARIZONA_ACCESSORY_DETECT_MODE_1,
551                                  ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
552                                  info->micd_modes[0].src |
553                                  ARIZONA_ACCDET_MODE_HPL);
554         if (ret != 0) {
555                 dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
556                 goto err;
557         }
558
559         ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
560                                  ARIZONA_HP_POLL, ARIZONA_HP_POLL);
561         if (ret != 0) {
562                 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
563                         ret);
564                 goto err;
565         }
566
567         return;
568
569 err:
570         regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
571                            ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
572
573         /* Just report headphone */
574         ret = extcon_update_state(&info->edev,
575                                   1 << ARIZONA_CABLE_HEADPHONE,
576                                   1 << ARIZONA_CABLE_HEADPHONE);
577         if (ret != 0)
578                 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
579
580         info->hpdet_active = false;
581 }
582
583 static irqreturn_t arizona_micdet(int irq, void *data)
584 {
585         struct arizona_extcon_info *info = data;
586         struct arizona *arizona = info->arizona;
587         unsigned int val, lvl;
588         int ret, i;
589
590         mutex_lock(&info->lock);
591
592         ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
593         if (ret != 0) {
594                 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
595                 mutex_unlock(&info->lock);
596                 return IRQ_NONE;
597         }
598
599         dev_dbg(arizona->dev, "MICDET: %x\n", val);
600
601         if (!(val & ARIZONA_MICD_VALID)) {
602                 dev_warn(arizona->dev, "Microphone detection state invalid\n");
603                 mutex_unlock(&info->lock);
604                 return IRQ_NONE;
605         }
606
607         /* Due to jack detect this should never happen */
608         if (!(val & ARIZONA_MICD_STS)) {
609                 dev_warn(arizona->dev, "Detected open circuit\n");
610                 info->detecting = false;
611                 goto handled;
612         }
613
614         /* If we got a high impedence we should have a headset, report it. */
615         if (info->detecting && (val & 0x400)) {
616                 arizona_identify_headphone(info);
617
618                 ret = extcon_update_state(&info->edev,
619                                           1 << ARIZONA_CABLE_MICROPHONE,
620                                           1 << ARIZONA_CABLE_MICROPHONE);
621
622                 if (ret != 0)
623                         dev_err(arizona->dev, "Headset report failed: %d\n",
624                                 ret);
625
626                 info->mic = true;
627                 info->detecting = false;
628                 goto handled;
629         }
630
631         /* If we detected a lower impedence during initial startup
632          * then we probably have the wrong polarity, flip it.  Don't
633          * do this for the lowest impedences to speed up detection of
634          * plain headphones.  If both polarities report a low
635          * impedence then give up and report headphones.
636          */
637         if (info->detecting && (val & 0x3f8)) {
638                 info->jack_flips++;
639
640                 if (info->jack_flips >= info->micd_num_modes) {
641                         dev_dbg(arizona->dev, "Detected HP/line\n");
642                         arizona_identify_headphone(info);
643
644                         info->detecting = false;
645
646                         arizona_stop_mic(info);
647                 } else {
648                         info->micd_mode++;
649                         if (info->micd_mode == info->micd_num_modes)
650                                 info->micd_mode = 0;
651                         arizona_extcon_set_mode(info, info->micd_mode);
652
653                         info->jack_flips++;
654                 }
655
656                 goto handled;
657         }
658
659         /*
660          * If we're still detecting and we detect a short then we've
661          * got a headphone.  Otherwise it's a button press.
662          */
663         if (val & 0x3fc) {
664                 if (info->mic) {
665                         dev_dbg(arizona->dev, "Mic button detected\n");
666
667                         lvl = val & ARIZONA_MICD_LVL_MASK;
668                         lvl >>= ARIZONA_MICD_LVL_SHIFT;
669
670                         for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
671                                 if (lvl & arizona_lvl_to_key[i].status)
672                                         input_report_key(info->input,
673                                                          arizona_lvl_to_key[i].report,
674                                                          1);
675                         input_sync(info->input);
676
677                 } else if (info->detecting) {
678                         dev_dbg(arizona->dev, "Headphone detected\n");
679                         info->detecting = false;
680                         arizona_stop_mic(info);
681
682                         arizona_identify_headphone(info);
683                 } else {
684                         dev_warn(arizona->dev, "Button with no mic: %x\n",
685                                  val);
686                 }
687         } else {
688                 dev_dbg(arizona->dev, "Mic button released\n");
689                 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
690                         input_report_key(info->input,
691                                          arizona_lvl_to_key[i].report, 0);
692                 input_sync(info->input);
693         }
694
695 handled:
696         pm_runtime_mark_last_busy(info->dev);
697         mutex_unlock(&info->lock);
698
699         return IRQ_HANDLED;
700 }
701
702 static irqreturn_t arizona_jackdet(int irq, void *data)
703 {
704         struct arizona_extcon_info *info = data;
705         struct arizona *arizona = info->arizona;
706         unsigned int val, present, mask;
707         int ret, i;
708
709         pm_runtime_get_sync(info->dev);
710
711         mutex_lock(&info->lock);
712
713         if (arizona->pdata.jd_gpio5) {
714                 mask = ARIZONA_MICD_CLAMP_STS;
715                 present = 0;
716         } else {
717                 mask = ARIZONA_JD1_STS;
718                 present = ARIZONA_JD1_STS;
719         }
720
721         ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
722         if (ret != 0) {
723                 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
724                         ret);
725                 mutex_unlock(&info->lock);
726                 pm_runtime_put_autosuspend(info->dev);
727                 return IRQ_NONE;
728         }
729
730         if ((val & mask) == present) {
731                 dev_dbg(arizona->dev, "Detected jack\n");
732                 ret = extcon_set_cable_state_(&info->edev,
733                                               ARIZONA_CABLE_MECHANICAL, true);
734
735                 if (ret != 0)
736                         dev_err(arizona->dev, "Mechanical report failed: %d\n",
737                                 ret);
738
739                 if (!arizona->pdata.hpdet_acc_id) {
740                         info->detecting = true;
741                         info->mic = false;
742                         info->jack_flips = 0;
743
744                         arizona_start_mic(info);
745                 } else {
746                         arizona_start_hpdet_acc_id(info);
747                 }
748         } else {
749                 dev_dbg(arizona->dev, "Detected jack removal\n");
750
751                 arizona_stop_mic(info);
752
753                 info->num_hpdet_res = 0;
754                 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
755                         info->hpdet_res[i] = 0;
756                 info->mic = false;
757
758                 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
759                         input_report_key(info->input,
760                                          arizona_lvl_to_key[i].report, 0);
761                 input_sync(info->input);
762
763                 ret = extcon_update_state(&info->edev, 0xffffffff, 0);
764                 if (ret != 0)
765                         dev_err(arizona->dev, "Removal report failed: %d\n",
766                                 ret);
767         }
768
769         mutex_unlock(&info->lock);
770
771         pm_runtime_mark_last_busy(info->dev);
772         pm_runtime_put_autosuspend(info->dev);
773
774         return IRQ_HANDLED;
775 }
776
777 static int arizona_extcon_probe(struct platform_device *pdev)
778 {
779         struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
780         struct arizona_pdata *pdata;
781         struct arizona_extcon_info *info;
782         int jack_irq_fall, jack_irq_rise;
783         int ret, mode, i;
784
785         pdata = dev_get_platdata(arizona->dev);
786
787         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
788         if (!info) {
789                 dev_err(&pdev->dev, "Failed to allocate memory\n");
790                 ret = -ENOMEM;
791                 goto err;
792         }
793
794         info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
795         if (IS_ERR(info->micvdd)) {
796                 ret = PTR_ERR(info->micvdd);
797                 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
798                 goto err;
799         }
800
801         mutex_init(&info->lock);
802         info->arizona = arizona;
803         info->dev = &pdev->dev;
804         platform_set_drvdata(pdev, info);
805
806         switch (arizona->type) {
807         case WM5102:
808                 switch (arizona->rev) {
809                 case 0:
810                         info->micd_reva = true;
811                         break;
812                 default:
813                         info->micd_clamp = true;
814                         info->hpdet_ip = 1;
815                         break;
816                 }
817                 break;
818         default:
819                 break;
820         }
821
822         info->edev.name = "Headset Jack";
823         info->edev.supported_cable = arizona_cable;
824
825         ret = extcon_dev_register(&info->edev, arizona->dev);
826         if (ret < 0) {
827                 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
828                         ret);
829                 goto err;
830         }
831
832         if (pdata->num_micd_configs) {
833                 info->micd_modes = pdata->micd_configs;
834                 info->micd_num_modes = pdata->num_micd_configs;
835         } else {
836                 info->micd_modes = micd_default_modes;
837                 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
838         }
839
840         if (arizona->pdata.micd_pol_gpio > 0) {
841                 if (info->micd_modes[0].gpio)
842                         mode = GPIOF_OUT_INIT_HIGH;
843                 else
844                         mode = GPIOF_OUT_INIT_LOW;
845
846                 ret = devm_gpio_request_one(&pdev->dev,
847                                             arizona->pdata.micd_pol_gpio,
848                                             mode,
849                                             "MICD polarity");
850                 if (ret != 0) {
851                         dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
852                                 arizona->pdata.micd_pol_gpio, ret);
853                         goto err_register;
854                 }
855         }
856
857         if (arizona->pdata.micd_bias_start_time)
858                 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
859                                    ARIZONA_MICD_BIAS_STARTTIME_MASK,
860                                    arizona->pdata.micd_bias_start_time
861                                    << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
862
863         /*
864          * If we have a clamp use it, activating in conjunction with
865          * GPIO5 if that is connected for jack detect operation.
866          */
867         if (info->micd_clamp) {
868                 if (arizona->pdata.jd_gpio5) {
869                         /* Put the GPIO into input mode */
870                         regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
871                                      0xc101);
872
873                         regmap_update_bits(arizona->regmap,
874                                            ARIZONA_MICD_CLAMP_CONTROL,
875                                            ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
876                 } else {
877                         regmap_update_bits(arizona->regmap,
878                                            ARIZONA_MICD_CLAMP_CONTROL,
879                                            ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
880                 }
881
882                 regmap_update_bits(arizona->regmap,
883                                    ARIZONA_JACK_DETECT_DEBOUNCE,
884                                    ARIZONA_MICD_CLAMP_DB,
885                                    ARIZONA_MICD_CLAMP_DB);
886         }
887
888         arizona_extcon_set_mode(info, 0);
889
890         info->input = devm_input_allocate_device(&pdev->dev);
891         if (!info->input) {
892                 dev_err(arizona->dev, "Can't allocate input dev\n");
893                 ret = -ENOMEM;
894                 goto err_register;
895         }
896
897         for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
898                 input_set_capability(info->input, EV_KEY,
899                                      arizona_lvl_to_key[i].report);
900         info->input->name = "Headset";
901         info->input->phys = "arizona/extcon";
902         info->input->dev.parent = &pdev->dev;
903
904         pm_runtime_enable(&pdev->dev);
905         pm_runtime_idle(&pdev->dev);
906         pm_runtime_get_sync(&pdev->dev);
907
908         if (arizona->pdata.jd_gpio5) {
909                 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
910                 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
911         } else {
912                 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
913                 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
914         }
915
916         ret = arizona_request_irq(arizona, jack_irq_rise,
917                                   "JACKDET rise", arizona_jackdet, info);
918         if (ret != 0) {
919                 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
920                         ret);
921                 goto err_input;
922         }
923
924         ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
925         if (ret != 0) {
926                 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
927                         ret);
928                 goto err_rise;
929         }
930
931         ret = arizona_request_irq(arizona, jack_irq_fall,
932                                   "JACKDET fall", arizona_jackdet, info);
933         if (ret != 0) {
934                 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
935                 goto err_rise_wake;
936         }
937
938         ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
939         if (ret != 0) {
940                 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
941                         ret);
942                 goto err_fall;
943         }
944
945         ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
946                                   "MICDET", arizona_micdet, info);
947         if (ret != 0) {
948                 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
949                 goto err_fall_wake;
950         }
951
952         ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
953                                   "HPDET", arizona_hpdet_irq, info);
954         if (ret != 0) {
955                 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
956                 goto err_micdet;
957         }
958
959         regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
960                            ARIZONA_MICD_RATE_MASK,
961                            8 << ARIZONA_MICD_RATE_SHIFT);
962
963         arizona_clk32k_enable(arizona);
964         regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
965                            ARIZONA_JD1_DB, ARIZONA_JD1_DB);
966         regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
967                            ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
968
969         ret = regulator_allow_bypass(info->micvdd, true);
970         if (ret != 0)
971                 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
972                          ret);
973
974         pm_runtime_put(&pdev->dev);
975
976         ret = input_register_device(info->input);
977         if (ret) {
978                 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
979                 goto err_hpdet;
980         }
981
982         return 0;
983
984 err_hpdet:
985         arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
986 err_micdet:
987         arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
988 err_fall_wake:
989         arizona_set_irq_wake(arizona, jack_irq_fall, 0);
990 err_fall:
991         arizona_free_irq(arizona, jack_irq_fall, info);
992 err_rise_wake:
993         arizona_set_irq_wake(arizona, jack_irq_rise, 0);
994 err_rise:
995         arizona_free_irq(arizona, jack_irq_rise, info);
996 err_input:
997 err_register:
998         pm_runtime_disable(&pdev->dev);
999         extcon_dev_unregister(&info->edev);
1000 err:
1001         return ret;
1002 }
1003
1004 static int arizona_extcon_remove(struct platform_device *pdev)
1005 {
1006         struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1007         struct arizona *arizona = info->arizona;
1008         int jack_irq_rise, jack_irq_fall;
1009
1010         pm_runtime_disable(&pdev->dev);
1011
1012         regmap_update_bits(arizona->regmap,
1013                            ARIZONA_MICD_CLAMP_CONTROL,
1014                            ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1015
1016         if (arizona->pdata.jd_gpio5) {
1017                 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1018                 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1019         } else {
1020                 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1021                 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1022         }
1023
1024         arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1025         arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1026         arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1027         arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1028         arizona_free_irq(arizona, jack_irq_rise, info);
1029         arizona_free_irq(arizona, jack_irq_fall, info);
1030         regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1031                            ARIZONA_JD1_ENA, 0);
1032         arizona_clk32k_disable(arizona);
1033         extcon_dev_unregister(&info->edev);
1034
1035         return 0;
1036 }
1037
1038 static struct platform_driver arizona_extcon_driver = {
1039         .driver         = {
1040                 .name   = "arizona-extcon",
1041                 .owner  = THIS_MODULE,
1042         },
1043         .probe          = arizona_extcon_probe,
1044         .remove         = arizona_extcon_remove,
1045 };
1046
1047 module_platform_driver(arizona_extcon_driver);
1048
1049 MODULE_DESCRIPTION("Arizona Extcon driver");
1050 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1051 MODULE_LICENSE("GPL");
1052 MODULE_ALIAS("platform:extcon-arizona");