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