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