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