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