extcon: arizona: Use the micd_clamp for interrupts if it is available
[deliverable/linux.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
MB
1120
1121 regmap_update_bits(arizona->regmap,
1122 ARIZONA_JACK_DETECT_DEBOUNCE,
1123 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
f2c32a88
MB
1124 } else {
1125 dev_dbg(arizona->dev, "Detected jack removal\n");
1126
1127 arizona_stop_mic(info);
1128
dd235eea
MB
1129 info->num_hpdet_res = 0;
1130 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1131 info->hpdet_res[i] = 0;
1132 info->mic = false;
bf14ee5a 1133 info->hpdet_done = false;
9dd5e53d 1134 info->hpdet_retried = false;
92a49871 1135
6fed4d86 1136 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 1137 input_report_key(info->input,
6fed4d86 1138 info->micd_ranges[i].key, 0);
34efe4dc
MB
1139 input_sync(info->input);
1140
ef70a214 1141 ret = extcon_update_state(info->edev, 0xffffffff, 0);
f2c32a88
MB
1142 if (ret != 0)
1143 dev_err(arizona->dev, "Removal report failed: %d\n",
1144 ret);
4e616877
MB
1145
1146 regmap_update_bits(arizona->regmap,
1147 ARIZONA_JACK_DETECT_DEBOUNCE,
1148 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1149 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
f2c32a88
MB
1150 }
1151
7abd4e2a
MB
1152 if (arizona->pdata.micd_timeout)
1153 info->micd_timeout = arizona->pdata.micd_timeout;
1154 else
1155 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1156
cb9005d7 1157out:
5d9ab708
CK
1158 /* Clear trig_sts to make sure DCVDD is not forced up */
1159 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1160 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1161 ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1162 ARIZONA_JD1_FALL_TRIG_STS |
1163 ARIZONA_JD1_RISE_TRIG_STS);
1164
f2c32a88
MB
1165 mutex_unlock(&info->lock);
1166
1167 pm_runtime_mark_last_busy(info->dev);
1168 pm_runtime_put_autosuspend(info->dev);
1169
1170 return IRQ_HANDLED;
1171}
1172
6fed4d86
MB
1173/* Map a level onto a slot in the register bank */
1174static void arizona_micd_set_level(struct arizona *arizona, int index,
1175 unsigned int level)
1176{
1177 int reg;
1178 unsigned int mask;
1179
1180 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1181
1182 if (!(index % 2)) {
1183 mask = 0x3f00;
1184 level <<= 8;
1185 } else {
1186 mask = 0x3f;
1187 }
1188
1189 /* Program the level itself */
1190 regmap_update_bits(arizona->regmap, reg, mask, level);
1191}
1192
feffb0cc 1193static int arizona_extcon_device_get_pdata(struct arizona *arizona)
9e86b2ad
IS
1194{
1195 struct arizona_pdata *pdata = &arizona->pdata;
1196 unsigned int val = ARIZONA_ACCDET_MODE_HPL;
1197
feffb0cc 1198 device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val);
9e86b2ad
IS
1199 switch (val) {
1200 case ARIZONA_ACCDET_MODE_HPL:
1201 case ARIZONA_ACCDET_MODE_HPR:
1202 pdata->hpdet_channel = val;
1203 break;
1204 default:
1205 dev_err(arizona->dev,
1206 "Wrong wlf,hpdet-channel DT value %d\n", val);
1207 pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
1208 }
1209
4778d44f
CK
1210 device_property_read_u32(arizona->dev, "wlf,micd-detect-debounce",
1211 &pdata->micd_detect_debounce);
1212
1213 device_property_read_u32(arizona->dev, "wlf,micd-bias-start-time",
1214 &pdata->micd_bias_start_time);
1215
1216 device_property_read_u32(arizona->dev, "wlf,micd-rate",
1217 &pdata->micd_rate);
1218
1219 device_property_read_u32(arizona->dev, "wlf,micd-dbtime",
1220 &pdata->micd_dbtime);
1221
1222 device_property_read_u32(arizona->dev, "wlf,micd-timeout",
1223 &pdata->micd_timeout);
1224
1225 pdata->micd_force_micbias = device_property_read_bool(arizona->dev,
1226 "wlf,micd-force-micbias");
1227
9e86b2ad
IS
1228 return 0;
1229}
1230
44f34fd4 1231static int arizona_extcon_probe(struct platform_device *pdev)
f2c32a88
MB
1232{
1233 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
6ac6b475 1234 struct arizona_pdata *pdata = &arizona->pdata;
f2c32a88 1235 struct arizona_extcon_info *info;
e56a0a57 1236 unsigned int val;
a288d648 1237 unsigned int clamp_mode;
92a49871 1238 int jack_irq_fall, jack_irq_rise;
6fed4d86 1239 int ret, mode, i, j;
f2c32a88 1240
bbbd46e3
MB
1241 if (!arizona->dapm || !arizona->dapm->card)
1242 return -EPROBE_DEFER;
1243
f2c32a88 1244 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0a16ee63 1245 if (!info)
d88cc367 1246 return -ENOMEM;
f2c32a88 1247
feffb0cc
CK
1248 if (!dev_get_platdata(arizona->dev))
1249 arizona_extcon_device_get_pdata(arizona);
9e86b2ad 1250
17271f60 1251 info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
f2c32a88
MB
1252 if (IS_ERR(info->micvdd)) {
1253 ret = PTR_ERR(info->micvdd);
1254 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
d88cc367 1255 return ret;
f2c32a88
MB
1256 }
1257
1258 mutex_init(&info->lock);
1259 info->arizona = arizona;
1260 info->dev = &pdev->dev;
a3e2078d 1261 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
0e27bd31 1262 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
cd59e796 1263 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
939c5671 1264 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
f2c32a88
MB
1265 platform_set_drvdata(pdev, info);
1266
1267 switch (arizona->type) {
1268 case WM5102:
1269 switch (arizona->rev) {
1270 case 0:
1271 info->micd_reva = true;
1272 break;
1273 default:
dab63eb2 1274 info->micd_clamp = true;
d0fd5fbc 1275 info->hpdet_ip_version = 1;
f2c32a88
MB
1276 break;
1277 }
1278 break;
77438610 1279 case WM5110:
2f2b6aa8 1280 case WM8280:
77438610
CK
1281 switch (arizona->rev) {
1282 case 0 ... 2:
1283 break;
1284 default:
1285 info->micd_clamp = true;
d0fd5fbc 1286 info->hpdet_ip_version = 2;
77438610
CK
1287 break;
1288 }
1289 break;
f2c32a88
MB
1290 default:
1291 break;
1292 }
1293
ef70a214
CC
1294 info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
1295 if (IS_ERR(info->edev)) {
1296 dev_err(&pdev->dev, "failed to allocate extcon device\n");
1297 return -ENOMEM;
1298 }
f2c32a88 1299
ef70a214 1300 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
f2c32a88 1301 if (ret < 0) {
8e5f5018 1302 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
f2c32a88 1303 ret);
d88cc367 1304 return ret;
f2c32a88
MB
1305 }
1306
6fed4d86
MB
1307 info->input = devm_input_allocate_device(&pdev->dev);
1308 if (!info->input) {
1309 dev_err(arizona->dev, "Can't allocate input dev\n");
1310 ret = -ENOMEM;
1311 goto err_register;
1312 }
1313
1314 info->input->name = "Headset";
1315 info->input->phys = "arizona/extcon";
6fed4d86 1316
f2c32a88
MB
1317 if (pdata->num_micd_configs) {
1318 info->micd_modes = pdata->micd_configs;
1319 info->micd_num_modes = pdata->num_micd_configs;
1320 } else {
1321 info->micd_modes = micd_default_modes;
1322 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1323 }
1324
6772a5ab
CK
1325 if (arizona->pdata.gpsw > 0)
1326 regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1,
1327 ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw);
1328
f2c32a88
MB
1329 if (arizona->pdata.micd_pol_gpio > 0) {
1330 if (info->micd_modes[0].gpio)
1331 mode = GPIOF_OUT_INIT_HIGH;
1332 else
1333 mode = GPIOF_OUT_INIT_LOW;
1334
1335 ret = devm_gpio_request_one(&pdev->dev,
1336 arizona->pdata.micd_pol_gpio,
1337 mode,
1338 "MICD polarity");
1339 if (ret != 0) {
1340 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1341 arizona->pdata.micd_pol_gpio, ret);
1342 goto err_register;
1343 }
8e5838dd
CK
1344 } else {
1345 if (info->micd_modes[0].gpio)
1346 mode = GPIOD_OUT_HIGH;
1347 else
1348 mode = GPIOD_OUT_LOW;
1349
1350 /* We can't use devm here because we need to do the get
1351 * against the MFD device, as that is where the of_node
1352 * will reside, but if we devm against that the GPIO
1353 * will not be freed if the extcon driver is unloaded.
1354 */
1355 info->micd_pol_gpio = gpiod_get_optional(arizona->dev,
1356 "wlf,micd-pol",
1357 GPIOD_OUT_LOW);
1358 if (IS_ERR(info->micd_pol_gpio)) {
1359 ret = PTR_ERR(info->micd_pol_gpio);
1360 dev_err(arizona->dev,
1361 "Failed to get microphone polarity GPIO: %d\n",
1362 ret);
1363 goto err_register;
1364 }
f2c32a88
MB
1365 }
1366
1eda6aa7
MB
1367 if (arizona->pdata.hpdet_id_gpio > 0) {
1368 ret = devm_gpio_request_one(&pdev->dev,
1369 arizona->pdata.hpdet_id_gpio,
1370 GPIOF_OUT_INIT_LOW,
1371 "HPDET");
1372 if (ret != 0) {
1373 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1374 arizona->pdata.hpdet_id_gpio, ret);
8e5838dd 1375 goto err_gpio;
1eda6aa7
MB
1376 }
1377 }
1378
b17e5462
MB
1379 if (arizona->pdata.micd_bias_start_time)
1380 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1381 ARIZONA_MICD_BIAS_STARTTIME_MASK,
1382 arizona->pdata.micd_bias_start_time
1383 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1384
2e033db5
MB
1385 if (arizona->pdata.micd_rate)
1386 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1387 ARIZONA_MICD_RATE_MASK,
1388 arizona->pdata.micd_rate
1389 << ARIZONA_MICD_RATE_SHIFT);
1390
bb327e92
CK
1391 switch (arizona->pdata.micd_dbtime) {
1392 case MICD_DBTIME_FOUR_READINGS:
2e033db5
MB
1393 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1394 ARIZONA_MICD_DBTIME_MASK,
bb327e92
CK
1395 ARIZONA_MICD_DBTIME);
1396 break;
1397 case MICD_DBTIME_TWO_READINGS:
1398 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1399 ARIZONA_MICD_DBTIME_MASK, 0);
1400 break;
1401 default:
1402 break;
1403 }
2e033db5 1404
df8b6771
CK
1405 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) <
1406 ARIZONA_NUM_MICD_BUTTON_LEVELS);
6fed4d86
MB
1407
1408 if (arizona->pdata.num_micd_ranges) {
1409 info->micd_ranges = pdata->micd_ranges;
1410 info->num_micd_ranges = pdata->num_micd_ranges;
1411 } else {
1412 info->micd_ranges = micd_default_ranges;
1413 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1414 }
1415
1416 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1417 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1418 arizona->pdata.num_micd_ranges);
1419 }
1420
1421 if (info->num_micd_ranges > 1) {
1422 for (i = 1; i < info->num_micd_ranges; i++) {
1423 if (info->micd_ranges[i - 1].max >
1424 info->micd_ranges[i].max) {
1425 dev_err(arizona->dev,
1426 "MICD ranges must be sorted\n");
1427 ret = -EINVAL;
8e5838dd 1428 goto err_gpio;
6fed4d86
MB
1429 }
1430 }
1431 }
1432
1433 /* Disable all buttons by default */
1434 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1435 ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1436
1437 /* Set up all the buttons the user specified */
1438 for (i = 0; i < info->num_micd_ranges; i++) {
df8b6771 1439 for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++)
6fed4d86
MB
1440 if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1441 break;
1442
df8b6771 1443 if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) {
6fed4d86
MB
1444 dev_err(arizona->dev, "Unsupported MICD level %d\n",
1445 info->micd_ranges[i].max);
1446 ret = -EINVAL;
8e5838dd 1447 goto err_gpio;
6fed4d86
MB
1448 }
1449
1450 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1451 arizona_micd_levels[j], i);
1452
1453 arizona_micd_set_level(arizona, i, j);
1454 input_set_capability(info->input, EV_KEY,
1455 info->micd_ranges[i].key);
1456
1457 /* Enable reporting of that range */
1458 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1459 1 << i, 1 << i);
1460 }
1461
1462 /* Set all the remaining keys to a maximum */
1463 for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1464 arizona_micd_set_level(arizona, i, 0x3f);
1465
dab63eb2 1466 /*
92a49871
MB
1467 * If we have a clamp use it, activating in conjunction with
1468 * GPIO5 if that is connected for jack detect operation.
dab63eb2
MB
1469 */
1470 if (info->micd_clamp) {
92a49871 1471 if (arizona->pdata.jd_gpio5) {
e56a0a57
MB
1472 /* Put the GPIO into input mode with optional pull */
1473 val = 0xc101;
1474 if (arizona->pdata.jd_gpio5_nopull)
1475 val &= ~ARIZONA_GPN_PU;
1476
92a49871 1477 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
e56a0a57 1478 val);
92a49871 1479
a288d648
RF
1480 if (arizona->pdata.jd_invert)
1481 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
1482 else
1483 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
92a49871 1484 } else {
a288d648
RF
1485 if (arizona->pdata.jd_invert)
1486 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
1487 else
1488 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
92a49871
MB
1489 }
1490
a288d648
RF
1491 regmap_update_bits(arizona->regmap,
1492 ARIZONA_MICD_CLAMP_CONTROL,
1493 ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
1494
dab63eb2
MB
1495 regmap_update_bits(arizona->regmap,
1496 ARIZONA_JACK_DETECT_DEBOUNCE,
1497 ARIZONA_MICD_CLAMP_DB,
1498 ARIZONA_MICD_CLAMP_DB);
1499 }
1500
f2c32a88
MB
1501 arizona_extcon_set_mode(info, 0);
1502
1503 pm_runtime_enable(&pdev->dev);
1504 pm_runtime_idle(&pdev->dev);
1505 pm_runtime_get_sync(&pdev->dev);
1506
ff1cb0ed 1507 if (info->micd_clamp) {
92a49871
MB
1508 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1509 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1510 } else {
1511 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1512 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1513 }
1514
1515 ret = arizona_request_irq(arizona, jack_irq_rise,
f2c32a88
MB
1516 "JACKDET rise", arizona_jackdet, info);
1517 if (ret != 0) {
1518 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1519 ret);
8e5838dd 1520 goto err_gpio;
f2c32a88
MB
1521 }
1522
92a49871 1523 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
f2c32a88
MB
1524 if (ret != 0) {
1525 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1526 ret);
1527 goto err_rise;
1528 }
1529
92a49871 1530 ret = arizona_request_irq(arizona, jack_irq_fall,
f2c32a88
MB
1531 "JACKDET fall", arizona_jackdet, info);
1532 if (ret != 0) {
1533 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1534 goto err_rise_wake;
1535 }
1536
92a49871 1537 ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
f2c32a88
MB
1538 if (ret != 0) {
1539 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1540 ret);
1541 goto err_fall;
1542 }
1543
1544 ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1545 "MICDET", arizona_micdet, info);
1546 if (ret != 0) {
1547 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1548 goto err_fall_wake;
1549 }
1550
4f340333
MB
1551 ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1552 "HPDET", arizona_hpdet_irq, info);
1553 if (ret != 0) {
1554 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1555 goto err_micdet;
1556 }
1557
f2c32a88
MB
1558 arizona_clk32k_enable(arizona);
1559 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1560 ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1561 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1562 ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1563
b8575a11
MB
1564 ret = regulator_allow_bypass(info->micvdd, true);
1565 if (ret != 0)
1566 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1567 ret);
1568
f2c32a88
MB
1569 pm_runtime_put(&pdev->dev);
1570
34efe4dc
MB
1571 ret = input_register_device(info->input);
1572 if (ret) {
1573 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
4f340333 1574 goto err_hpdet;
34efe4dc
MB
1575 }
1576
f2c32a88
MB
1577 return 0;
1578
4f340333
MB
1579err_hpdet:
1580 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
80732cc1
MB
1581err_micdet:
1582 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
f2c32a88 1583err_fall_wake:
92a49871 1584 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
f2c32a88 1585err_fall:
92a49871 1586 arizona_free_irq(arizona, jack_irq_fall, info);
f2c32a88 1587err_rise_wake:
92a49871 1588 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
f2c32a88 1589err_rise:
92a49871 1590 arizona_free_irq(arizona, jack_irq_rise, info);
8e5838dd
CK
1591err_gpio:
1592 gpiod_put(info->micd_pol_gpio);
f2c32a88
MB
1593err_register:
1594 pm_runtime_disable(&pdev->dev);
f2c32a88
MB
1595 return ret;
1596}
1597
93ed0327 1598static int arizona_extcon_remove(struct platform_device *pdev)
f2c32a88
MB
1599{
1600 struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1601 struct arizona *arizona = info->arizona;
92a49871 1602 int jack_irq_rise, jack_irq_fall;
f2c32a88 1603
8e5838dd
CK
1604 gpiod_put(info->micd_pol_gpio);
1605
f2c32a88
MB
1606 pm_runtime_disable(&pdev->dev);
1607
dab63eb2
MB
1608 regmap_update_bits(arizona->regmap,
1609 ARIZONA_MICD_CLAMP_CONTROL,
1610 ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1611
ff1cb0ed 1612 if (info->micd_clamp) {
92a49871
MB
1613 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1614 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1615 } else {
1616 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1617 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1618 }
1619
1620 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1621 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1622 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
f2c32a88 1623 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
92a49871
MB
1624 arizona_free_irq(arizona, jack_irq_rise, info);
1625 arizona_free_irq(arizona, jack_irq_fall, info);
0e27bd31 1626 cancel_delayed_work_sync(&info->hpdet_work);
f2c32a88
MB
1627 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1628 ARIZONA_JD1_ENA, 0);
1629 arizona_clk32k_disable(arizona);
f2c32a88
MB
1630
1631 return 0;
1632}
1633
1634static struct platform_driver arizona_extcon_driver = {
1635 .driver = {
1636 .name = "arizona-extcon",
f2c32a88
MB
1637 },
1638 .probe = arizona_extcon_probe,
5f7e2228 1639 .remove = arizona_extcon_remove,
f2c32a88
MB
1640};
1641
1642module_platform_driver(arizona_extcon_driver);
1643
1644MODULE_DESCRIPTION("Arizona Extcon driver");
1645MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1646MODULE_LICENSE("GPL");
1647MODULE_ALIAS("platform:extcon-arizona");
This page took 0.241186 seconds and 5 git commands to generate.