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