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