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