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