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