]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/extcon/extcon-arizona.c
config: Add RTL8XXXU wifi module
[mirror_ubuntu-zesty-kernel.git] / drivers / extcon / extcon-arizona.c
CommitLineData
f2c32a88
MB
1/*
2 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
3 *
d8d09564 4 * Copyright (C) 2012-2014 Wolfson Microelectronics plc
f2c32a88
MB
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>
8e5838dd 23#include <linux/gpio/consumer.h>
f2c32a88 24#include <linux/gpio.h>
34efe4dc 25#include <linux/input.h>
f2c32a88
MB
26#include <linux/platform_device.h>
27#include <linux/pm_runtime.h>
feffb0cc 28#include <linux/property.h>
f2c32a88
MB
29#include <linux/regulator/consumer.h>
30#include <linux/extcon.h>
31
bbbd46e3
MB
32#include <sound/soc.h>
33
f2c32a88
MB
34#include <linux/mfd/arizona/core.h>
35#include <linux/mfd/arizona/pdata.h>
36#include <linux/mfd/arizona/registers.h>
9e86b2ad 37#include <dt-bindings/mfd/arizona.h>
f2c32a88 38
6fed4d86 39#define ARIZONA_MAX_MICD_RANGE 8
34efe4dc 40
a288d648
RF
41#define ARIZONA_MICD_CLAMP_MODE_JDL 0x4
42#define ARIZONA_MICD_CLAMP_MODE_JDH 0x5
43#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
44#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
45
f719ae33
CK
46#define ARIZONA_TST_CAP_DEFAULT 0x3
47#define ARIZONA_TST_CAP_CLAMP 0x1
48
9dd5e53d
MB
49#define ARIZONA_HPDET_MAX 10000
50
2643fd64 51#define HPDET_DEBOUNCE 500
7abd4e2a 52#define DEFAULT_MICD_TIMEOUT 2000
a3e2078d 53
df8b6771
CK
54#define QUICK_HEADPHONE_MAX_OHM 3
55#define MICROPHONE_MIN_OHM 1257
56#define MICROPHONE_MAX_OHM 30000
57
bb327e92
CK
58#define MICD_DBTIME_TWO_READINGS 2
59#define MICD_DBTIME_FOUR_READINGS 4
60
ffae24fe
CK
61#define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \
62 ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \
63 ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \
64 ARIZONA_MICD_LVL_7)
65
66#define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)
67
68#define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)
69
f2c32a88
MB
70struct arizona_extcon_info {
71 struct device *dev;
72 struct arizona *arizona;
73 struct mutex lock;
74 struct regulator *micvdd;
34efe4dc 75 struct input_dev *input;
f2c32a88 76
a3e2078d
MB
77 u16 last_jackdet;
78
f2c32a88
MB
79 int micd_mode;
80 const struct arizona_micd_config *micd_modes;
81 int micd_num_modes;
82
6fed4d86
MB
83 const struct arizona_micd_range *micd_ranges;
84 int num_micd_ranges;
85
7abd4e2a
MB
86 int micd_timeout;
87
f2c32a88 88 bool micd_reva;
dab63eb2 89 bool micd_clamp;
f2c32a88 90
0e27bd31 91 struct delayed_work hpdet_work;
cd59e796 92 struct delayed_work micd_detect_work;
939c5671 93 struct delayed_work micd_timeout_work;
0e27bd31 94
4f340333 95 bool hpdet_active;
bf14ee5a 96 bool hpdet_done;
9dd5e53d 97 bool hpdet_retried;
4f340333 98
dd235eea 99 int num_hpdet_res;
1eda6aa7 100 unsigned int hpdet_res[3];
dd235eea 101
f2c32a88
MB
102 bool mic;
103 bool detecting;
104 int jack_flips;
105
d0fd5fbc 106 int hpdet_ip_version;
4f340333 107
ef70a214 108 struct extcon_dev *edev;
8e5838dd
CK
109
110 struct gpio_desc *micd_pol_gpio;
f2c32a88
MB
111};
112
113static const struct arizona_micd_config micd_default_modes[] = {
41024243
CK
114 { ARIZONA_ACCDET_SRC, 1, 0 },
115 { 0, 2, 1 },
f2c32a88
MB
116};
117
6fed4d86
MB
118static const struct arizona_micd_range micd_default_ranges[] = {
119 { .max = 11, .key = BTN_0 },
120 { .max = 28, .key = BTN_1 },
121 { .max = 54, .key = BTN_2 },
122 { .max = 100, .key = BTN_3 },
123 { .max = 186, .key = BTN_4 },
124 { .max = 430, .key = BTN_5 },
125};
126
df8b6771
CK
127/* The number of levels in arizona_micd_levels valid for button thresholds */
128#define ARIZONA_NUM_MICD_BUTTON_LEVELS 64
129
6fed4d86
MB
130static const int arizona_micd_levels[] = {
131 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
132 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
133 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
134 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
df8b6771 135 1257, 30000,
34efe4dc
MB
136};
137
73b6ecdb 138static const unsigned int arizona_cable[] = {
2a9de9c0 139 EXTCON_MECHANICAL,
11eecf91
CC
140 EXTCON_JACK_MICROPHONE,
141 EXTCON_JACK_HEADPHONE,
142 EXTCON_JACK_LINE_OUT,
2a9de9c0 143 EXTCON_NONE,
f2c32a88
MB
144};
145
9dd5e53d
MB
146static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
147
112bdfaa
CK
148static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info,
149 bool clamp)
03409071
MB
150{
151 struct arizona *arizona = info->arizona;
43f0acd9 152 unsigned int mask = 0, val = 0;
f719ae33 153 unsigned int cap_sel = 0;
03409071
MB
154 int ret;
155
43f0acd9 156 switch (arizona->type) {
d8d09564
RF
157 case WM8998:
158 case WM1814:
159 mask = 0;
160 break;
43f0acd9 161 case WM5110:
2b51f9c2 162 case WM8280:
43f0acd9
CK
163 mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |
164 ARIZONA_HP1L_SHRTI;
f719ae33 165 if (clamp) {
43f0acd9 166 val = ARIZONA_HP1L_SHRTO;
f719ae33
CK
167 cap_sel = ARIZONA_TST_CAP_CLAMP;
168 } else {
43f0acd9 169 val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI;
f719ae33
CK
170 cap_sel = ARIZONA_TST_CAP_DEFAULT;
171 }
172
173 ret = regmap_update_bits(arizona->regmap,
174 ARIZONA_HP_TEST_CTRL_1,
175 ARIZONA_HP1_TST_CAP_SEL_MASK,
176 cap_sel);
177 if (ret != 0)
178 dev_warn(arizona->dev,
179 "Failed to set TST_CAP_SEL: %d\n", ret);
43f0acd9
CK
180 break;
181 default:
182 mask = ARIZONA_RMV_SHRT_HP1L;
183 if (clamp)
184 val = ARIZONA_RMV_SHRT_HP1L;
185 break;
c19dc203 186 }
112bdfaa 187
03bf1adb 188 snd_soc_dapm_mutex_lock(arizona->dapm);
03409071 189
112bdfaa 190 arizona->hpdet_clamp = clamp;
03409071 191
112bdfaa
CK
192 /* Keep the HP output stages disabled while doing the clamp */
193 if (clamp) {
df8c3dbe
MB
194 ret = regmap_update_bits(arizona->regmap,
195 ARIZONA_OUTPUT_ENABLES_1,
196 ARIZONA_OUT1L_ENA |
197 ARIZONA_OUT1R_ENA, 0);
03409071 198 if (ret != 0)
df8c3dbe
MB
199 dev_warn(arizona->dev,
200 "Failed to disable headphone outputs: %d\n",
201 ret);
202 }
203
d8d09564
RF
204 if (mask) {
205 ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L,
206 mask, val);
207 if (ret != 0)
208 dev_warn(arizona->dev, "Failed to do clamp: %d\n",
03409071
MB
209 ret);
210
d8d09564
RF
211 ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R,
212 mask, val);
213 if (ret != 0)
214 dev_warn(arizona->dev, "Failed to do clamp: %d\n",
215 ret);
216 }
df8c3dbe 217
112bdfaa
CK
218 /* Restore the desired state while not doing the clamp */
219 if (!clamp) {
df8c3dbe
MB
220 ret = regmap_update_bits(arizona->regmap,
221 ARIZONA_OUTPUT_ENABLES_1,
222 ARIZONA_OUT1L_ENA |
223 ARIZONA_OUT1R_ENA, arizona->hp_ena);
03409071 224 if (ret != 0)
df8c3dbe
MB
225 dev_warn(arizona->dev,
226 "Failed to restore headphone outputs: %d\n",
03409071
MB
227 ret);
228 }
229
03bf1adb 230 snd_soc_dapm_mutex_unlock(arizona->dapm);
03409071
MB
231}
232
f2c32a88
MB
233static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
234{
235 struct arizona *arizona = info->arizona;
236
6fed4d86 237 mode %= info->micd_num_modes;
84eaa136 238
cd74f7b3
MB
239 if (arizona->pdata.micd_pol_gpio > 0)
240 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
241 info->micd_modes[mode].gpio);
8e5838dd
CK
242 else
243 gpiod_set_value_cansleep(info->micd_pol_gpio,
244 info->micd_modes[mode].gpio);
245
f2c32a88
MB
246 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
247 ARIZONA_MICD_BIAS_SRC_MASK,
41024243
CK
248 info->micd_modes[mode].bias <<
249 ARIZONA_MICD_BIAS_SRC_SHIFT);
f2c32a88
MB
250 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
251 ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
252
253 info->micd_mode = mode;
254
255 dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
256}
257
bbbd46e3
MB
258static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
259{
41024243 260 switch (info->micd_modes[0].bias) {
bbbd46e3
MB
261 case 1:
262 return "MICBIAS1";
263 case 2:
264 return "MICBIAS2";
265 case 3:
266 return "MICBIAS3";
267 default:
268 return "MICVDD";
269 }
270}
271
272static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
273{
274 struct arizona *arizona = info->arizona;
275 const char *widget = arizona_extcon_get_micbias(info);
276 struct snd_soc_dapm_context *dapm = arizona->dapm;
efd95c71 277 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
bbbd46e3
MB
278 int ret;
279
efd95c71 280 ret = snd_soc_component_force_enable_pin(component, widget);
bbbd46e3
MB
281 if (ret != 0)
282 dev_warn(arizona->dev, "Failed to enable %s: %d\n",
283 widget, ret);
284
bbbd46e3
MB
285 snd_soc_dapm_sync(dapm);
286
287 if (!arizona->pdata.micd_force_micbias) {
efd95c71 288 ret = snd_soc_component_disable_pin(component, widget);
bbbd46e3
MB
289 if (ret != 0)
290 dev_warn(arizona->dev, "Failed to disable %s: %d\n",
291 widget, ret);
292
bbbd46e3
MB
293 snd_soc_dapm_sync(dapm);
294 }
295}
296
9b1270c7
MB
297static void arizona_start_mic(struct arizona_extcon_info *info)
298{
299 struct arizona *arizona = info->arizona;
300 bool change;
301 int ret;
df8b6771 302 unsigned int mode;
9b1270c7 303
9b1270c7
MB
304 /* Microphone detection can't use idle mode */
305 pm_runtime_get(info->dev);
306
bbbd46e3
MB
307 if (info->detecting) {
308 ret = regulator_allow_bypass(info->micvdd, false);
309 if (ret != 0) {
310 dev_err(arizona->dev,
311 "Failed to regulate MICVDD: %d\n",
312 ret);
313 }
314 }
315
9b1270c7
MB
316 ret = regulator_enable(info->micvdd);
317 if (ret != 0) {
318 dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
319 ret);
320 }
321
322 if (info->micd_reva) {
323 regmap_write(arizona->regmap, 0x80, 0x3);
324 regmap_write(arizona->regmap, 0x294, 0);
325 regmap_write(arizona->regmap, 0x80, 0x0);
326 }
327
df8b6771
CK
328 if (info->detecting && arizona->pdata.micd_software_compare)
329 mode = ARIZONA_ACCDET_MODE_ADC;
330 else
331 mode = ARIZONA_ACCDET_MODE_MIC;
332
9b1270c7
MB
333 regmap_update_bits(arizona->regmap,
334 ARIZONA_ACCESSORY_DETECT_MODE_1,
df8b6771 335 ARIZONA_ACCDET_MODE_MASK, mode);
9b1270c7 336
bbbd46e3
MB
337 arizona_extcon_pulse_micbias(info);
338
9b1270c7
MB
339 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
340 ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
341 &change);
342 if (!change) {
343 regulator_disable(info->micvdd);
344 pm_runtime_put_autosuspend(info->dev);
345 }
346}
347
348static void arizona_stop_mic(struct arizona_extcon_info *info)
349{
350 struct arizona *arizona = info->arizona;
bbbd46e3
MB
351 const char *widget = arizona_extcon_get_micbias(info);
352 struct snd_soc_dapm_context *dapm = arizona->dapm;
efd95c71 353 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
9b1270c7 354 bool change;
bbbd46e3 355 int ret;
9b1270c7
MB
356
357 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
358 ARIZONA_MICD_ENA, 0,
359 &change);
360
efd95c71 361 ret = snd_soc_component_disable_pin(component, widget);
bbbd46e3
MB
362 if (ret != 0)
363 dev_warn(arizona->dev,
364 "Failed to disable %s: %d\n",
365 widget, ret);
366
bbbd46e3
MB
367 snd_soc_dapm_sync(dapm);
368
9b1270c7
MB
369 if (info->micd_reva) {
370 regmap_write(arizona->regmap, 0x80, 0x3);
371 regmap_write(arizona->regmap, 0x294, 2);
372 regmap_write(arizona->regmap, 0x80, 0x0);
373 }
374
bbbd46e3
MB
375 ret = regulator_allow_bypass(info->micvdd, true);
376 if (ret != 0) {
377 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
378 ret);
379 }
380
9b1270c7
MB
381 if (change) {
382 regulator_disable(info->micvdd);
383 pm_runtime_mark_last_busy(info->dev);
384 pm_runtime_put_autosuspend(info->dev);
385 }
386}
387
4f340333 388static struct {
24a279b1 389 unsigned int threshold;
4f340333
MB
390 unsigned int factor_a;
391 unsigned int factor_b;
392} arizona_hpdet_b_ranges[] = {
24a279b1
CK
393 { 100, 5528, 362464 },
394 { 169, 11084, 6186851 },
395 { 169, 11065, 65460395 },
4f340333
MB
396};
397
24a279b1
CK
398#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
399
4f340333
MB
400static struct {
401 int min;
402 int max;
403} arizona_hpdet_c_ranges[] = {
404 { 0, 30 },
405 { 8, 100 },
406 { 100, 1000 },
407 { 1000, 10000 },
408};
409
410static int arizona_hpdet_read(struct arizona_extcon_info *info)
411{
412 struct arizona *arizona = info->arizona;
413 unsigned int val, range;
414 int ret;
415
416 ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
417 if (ret != 0) {
418 dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
419 ret);
420 return ret;
421 }
422
d0fd5fbc 423 switch (info->hpdet_ip_version) {
4f340333
MB
424 case 0:
425 if (!(val & ARIZONA_HP_DONE)) {
426 dev_err(arizona->dev, "HPDET did not complete: %x\n",
427 val);
e6dd8cf2 428 return -EAGAIN;
4f340333
MB
429 }
430
431 val &= ARIZONA_HP_LVL_MASK;
432 break;
433
434 case 1:
435 if (!(val & ARIZONA_HP_DONE_B)) {
436 dev_err(arizona->dev, "HPDET did not complete: %x\n",
437 val);
e6dd8cf2 438 return -EAGAIN;
4f340333
MB
439 }
440
441 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
442 if (ret != 0) {
443 dev_err(arizona->dev, "Failed to read HP value: %d\n",
444 ret);
e6dd8cf2 445 return -EAGAIN;
4f340333
MB
446 }
447
448 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
449 &range);
450 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
451 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
452
453 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
24a279b1
CK
454 (val < arizona_hpdet_b_ranges[range].threshold ||
455 val >= ARIZONA_HPDET_B_RANGE_MAX)) {
4f340333
MB
456 range++;
457 dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
458 range);
459 regmap_update_bits(arizona->regmap,
460 ARIZONA_HEADPHONE_DETECT_1,
461 ARIZONA_HP_IMPEDANCE_RANGE_MASK,
462 range <<
463 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
464 return -EAGAIN;
465 }
466
467 /* If we go out of range report top of range */
24a279b1
CK
468 if (val < arizona_hpdet_b_ranges[range].threshold ||
469 val >= ARIZONA_HPDET_B_RANGE_MAX) {
4f340333 470 dev_dbg(arizona->dev, "Measurement out of range\n");
9dd5e53d 471 return ARIZONA_HPDET_MAX;
4f340333
MB
472 }
473
474 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
475 val, range);
476
477 val = arizona_hpdet_b_ranges[range].factor_b
478 / ((val * 100) -
479 arizona_hpdet_b_ranges[range].factor_a);
480 break;
481
4f340333
MB
482 case 2:
483 if (!(val & ARIZONA_HP_DONE_B)) {
484 dev_err(arizona->dev, "HPDET did not complete: %x\n",
485 val);
e6dd8cf2 486 return -EAGAIN;
4f340333
MB
487 }
488
489 val &= ARIZONA_HP_LVL_B_MASK;
77438610
CK
490 /* Convert to ohms, the value is in 0.5 ohm increments */
491 val /= 2;
4f340333
MB
492
493 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
494 &range);
495 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
496 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
497
9141461d 498 /* Skip up a range, or report? */
4f340333
MB
499 if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
500 (val >= arizona_hpdet_c_ranges[range].max)) {
501 range++;
502 dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
503 arizona_hpdet_c_ranges[range].min,
504 arizona_hpdet_c_ranges[range].max);
505 regmap_update_bits(arizona->regmap,
506 ARIZONA_HEADPHONE_DETECT_1,
507 ARIZONA_HP_IMPEDANCE_RANGE_MASK,
508 range <<
509 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
510 return -EAGAIN;
511 }
9141461d
CK
512
513 if (range && (val < arizona_hpdet_c_ranges[range].min)) {
514 dev_dbg(arizona->dev, "Reporting range boundary %d\n",
515 arizona_hpdet_c_ranges[range].min);
516 val = arizona_hpdet_c_ranges[range].min;
517 }
e9844b2c
CC
518 break;
519
520 default:
521 dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
522 info->hpdet_ip_version);
523 return -EINVAL;
4f340333
MB
524 }
525
526 dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
527 return val;
528}
529
9c2ba270
MB
530static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
531 bool *mic)
dd235eea
MB
532{
533 struct arizona *arizona = info->arizona;
1eda6aa7 534 int id_gpio = arizona->pdata.hpdet_id_gpio;
dd235eea
MB
535
536 /*
537 * If we're using HPDET for accessory identification we need
538 * to take multiple measurements, step through them in sequence.
539 */
540 if (arizona->pdata.hpdet_acc_id) {
541 info->hpdet_res[info->num_hpdet_res++] = *reading;
1eda6aa7
MB
542
543 /* Only check the mic directly if we didn't already ID it */
9c2ba270 544 if (id_gpio && info->num_hpdet_res == 1) {
1eda6aa7
MB
545 dev_dbg(arizona->dev, "Measuring mic\n");
546
547 regmap_update_bits(arizona->regmap,
548 ARIZONA_ACCESSORY_DETECT_MODE_1,
549 ARIZONA_ACCDET_MODE_MASK |
550 ARIZONA_ACCDET_SRC,
551 ARIZONA_ACCDET_MODE_HPR |
552 info->micd_modes[0].src);
553
554 gpio_set_value_cansleep(id_gpio, 1);
555
dd235eea
MB
556 regmap_update_bits(arizona->regmap,
557 ARIZONA_HEADPHONE_DETECT_1,
558 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
559 return -EAGAIN;
560 }
561
562 /* OK, got both. Now, compare... */
9c2ba270
MB
563 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
564 info->hpdet_res[0], info->hpdet_res[1]);
c37b387f
MB
565
566 /* Take the headphone impedance for the main report */
567 *reading = info->hpdet_res[0];
568
9dd5e53d
MB
569 /* Sometimes we get false readings due to slow insert */
570 if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
571 dev_dbg(arizona->dev, "Retrying high impedance\n");
572 info->num_hpdet_res = 0;
573 info->hpdet_retried = true;
574 arizona_start_hpdet_acc_id(info);
575 pm_runtime_put(info->dev);
576 return -EAGAIN;
577 }
578
1eda6aa7 579 /*
d97abdde 580 * If we measure the mic as high impedance
1eda6aa7 581 */
9c2ba270 582 if (!id_gpio || info->hpdet_res[1] > 50) {
dd235eea 583 dev_dbg(arizona->dev, "Detected mic\n");
9c2ba270 584 *mic = true;
bf14ee5a 585 info->detecting = true;
dd235eea
MB
586 } else {
587 dev_dbg(arizona->dev, "Detected headphone\n");
588 }
589
590 /* Make sure everything is reset back to the real polarity */
591 regmap_update_bits(arizona->regmap,
592 ARIZONA_ACCESSORY_DETECT_MODE_1,
593 ARIZONA_ACCDET_SRC,
594 info->micd_modes[0].src);
595 }
596
597 return 0;
598}
599
4f340333
MB
600static irqreturn_t arizona_hpdet_irq(int irq, void *data)
601{
602 struct arizona_extcon_info *info = data;
603 struct arizona *arizona = info->arizona;
1eda6aa7 604 int id_gpio = arizona->pdata.hpdet_id_gpio;
11eecf91 605 unsigned int report = EXTCON_JACK_HEADPHONE;
dd235eea 606 int ret, reading;
9c2ba270 607 bool mic = false;
4f340333
MB
608
609 mutex_lock(&info->lock);
610
611 /* If we got a spurious IRQ for some reason then ignore it */
612 if (!info->hpdet_active) {
613 dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
614 mutex_unlock(&info->lock);
615 return IRQ_NONE;
616 }
617
618 /* If the cable was removed while measuring ignore the result */
8670b459 619 ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
4f340333
MB
620 if (ret < 0) {
621 dev_err(arizona->dev, "Failed to check cable state: %d\n",
622 ret);
623 goto out;
624 } else if (!ret) {
625 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
626 goto done;
627 }
628
629 ret = arizona_hpdet_read(info);
d6675667 630 if (ret == -EAGAIN)
4f340333 631 goto out;
d6675667 632 else if (ret < 0)
4f340333 633 goto done;
dd235eea 634 reading = ret;
4f340333
MB
635
636 /* Reset back to starting range */
637 regmap_update_bits(arizona->regmap,
638 ARIZONA_HEADPHONE_DETECT_1,
dd235eea
MB
639 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
640 0);
641
9c2ba270 642 ret = arizona_hpdet_do_id(info, &reading, &mic);
d6675667 643 if (ret == -EAGAIN)
dd235eea 644 goto out;
d6675667 645 else if (ret < 0)
dd235eea 646 goto done;
4f340333
MB
647
648 /* Report high impedence cables as line outputs */
dd235eea 649 if (reading >= 5000)
11eecf91 650 report = EXTCON_JACK_LINE_OUT;
4f340333 651 else
11eecf91 652 report = EXTCON_JACK_HEADPHONE;
4f340333 653
8670b459 654 ret = extcon_set_state_sync(info->edev, report, true);
4f340333
MB
655 if (ret != 0)
656 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
657 ret);
658
a3e00d4b
CK
659done:
660 /* Reset back to starting range */
661 regmap_update_bits(arizona->regmap,
662 ARIZONA_HEADPHONE_DETECT_1,
663 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
664 0);
665
112bdfaa 666 arizona_extcon_hp_clamp(info, false);
4f340333 667
1eda6aa7
MB
668 if (id_gpio)
669 gpio_set_value_cansleep(id_gpio, 0);
4f340333
MB
670
671 /* Revert back to MICDET mode */
672 regmap_update_bits(arizona->regmap,
673 ARIZONA_ACCESSORY_DETECT_MODE_1,
674 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
675
676 /* If we have a mic then reenable MICDET */
9c2ba270 677 if (mic || info->mic)
4f340333
MB
678 arizona_start_mic(info);
679
680 if (info->hpdet_active) {
681 pm_runtime_put_autosuspend(info->dev);
682 info->hpdet_active = false;
683 }
684
bf14ee5a
MB
685 info->hpdet_done = true;
686
4f340333
MB
687out:
688 mutex_unlock(&info->lock);
689
690 return IRQ_HANDLED;
691}
692
693static void arizona_identify_headphone(struct arizona_extcon_info *info)
694{
695 struct arizona *arizona = info->arizona;
696 int ret;
697
bf14ee5a
MB
698 if (info->hpdet_done)
699 return;
700
4f340333
MB
701 dev_dbg(arizona->dev, "Starting HPDET\n");
702
703 /* Make sure we keep the device enabled during the measurement */
704 pm_runtime_get(info->dev);
705
706 info->hpdet_active = true;
707
708 if (info->mic)
709 arizona_stop_mic(info);
710
112bdfaa 711 arizona_extcon_hp_clamp(info, true);
4f340333
MB
712
713 ret = regmap_update_bits(arizona->regmap,
714 ARIZONA_ACCESSORY_DETECT_MODE_1,
715 ARIZONA_ACCDET_MODE_MASK,
9e86b2ad 716 arizona->pdata.hpdet_channel);
4f340333 717 if (ret != 0) {
9e86b2ad 718 dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
4f340333
MB
719 goto err;
720 }
721
722 ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
723 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
724 if (ret != 0) {
725 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
726 ret);
727 goto err;
728 }
729
730 return;
731
732err:
733 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
734 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
735
736 /* Just report headphone */
8670b459 737 ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
4f340333
MB
738 if (ret != 0)
739 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
740
741 if (info->mic)
742 arizona_start_mic(info);
743
744 info->hpdet_active = false;
745}
dd235eea
MB
746
747static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
748{
749 struct arizona *arizona = info->arizona;
9c2ba270
MB
750 int hp_reading = 32;
751 bool mic;
dd235eea
MB
752 int ret;
753
754 dev_dbg(arizona->dev, "Starting identification via HPDET\n");
755
756 /* Make sure we keep the device enabled during the measurement */
0e27bd31 757 pm_runtime_get_sync(info->dev);
dd235eea
MB
758
759 info->hpdet_active = true;
760
112bdfaa 761 arizona_extcon_hp_clamp(info, true);
dd235eea
MB
762
763 ret = regmap_update_bits(arizona->regmap,
764 ARIZONA_ACCESSORY_DETECT_MODE_1,
765 ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
766 info->micd_modes[0].src |
9e86b2ad 767 arizona->pdata.hpdet_channel);
dd235eea 768 if (ret != 0) {
9e86b2ad 769 dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
dd235eea
MB
770 goto err;
771 }
772
9c2ba270
MB
773 if (arizona->pdata.hpdet_acc_id_line) {
774 ret = regmap_update_bits(arizona->regmap,
775 ARIZONA_HEADPHONE_DETECT_1,
776 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
777 if (ret != 0) {
778 dev_err(arizona->dev,
779 "Can't start HPDETL measurement: %d\n",
780 ret);
781 goto err;
782 }
783 } else {
784 arizona_hpdet_do_id(info, &hp_reading, &mic);
4f340333
MB
785 }
786
dd235eea
MB
787 return;
788
789err:
790 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
791 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
792
793 /* Just report headphone */
8670b459 794 ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
dd235eea
MB
795 if (ret != 0)
796 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
797
4f340333
MB
798 info->hpdet_active = false;
799}
800
939c5671
MB
801static void arizona_micd_timeout_work(struct work_struct *work)
802{
803 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
804 struct arizona_extcon_info,
805 micd_timeout_work.work);
939c5671
MB
806
807 mutex_lock(&info->lock);
808
809 dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
939c5671
MB
810
811 info->detecting = false;
812
0ffe8cbd
CK
813 arizona_identify_headphone(info);
814
939c5671
MB
815 arizona_stop_mic(info);
816
817 mutex_unlock(&info->lock);
818}
819
cd59e796 820static void arizona_micd_detect(struct work_struct *work)
f2c32a88 821{
cd59e796 822 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
823 struct arizona_extcon_info,
824 micd_detect_work.work);
f2c32a88 825 struct arizona *arizona = info->arizona;
e2c0f476 826 unsigned int val = 0, lvl;
6fed4d86 827 int ret, i, key;
f2c32a88 828
939c5671
MB
829 cancel_delayed_work_sync(&info->micd_timeout_work);
830
f2c32a88
MB
831 mutex_lock(&info->lock);
832
31a847e6 833 /* If the cable was removed while measuring ignore the result */
8670b459 834 ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
31a847e6
CK
835 if (ret < 0) {
836 dev_err(arizona->dev, "Failed to check cable state: %d\n",
837 ret);
838 mutex_unlock(&info->lock);
839 return;
840 } else if (!ret) {
841 dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
842 mutex_unlock(&info->lock);
843 return;
844 }
845
df8b6771
CK
846 if (info->detecting && arizona->pdata.micd_software_compare) {
847 /* Must disable MICD before we read the ADCVAL */
848 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
849 ARIZONA_MICD_ENA, 0);
850 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
851 if (ret != 0) {
852 dev_err(arizona->dev,
853 "Failed to read MICDET_ADCVAL: %d\n",
854 ret);
855 mutex_unlock(&info->lock);
856 return;
857 }
858
859 dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
860
861 val &= ARIZONA_MICDET_ADCVAL_MASK;
862 if (val < ARRAY_SIZE(arizona_micd_levels))
863 val = arizona_micd_levels[val];
864 else
865 val = INT_MAX;
866
867 if (val <= QUICK_HEADPHONE_MAX_OHM)
868 val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
869 else if (val <= MICROPHONE_MIN_OHM)
870 val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
871 else if (val <= MICROPHONE_MAX_OHM)
872 val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
873 else
874 val = ARIZONA_MICD_LVL_8;
875 }
876
ffae24fe 877 for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
e2c0f476
CK
878 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
879 if (ret != 0) {
c2275d2f
CC
880 dev_err(arizona->dev,
881 "Failed to read MICDET: %d\n", ret);
e2c0f476 882 mutex_unlock(&info->lock);
cd59e796 883 return;
e2c0f476
CK
884 }
885
886 dev_dbg(arizona->dev, "MICDET: %x\n", val);
f2c32a88 887
e2c0f476 888 if (!(val & ARIZONA_MICD_VALID)) {
c2275d2f
CC
889 dev_warn(arizona->dev,
890 "Microphone detection state invalid\n");
e2c0f476 891 mutex_unlock(&info->lock);
cd59e796 892 return;
e2c0f476
CK
893 }
894 }
f2c32a88 895
ffae24fe 896 if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
e2c0f476 897 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
f2c32a88 898 mutex_unlock(&info->lock);
cd59e796 899 return;
f2c32a88
MB
900 }
901
902 /* Due to jack detect this should never happen */
903 if (!(val & ARIZONA_MICD_STS)) {
904 dev_warn(arizona->dev, "Detected open circuit\n");
57f70ef9
CK
905 info->mic = false;
906 arizona_stop_mic(info);
f2c32a88 907 info->detecting = false;
57f70ef9 908 arizona_identify_headphone(info);
f2c32a88
MB
909 goto handled;
910 }
911
912 /* If we got a high impedence we should have a headset, report it. */
ffae24fe 913 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
0ffe8cbd
CK
914 info->mic = true;
915 info->detecting = false;
916
4f340333
MB
917 arizona_identify_headphone(info);
918
8670b459 919 ret = extcon_set_state_sync(info->edev,
11eecf91 920 EXTCON_JACK_MICROPHONE, true);
f2c32a88
MB
921 if (ret != 0)
922 dev_err(arizona->dev, "Headset report failed: %d\n",
923 ret);
924
bbbd46e3 925 /* Don't need to regulate for button detection */
e368f525 926 ret = regulator_allow_bypass(info->micvdd, true);
bbbd46e3
MB
927 if (ret != 0) {
928 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
929 ret);
930 }
931
f2c32a88
MB
932 goto handled;
933 }
934
935 /* If we detected a lower impedence during initial startup
936 * then we probably have the wrong polarity, flip it. Don't
937 * do this for the lowest impedences to speed up detection of
938 * plain headphones. If both polarities report a low
939 * impedence then give up and report headphones.
940 */
ffae24fe 941 if (info->detecting && (val & MICD_LVL_1_TO_7)) {
84eaa136 942 if (info->jack_flips >= info->micd_num_modes * 10) {
4f340333 943 dev_dbg(arizona->dev, "Detected HP/line\n");
4f340333 944
f2c32a88 945 info->detecting = false;
9ef2224d 946
0ffe8cbd
CK
947 arizona_identify_headphone(info);
948
4f340333 949 arizona_stop_mic(info);
f2c32a88
MB
950 } else {
951 info->micd_mode++;
952 if (info->micd_mode == info->micd_num_modes)
953 info->micd_mode = 0;
954 arizona_extcon_set_mode(info, info->micd_mode);
955
956 info->jack_flips++;
957 }
958
959 goto handled;
960 }
961
962 /*
963 * If we're still detecting and we detect a short then we've
34efe4dc 964 * got a headphone. Otherwise it's a button press.
f2c32a88 965 */
ffae24fe 966 if (val & MICD_LVL_0_TO_7) {
f2c32a88
MB
967 if (info->mic) {
968 dev_dbg(arizona->dev, "Mic button detected\n");
969
34efe4dc
MB
970 lvl = val & ARIZONA_MICD_LVL_MASK;
971 lvl >>= ARIZONA_MICD_LVL_SHIFT;
972
41a57850
MB
973 for (i = 0; i < info->num_micd_ranges; i++)
974 input_report_key(info->input,
975 info->micd_ranges[i].key, 0);
976
6fed4d86
MB
977 WARN_ON(!lvl);
978 WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
979 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
980 key = info->micd_ranges[ffs(lvl) - 1].key;
981 input_report_key(info->input, key, 1);
982 input_sync(info->input);
983 }
34efe4dc 984
f2c32a88
MB
985 } else if (info->detecting) {
986 dev_dbg(arizona->dev, "Headphone detected\n");
987 info->detecting = false;
988 arizona_stop_mic(info);
989
4f340333 990 arizona_identify_headphone(info);
f2c32a88
MB
991 } else {
992 dev_warn(arizona->dev, "Button with no mic: %x\n",
993 val);
994 }
995 } else {
996 dev_dbg(arizona->dev, "Mic button released\n");
6fed4d86 997 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 998 input_report_key(info->input,
6fed4d86 999 info->micd_ranges[i].key, 0);
34efe4dc 1000 input_sync(info->input);
bbbd46e3 1001 arizona_extcon_pulse_micbias(info);
f2c32a88
MB
1002 }
1003
1004handled:
df8b6771
CK
1005 if (info->detecting) {
1006 if (arizona->pdata.micd_software_compare)
1007 regmap_update_bits(arizona->regmap,
1008 ARIZONA_MIC_DETECT_1,
1009 ARIZONA_MICD_ENA,
1010 ARIZONA_MICD_ENA);
1011
df9a5ab4
MB
1012 queue_delayed_work(system_power_efficient_wq,
1013 &info->micd_timeout_work,
1014 msecs_to_jiffies(info->micd_timeout));
df8b6771 1015 }
939c5671 1016
f2c32a88
MB
1017 pm_runtime_mark_last_busy(info->dev);
1018 mutex_unlock(&info->lock);
cd59e796
MB
1019}
1020
1021static irqreturn_t arizona_micdet(int irq, void *data)
1022{
1023 struct arizona_extcon_info *info = data;
1024 struct arizona *arizona = info->arizona;
1025 int debounce = arizona->pdata.micd_detect_debounce;
1026
1027 cancel_delayed_work_sync(&info->micd_detect_work);
1028 cancel_delayed_work_sync(&info->micd_timeout_work);
1029
1030 mutex_lock(&info->lock);
1031 if (!info->detecting)
1032 debounce = 0;
1033 mutex_unlock(&info->lock);
1034
1035 if (debounce)
df9a5ab4
MB
1036 queue_delayed_work(system_power_efficient_wq,
1037 &info->micd_detect_work,
1038 msecs_to_jiffies(debounce));
cd59e796
MB
1039 else
1040 arizona_micd_detect(&info->micd_detect_work.work);
f2c32a88
MB
1041
1042 return IRQ_HANDLED;
1043}
1044
0e27bd31
MB
1045static void arizona_hpdet_work(struct work_struct *work)
1046{
1047 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
1048 struct arizona_extcon_info,
1049 hpdet_work.work);
0e27bd31
MB
1050
1051 mutex_lock(&info->lock);
1052 arizona_start_hpdet_acc_id(info);
1053 mutex_unlock(&info->lock);
1054}
1055
f2c32a88
MB
1056static irqreturn_t arizona_jackdet(int irq, void *data)
1057{
1058 struct arizona_extcon_info *info = data;
1059 struct arizona *arizona = info->arizona;
92a49871 1060 unsigned int val, present, mask;
939c5671 1061 bool cancelled_hp, cancelled_mic;
34efe4dc 1062 int ret, i;
f2c32a88 1063
939c5671
MB
1064 cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
1065 cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
f2c32a88 1066
a3e2078d 1067 pm_runtime_get_sync(info->dev);
0e27bd31 1068
f2c32a88
MB
1069 mutex_lock(&info->lock);
1070
ff1cb0ed 1071 if (info->micd_clamp) {
92a49871 1072 mask = ARIZONA_MICD_CLAMP_STS;
a0ef6428 1073 present = 0;
92a49871
MB
1074 } else {
1075 mask = ARIZONA_JD1_STS;
a288d648
RF
1076 if (arizona->pdata.jd_invert)
1077 present = 0;
1078 else
1079 present = ARIZONA_JD1_STS;
92a49871
MB
1080 }
1081
f2c32a88
MB
1082 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
1083 if (ret != 0) {
1084 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
1085 ret);
1086 mutex_unlock(&info->lock);
1087 pm_runtime_put_autosuspend(info->dev);
1088 return IRQ_NONE;
1089 }
1090
a3e2078d
MB
1091 val &= mask;
1092 if (val == info->last_jackdet) {
1093 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
939c5671 1094 if (cancelled_hp)
df9a5ab4
MB
1095 queue_delayed_work(system_power_efficient_wq,
1096 &info->hpdet_work,
1097 msecs_to_jiffies(HPDET_DEBOUNCE));
a3e2078d 1098
c2275d2f
CC
1099 if (cancelled_mic) {
1100 int micd_timeout = info->micd_timeout;
1101
df9a5ab4
MB
1102 queue_delayed_work(system_power_efficient_wq,
1103 &info->micd_timeout_work,
c2275d2f
CC
1104 msecs_to_jiffies(micd_timeout));
1105 }
939c5671 1106
a3e2078d
MB
1107 goto out;
1108 }
1109 info->last_jackdet = val;
1110
1111 if (info->last_jackdet == present) {
f2c32a88 1112 dev_dbg(arizona->dev, "Detected jack\n");
8670b459 1113 ret = extcon_set_state_sync(info->edev,
2a9de9c0 1114 EXTCON_MECHANICAL, true);
f2c32a88
MB
1115
1116 if (ret != 0)
1117 dev_err(arizona->dev, "Mechanical report failed: %d\n",
1118 ret);
1119
dd235eea
MB
1120 if (!arizona->pdata.hpdet_acc_id) {
1121 info->detecting = true;
1122 info->mic = false;
1123 info->jack_flips = 0;
1124
1125 arizona_start_mic(info);
1126 } else {
df9a5ab4
MB
1127 queue_delayed_work(system_power_efficient_wq,
1128 &info->hpdet_work,
1129 msecs_to_jiffies(HPDET_DEBOUNCE));
dd235eea 1130 }
4e616877 1131
6c20b934
CK
1132 if (info->micd_clamp || !arizona->pdata.jd_invert)
1133 regmap_update_bits(arizona->regmap,
1134 ARIZONA_JACK_DETECT_DEBOUNCE,
1135 ARIZONA_MICD_CLAMP_DB |
1136 ARIZONA_JD1_DB, 0);
f2c32a88
MB
1137 } else {
1138 dev_dbg(arizona->dev, "Detected jack removal\n");
1139
1140 arizona_stop_mic(info);
1141
dd235eea
MB
1142 info->num_hpdet_res = 0;
1143 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1144 info->hpdet_res[i] = 0;
1145 info->mic = false;
bf14ee5a 1146 info->hpdet_done = false;
9dd5e53d 1147 info->hpdet_retried = false;
92a49871 1148
6fed4d86 1149 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 1150 input_report_key(info->input,
6fed4d86 1151 info->micd_ranges[i].key, 0);
34efe4dc
MB
1152 input_sync(info->input);
1153
5475e631 1154 for (i = 0; i < ARRAY_SIZE(arizona_cable) - 1; i++) {
8670b459 1155 ret = extcon_set_state_sync(info->edev,
5475e631
CC
1156 arizona_cable[i], false);
1157 if (ret != 0)
1158 dev_err(arizona->dev,
1159 "Removal report failed: %d\n", ret);
1160 }
4e616877
MB
1161
1162 regmap_update_bits(arizona->regmap,
1163 ARIZONA_JACK_DETECT_DEBOUNCE,
1164 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1165 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
f2c32a88
MB
1166 }
1167
7abd4e2a
MB
1168 if (arizona->pdata.micd_timeout)
1169 info->micd_timeout = arizona->pdata.micd_timeout;
1170 else
1171 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1172
cb9005d7 1173out:
5d9ab708
CK
1174 /* Clear trig_sts to make sure DCVDD is not forced up */
1175 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1176 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1177 ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1178 ARIZONA_JD1_FALL_TRIG_STS |
1179 ARIZONA_JD1_RISE_TRIG_STS);
1180
f2c32a88
MB
1181 mutex_unlock(&info->lock);
1182
1183 pm_runtime_mark_last_busy(info->dev);
1184 pm_runtime_put_autosuspend(info->dev);
1185
1186 return IRQ_HANDLED;
1187}
1188
6fed4d86
MB
1189/* Map a level onto a slot in the register bank */
1190static void arizona_micd_set_level(struct arizona *arizona, int index,
1191 unsigned int level)
1192{
1193 int reg;
1194 unsigned int mask;
1195
1196 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1197
1198 if (!(index % 2)) {
1199 mask = 0x3f00;
1200 level <<= 8;
1201 } else {
1202 mask = 0x3f;
1203 }
1204
1205 /* Program the level itself */
1206 regmap_update_bits(arizona->regmap, reg, mask, level);
1207}
1208
bb6da5d9
CK
1209static int arizona_extcon_get_micd_configs(struct device *dev,
1210 struct arizona *arizona)
1211{
1212 const char * const prop = "wlf,micd-configs";
1213 const int entries_per_config = 3;
1214 struct arizona_micd_config *micd_configs;
1215 int nconfs, ret;
1216 int i, j;
1217 u32 *vals;
1218
1219 nconfs = device_property_read_u32_array(arizona->dev, prop, NULL, 0);
1220 if (nconfs <= 0)
1221 return 0;
1222
1223 vals = kcalloc(nconfs, sizeof(u32), GFP_KERNEL);
1224 if (!vals)
1225 return -ENOMEM;
1226
1227 ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs);
1228 if (ret < 0)
1229 goto out;
1230
1231 nconfs /= entries_per_config;
1232
1233 micd_configs = devm_kzalloc(dev,
1234 nconfs * sizeof(struct arizona_micd_range),
1235 GFP_KERNEL);
1236 if (!micd_configs) {
1237 ret = -ENOMEM;
1238 goto out;
1239 }
1240
1241 for (i = 0, j = 0; i < nconfs; ++i) {
1242 micd_configs[i].src = vals[j++] ? ARIZONA_ACCDET_SRC : 0;
1243 micd_configs[i].bias = vals[j++];
1244 micd_configs[i].gpio = vals[j++];
1245 }
1246
1247 arizona->pdata.micd_configs = micd_configs;
1248 arizona->pdata.num_micd_configs = nconfs;
1249
1250out:
1251 kfree(vals);
1252 return ret;
1253}
1254
1255static int arizona_extcon_device_get_pdata(struct device *dev,
1256 struct arizona *arizona)
9e86b2ad
IS
1257{
1258 struct arizona_pdata *pdata = &arizona->pdata;
1259 unsigned int val = ARIZONA_ACCDET_MODE_HPL;
bb6da5d9 1260 int ret;
9e86b2ad 1261
feffb0cc 1262 device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val);
9e86b2ad
IS
1263 switch (val) {
1264 case ARIZONA_ACCDET_MODE_HPL:
1265 case ARIZONA_ACCDET_MODE_HPR:
1266 pdata->hpdet_channel = val;
1267 break;
1268 default:
1269 dev_err(arizona->dev,
1270 "Wrong wlf,hpdet-channel DT value %d\n", val);
1271 pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
1272 }
1273
4778d44f
CK
1274 device_property_read_u32(arizona->dev, "wlf,micd-detect-debounce",
1275 &pdata->micd_detect_debounce);
1276
1277 device_property_read_u32(arizona->dev, "wlf,micd-bias-start-time",
1278 &pdata->micd_bias_start_time);
1279
1280 device_property_read_u32(arizona->dev, "wlf,micd-rate",
1281 &pdata->micd_rate);
1282
1283 device_property_read_u32(arizona->dev, "wlf,micd-dbtime",
1284 &pdata->micd_dbtime);
1285
7a7ef0f2 1286 device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms",
4778d44f
CK
1287 &pdata->micd_timeout);
1288
1289 pdata->micd_force_micbias = device_property_read_bool(arizona->dev,
1290 "wlf,micd-force-micbias");
1291
2e87b7a8
CK
1292 pdata->micd_software_compare = device_property_read_bool(arizona->dev,
1293 "wlf,micd-software-compare");
1294
3d7a872f
CK
1295 pdata->jd_invert = device_property_read_bool(arizona->dev,
1296 "wlf,jd-invert");
1297
99374227
CK
1298 device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw);
1299
35247c13 1300 pdata->jd_gpio5 = device_property_read_bool(arizona->dev,
832df9e8 1301 "wlf,use-jd2");
35247c13 1302 pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev,
832df9e8 1303 "wlf,use-jd2-nopull");
35247c13 1304
bb6da5d9
CK
1305 ret = arizona_extcon_get_micd_configs(dev, arizona);
1306 if (ret < 0)
1307 dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret);
1308
9e86b2ad
IS
1309 return 0;
1310}
1311
44f34fd4 1312static int arizona_extcon_probe(struct platform_device *pdev)
f2c32a88
MB
1313{
1314 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
6ac6b475 1315 struct arizona_pdata *pdata = &arizona->pdata;
f2c32a88 1316 struct arizona_extcon_info *info;
e56a0a57 1317 unsigned int val;
a288d648 1318 unsigned int clamp_mode;
92a49871 1319 int jack_irq_fall, jack_irq_rise;
6fed4d86 1320 int ret, mode, i, j;
f2c32a88 1321
bbbd46e3
MB
1322 if (!arizona->dapm || !arizona->dapm->card)
1323 return -EPROBE_DEFER;
1324
f2c32a88 1325 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0a16ee63 1326 if (!info)
d88cc367 1327 return -ENOMEM;
f2c32a88 1328
feffb0cc 1329 if (!dev_get_platdata(arizona->dev))
bb6da5d9 1330 arizona_extcon_device_get_pdata(&pdev->dev, arizona);
9e86b2ad 1331
17271f60 1332 info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
f2c32a88
MB
1333 if (IS_ERR(info->micvdd)) {
1334 ret = PTR_ERR(info->micvdd);
1335 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
d88cc367 1336 return ret;
f2c32a88
MB
1337 }
1338
1339 mutex_init(&info->lock);
1340 info->arizona = arizona;
1341 info->dev = &pdev->dev;
a3e2078d 1342 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
0e27bd31 1343 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
cd59e796 1344 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
939c5671 1345 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
f2c32a88
MB
1346 platform_set_drvdata(pdev, info);
1347
1348 switch (arizona->type) {
1349 case WM5102:
1350 switch (arizona->rev) {
1351 case 0:
1352 info->micd_reva = true;
1353 break;
1354 default:
dab63eb2 1355 info->micd_clamp = true;
d0fd5fbc 1356 info->hpdet_ip_version = 1;
f2c32a88
MB
1357 break;
1358 }
1359 break;
77438610 1360 case WM5110:
2f2b6aa8 1361 case WM8280:
77438610
CK
1362 switch (arizona->rev) {
1363 case 0 ... 2:
1364 break;
1365 default:
1366 info->micd_clamp = true;
d0fd5fbc 1367 info->hpdet_ip_version = 2;
77438610
CK
1368 break;
1369 }
1370 break;
d8d09564
RF
1371 case WM8998:
1372 case WM1814:
1373 info->micd_clamp = true;
1374 info->hpdet_ip_version = 2;
1375 break;
f2c32a88
MB
1376 default:
1377 break;
1378 }
1379
ef70a214
CC
1380 info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
1381 if (IS_ERR(info->edev)) {
1382 dev_err(&pdev->dev, "failed to allocate extcon device\n");
1383 return -ENOMEM;
1384 }
f2c32a88 1385
ef70a214 1386 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
f2c32a88 1387 if (ret < 0) {
8e5f5018 1388 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
f2c32a88 1389 ret);
d88cc367 1390 return ret;
f2c32a88
MB
1391 }
1392
6fed4d86
MB
1393 info->input = devm_input_allocate_device(&pdev->dev);
1394 if (!info->input) {
1395 dev_err(arizona->dev, "Can't allocate input dev\n");
1396 ret = -ENOMEM;
1397 goto err_register;
1398 }
1399
1400 info->input->name = "Headset";
1401 info->input->phys = "arizona/extcon";
6fed4d86 1402
f2c32a88
MB
1403 if (pdata->num_micd_configs) {
1404 info->micd_modes = pdata->micd_configs;
1405 info->micd_num_modes = pdata->num_micd_configs;
1406 } else {
1407 info->micd_modes = micd_default_modes;
1408 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1409 }
1410
6772a5ab
CK
1411 if (arizona->pdata.gpsw > 0)
1412 regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1,
1413 ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw);
1414
f2c32a88
MB
1415 if (arizona->pdata.micd_pol_gpio > 0) {
1416 if (info->micd_modes[0].gpio)
1417 mode = GPIOF_OUT_INIT_HIGH;
1418 else
1419 mode = GPIOF_OUT_INIT_LOW;
1420
1421 ret = devm_gpio_request_one(&pdev->dev,
1422 arizona->pdata.micd_pol_gpio,
1423 mode,
1424 "MICD polarity");
1425 if (ret != 0) {
1426 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1427 arizona->pdata.micd_pol_gpio, ret);
1428 goto err_register;
1429 }
8e5838dd
CK
1430 } else {
1431 if (info->micd_modes[0].gpio)
1432 mode = GPIOD_OUT_HIGH;
1433 else
1434 mode = GPIOD_OUT_LOW;
1435
1436 /* We can't use devm here because we need to do the get
1437 * against the MFD device, as that is where the of_node
1438 * will reside, but if we devm against that the GPIO
1439 * will not be freed if the extcon driver is unloaded.
1440 */
1441 info->micd_pol_gpio = gpiod_get_optional(arizona->dev,
1442 "wlf,micd-pol",
1443 GPIOD_OUT_LOW);
1444 if (IS_ERR(info->micd_pol_gpio)) {
1445 ret = PTR_ERR(info->micd_pol_gpio);
1446 dev_err(arizona->dev,
1447 "Failed to get microphone polarity GPIO: %d\n",
1448 ret);
1449 goto err_register;
1450 }
f2c32a88
MB
1451 }
1452
1eda6aa7
MB
1453 if (arizona->pdata.hpdet_id_gpio > 0) {
1454 ret = devm_gpio_request_one(&pdev->dev,
1455 arizona->pdata.hpdet_id_gpio,
1456 GPIOF_OUT_INIT_LOW,
1457 "HPDET");
1458 if (ret != 0) {
1459 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1460 arizona->pdata.hpdet_id_gpio, ret);
8e5838dd 1461 goto err_gpio;
1eda6aa7
MB
1462 }
1463 }
1464
b17e5462
MB
1465 if (arizona->pdata.micd_bias_start_time)
1466 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1467 ARIZONA_MICD_BIAS_STARTTIME_MASK,
1468 arizona->pdata.micd_bias_start_time
1469 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1470
2e033db5
MB
1471 if (arizona->pdata.micd_rate)
1472 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1473 ARIZONA_MICD_RATE_MASK,
1474 arizona->pdata.micd_rate
1475 << ARIZONA_MICD_RATE_SHIFT);
1476
bb327e92
CK
1477 switch (arizona->pdata.micd_dbtime) {
1478 case MICD_DBTIME_FOUR_READINGS:
2e033db5
MB
1479 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1480 ARIZONA_MICD_DBTIME_MASK,
bb327e92
CK
1481 ARIZONA_MICD_DBTIME);
1482 break;
1483 case MICD_DBTIME_TWO_READINGS:
1484 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1485 ARIZONA_MICD_DBTIME_MASK, 0);
1486 break;
1487 default:
1488 break;
1489 }
2e033db5 1490
df8b6771
CK
1491 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) <
1492 ARIZONA_NUM_MICD_BUTTON_LEVELS);
6fed4d86
MB
1493
1494 if (arizona->pdata.num_micd_ranges) {
1495 info->micd_ranges = pdata->micd_ranges;
1496 info->num_micd_ranges = pdata->num_micd_ranges;
1497 } else {
1498 info->micd_ranges = micd_default_ranges;
1499 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1500 }
1501
1502 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1503 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1504 arizona->pdata.num_micd_ranges);
1505 }
1506
1507 if (info->num_micd_ranges > 1) {
1508 for (i = 1; i < info->num_micd_ranges; i++) {
1509 if (info->micd_ranges[i - 1].max >
1510 info->micd_ranges[i].max) {
1511 dev_err(arizona->dev,
1512 "MICD ranges must be sorted\n");
1513 ret = -EINVAL;
8e5838dd 1514 goto err_gpio;
6fed4d86
MB
1515 }
1516 }
1517 }
1518
1519 /* Disable all buttons by default */
1520 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1521 ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1522
1523 /* Set up all the buttons the user specified */
1524 for (i = 0; i < info->num_micd_ranges; i++) {
df8b6771 1525 for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++)
6fed4d86
MB
1526 if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1527 break;
1528
df8b6771 1529 if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) {
6fed4d86
MB
1530 dev_err(arizona->dev, "Unsupported MICD level %d\n",
1531 info->micd_ranges[i].max);
1532 ret = -EINVAL;
8e5838dd 1533 goto err_gpio;
6fed4d86
MB
1534 }
1535
1536 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1537 arizona_micd_levels[j], i);
1538
1539 arizona_micd_set_level(arizona, i, j);
1540 input_set_capability(info->input, EV_KEY,
1541 info->micd_ranges[i].key);
1542
1543 /* Enable reporting of that range */
1544 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1545 1 << i, 1 << i);
1546 }
1547
1548 /* Set all the remaining keys to a maximum */
1549 for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1550 arizona_micd_set_level(arizona, i, 0x3f);
1551
dab63eb2 1552 /*
92a49871
MB
1553 * If we have a clamp use it, activating in conjunction with
1554 * GPIO5 if that is connected for jack detect operation.
dab63eb2
MB
1555 */
1556 if (info->micd_clamp) {
92a49871 1557 if (arizona->pdata.jd_gpio5) {
e56a0a57
MB
1558 /* Put the GPIO into input mode with optional pull */
1559 val = 0xc101;
1560 if (arizona->pdata.jd_gpio5_nopull)
1561 val &= ~ARIZONA_GPN_PU;
1562
92a49871 1563 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
e56a0a57 1564 val);
92a49871 1565
a288d648
RF
1566 if (arizona->pdata.jd_invert)
1567 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
1568 else
1569 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
92a49871 1570 } else {
a288d648
RF
1571 if (arizona->pdata.jd_invert)
1572 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
1573 else
1574 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
92a49871
MB
1575 }
1576
a288d648
RF
1577 regmap_update_bits(arizona->regmap,
1578 ARIZONA_MICD_CLAMP_CONTROL,
1579 ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
1580
dab63eb2
MB
1581 regmap_update_bits(arizona->regmap,
1582 ARIZONA_JACK_DETECT_DEBOUNCE,
1583 ARIZONA_MICD_CLAMP_DB,
1584 ARIZONA_MICD_CLAMP_DB);
1585 }
1586
f2c32a88
MB
1587 arizona_extcon_set_mode(info, 0);
1588
1589 pm_runtime_enable(&pdev->dev);
1590 pm_runtime_idle(&pdev->dev);
1591 pm_runtime_get_sync(&pdev->dev);
1592
ff1cb0ed 1593 if (info->micd_clamp) {
92a49871
MB
1594 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1595 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1596 } else {
1597 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1598 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1599 }
1600
1601 ret = arizona_request_irq(arizona, jack_irq_rise,
f2c32a88
MB
1602 "JACKDET rise", arizona_jackdet, info);
1603 if (ret != 0) {
1604 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1605 ret);
8e5838dd 1606 goto err_gpio;
f2c32a88
MB
1607 }
1608
92a49871 1609 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
f2c32a88
MB
1610 if (ret != 0) {
1611 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1612 ret);
1613 goto err_rise;
1614 }
1615
92a49871 1616 ret = arizona_request_irq(arizona, jack_irq_fall,
f2c32a88
MB
1617 "JACKDET fall", arizona_jackdet, info);
1618 if (ret != 0) {
1619 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1620 goto err_rise_wake;
1621 }
1622
92a49871 1623 ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
f2c32a88
MB
1624 if (ret != 0) {
1625 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1626 ret);
1627 goto err_fall;
1628 }
1629
1630 ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1631 "MICDET", arizona_micdet, info);
1632 if (ret != 0) {
1633 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1634 goto err_fall_wake;
1635 }
1636
4f340333
MB
1637 ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1638 "HPDET", arizona_hpdet_irq, info);
1639 if (ret != 0) {
1640 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1641 goto err_micdet;
1642 }
1643
f2c32a88
MB
1644 arizona_clk32k_enable(arizona);
1645 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1646 ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1647 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1648 ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1649
b8575a11
MB
1650 ret = regulator_allow_bypass(info->micvdd, true);
1651 if (ret != 0)
1652 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1653 ret);
1654
f2c32a88
MB
1655 pm_runtime_put(&pdev->dev);
1656
34efe4dc
MB
1657 ret = input_register_device(info->input);
1658 if (ret) {
1659 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
4f340333 1660 goto err_hpdet;
34efe4dc
MB
1661 }
1662
f2c32a88
MB
1663 return 0;
1664
4f340333
MB
1665err_hpdet:
1666 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
80732cc1
MB
1667err_micdet:
1668 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
f2c32a88 1669err_fall_wake:
92a49871 1670 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
f2c32a88 1671err_fall:
92a49871 1672 arizona_free_irq(arizona, jack_irq_fall, info);
f2c32a88 1673err_rise_wake:
92a49871 1674 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
f2c32a88 1675err_rise:
92a49871 1676 arizona_free_irq(arizona, jack_irq_rise, info);
8e5838dd
CK
1677err_gpio:
1678 gpiod_put(info->micd_pol_gpio);
f2c32a88
MB
1679err_register:
1680 pm_runtime_disable(&pdev->dev);
f2c32a88
MB
1681 return ret;
1682}
1683
93ed0327 1684static int arizona_extcon_remove(struct platform_device *pdev)
f2c32a88
MB
1685{
1686 struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1687 struct arizona *arizona = info->arizona;
92a49871 1688 int jack_irq_rise, jack_irq_fall;
f2c32a88 1689
8e5838dd
CK
1690 gpiod_put(info->micd_pol_gpio);
1691
f2c32a88
MB
1692 pm_runtime_disable(&pdev->dev);
1693
dab63eb2
MB
1694 regmap_update_bits(arizona->regmap,
1695 ARIZONA_MICD_CLAMP_CONTROL,
1696 ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1697
ff1cb0ed 1698 if (info->micd_clamp) {
92a49871
MB
1699 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1700 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1701 } else {
1702 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1703 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1704 }
1705
1706 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1707 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1708 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
f2c32a88 1709 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
92a49871
MB
1710 arizona_free_irq(arizona, jack_irq_rise, info);
1711 arizona_free_irq(arizona, jack_irq_fall, info);
0e27bd31 1712 cancel_delayed_work_sync(&info->hpdet_work);
f2c32a88
MB
1713 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1714 ARIZONA_JD1_ENA, 0);
1715 arizona_clk32k_disable(arizona);
f2c32a88
MB
1716
1717 return 0;
1718}
1719
1720static struct platform_driver arizona_extcon_driver = {
1721 .driver = {
1722 .name = "arizona-extcon",
f2c32a88
MB
1723 },
1724 .probe = arizona_extcon_probe,
5f7e2228 1725 .remove = arizona_extcon_remove,
f2c32a88
MB
1726};
1727
1728module_platform_driver(arizona_extcon_driver);
1729
1730MODULE_DESCRIPTION("Arizona Extcon driver");
1731MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1732MODULE_LICENSE("GPL");
1733MODULE_ALIAS("platform:extcon-arizona");