extcon: arizona: Fix reset of HPDET after race with 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
ffae24fe 783 for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
e2c0f476
CK
784 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
785 if (ret != 0) {
c2275d2f
CC
786 dev_err(arizona->dev,
787 "Failed to read MICDET: %d\n", ret);
e2c0f476 788 mutex_unlock(&info->lock);
cd59e796 789 return;
e2c0f476
CK
790 }
791
792 dev_dbg(arizona->dev, "MICDET: %x\n", val);
f2c32a88 793
e2c0f476 794 if (!(val & ARIZONA_MICD_VALID)) {
c2275d2f
CC
795 dev_warn(arizona->dev,
796 "Microphone detection state invalid\n");
e2c0f476 797 mutex_unlock(&info->lock);
cd59e796 798 return;
e2c0f476
CK
799 }
800 }
f2c32a88 801
ffae24fe 802 if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
e2c0f476 803 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
f2c32a88 804 mutex_unlock(&info->lock);
cd59e796 805 return;
f2c32a88
MB
806 }
807
808 /* Due to jack detect this should never happen */
809 if (!(val & ARIZONA_MICD_STS)) {
810 dev_warn(arizona->dev, "Detected open circuit\n");
811 info->detecting = false;
812 goto handled;
813 }
814
815 /* If we got a high impedence we should have a headset, report it. */
ffae24fe 816 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
4f340333
MB
817 arizona_identify_headphone(info);
818
325c6423 819 ret = extcon_update_state(&info->edev,
4f340333
MB
820 1 << ARIZONA_CABLE_MICROPHONE,
821 1 << ARIZONA_CABLE_MICROPHONE);
f2c32a88
MB
822
823 if (ret != 0)
824 dev_err(arizona->dev, "Headset report failed: %d\n",
825 ret);
826
bbbd46e3
MB
827 /* Don't need to regulate for button detection */
828 ret = regulator_allow_bypass(info->micvdd, false);
829 if (ret != 0) {
830 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
831 ret);
832 }
833
f2c32a88
MB
834 info->mic = true;
835 info->detecting = false;
836 goto handled;
837 }
838
839 /* If we detected a lower impedence during initial startup
840 * then we probably have the wrong polarity, flip it. Don't
841 * do this for the lowest impedences to speed up detection of
842 * plain headphones. If both polarities report a low
843 * impedence then give up and report headphones.
844 */
ffae24fe 845 if (info->detecting && (val & MICD_LVL_1_TO_7)) {
84eaa136 846 if (info->jack_flips >= info->micd_num_modes * 10) {
4f340333
MB
847 dev_dbg(arizona->dev, "Detected HP/line\n");
848 arizona_identify_headphone(info);
849
f2c32a88 850 info->detecting = false;
9ef2224d 851
4f340333 852 arizona_stop_mic(info);
f2c32a88
MB
853 } else {
854 info->micd_mode++;
855 if (info->micd_mode == info->micd_num_modes)
856 info->micd_mode = 0;
857 arizona_extcon_set_mode(info, info->micd_mode);
858
859 info->jack_flips++;
860 }
861
862 goto handled;
863 }
864
865 /*
866 * If we're still detecting and we detect a short then we've
34efe4dc 867 * got a headphone. Otherwise it's a button press.
f2c32a88 868 */
ffae24fe 869 if (val & MICD_LVL_0_TO_7) {
f2c32a88
MB
870 if (info->mic) {
871 dev_dbg(arizona->dev, "Mic button detected\n");
872
34efe4dc
MB
873 lvl = val & ARIZONA_MICD_LVL_MASK;
874 lvl >>= ARIZONA_MICD_LVL_SHIFT;
875
41a57850
MB
876 for (i = 0; i < info->num_micd_ranges; i++)
877 input_report_key(info->input,
878 info->micd_ranges[i].key, 0);
879
6fed4d86
MB
880 WARN_ON(!lvl);
881 WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
882 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
883 key = info->micd_ranges[ffs(lvl) - 1].key;
884 input_report_key(info->input, key, 1);
885 input_sync(info->input);
886 }
34efe4dc 887
f2c32a88
MB
888 } else if (info->detecting) {
889 dev_dbg(arizona->dev, "Headphone detected\n");
890 info->detecting = false;
891 arizona_stop_mic(info);
892
4f340333 893 arizona_identify_headphone(info);
f2c32a88
MB
894 } else {
895 dev_warn(arizona->dev, "Button with no mic: %x\n",
896 val);
897 }
898 } else {
899 dev_dbg(arizona->dev, "Mic button released\n");
6fed4d86 900 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 901 input_report_key(info->input,
6fed4d86 902 info->micd_ranges[i].key, 0);
34efe4dc 903 input_sync(info->input);
bbbd46e3 904 arizona_extcon_pulse_micbias(info);
f2c32a88
MB
905 }
906
907handled:
939c5671 908 if (info->detecting)
df9a5ab4
MB
909 queue_delayed_work(system_power_efficient_wq,
910 &info->micd_timeout_work,
911 msecs_to_jiffies(info->micd_timeout));
939c5671 912
f2c32a88
MB
913 pm_runtime_mark_last_busy(info->dev);
914 mutex_unlock(&info->lock);
cd59e796
MB
915}
916
917static irqreturn_t arizona_micdet(int irq, void *data)
918{
919 struct arizona_extcon_info *info = data;
920 struct arizona *arizona = info->arizona;
921 int debounce = arizona->pdata.micd_detect_debounce;
922
923 cancel_delayed_work_sync(&info->micd_detect_work);
924 cancel_delayed_work_sync(&info->micd_timeout_work);
925
926 mutex_lock(&info->lock);
927 if (!info->detecting)
928 debounce = 0;
929 mutex_unlock(&info->lock);
930
931 if (debounce)
df9a5ab4
MB
932 queue_delayed_work(system_power_efficient_wq,
933 &info->micd_detect_work,
934 msecs_to_jiffies(debounce));
cd59e796
MB
935 else
936 arizona_micd_detect(&info->micd_detect_work.work);
f2c32a88
MB
937
938 return IRQ_HANDLED;
939}
940
0e27bd31
MB
941static void arizona_hpdet_work(struct work_struct *work)
942{
943 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
944 struct arizona_extcon_info,
945 hpdet_work.work);
0e27bd31
MB
946
947 mutex_lock(&info->lock);
948 arizona_start_hpdet_acc_id(info);
949 mutex_unlock(&info->lock);
950}
951
f2c32a88
MB
952static irqreturn_t arizona_jackdet(int irq, void *data)
953{
954 struct arizona_extcon_info *info = data;
955 struct arizona *arizona = info->arizona;
92a49871 956 unsigned int val, present, mask;
939c5671 957 bool cancelled_hp, cancelled_mic;
34efe4dc 958 int ret, i;
f2c32a88 959
939c5671
MB
960 cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
961 cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
f2c32a88 962
a3e2078d 963 pm_runtime_get_sync(info->dev);
0e27bd31 964
f2c32a88
MB
965 mutex_lock(&info->lock);
966
92a49871
MB
967 if (arizona->pdata.jd_gpio5) {
968 mask = ARIZONA_MICD_CLAMP_STS;
969 present = 0;
970 } else {
971 mask = ARIZONA_JD1_STS;
972 present = ARIZONA_JD1_STS;
973 }
974
f2c32a88
MB
975 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
976 if (ret != 0) {
977 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
978 ret);
979 mutex_unlock(&info->lock);
980 pm_runtime_put_autosuspend(info->dev);
981 return IRQ_NONE;
982 }
983
a3e2078d
MB
984 val &= mask;
985 if (val == info->last_jackdet) {
986 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
939c5671 987 if (cancelled_hp)
df9a5ab4
MB
988 queue_delayed_work(system_power_efficient_wq,
989 &info->hpdet_work,
990 msecs_to_jiffies(HPDET_DEBOUNCE));
a3e2078d 991
c2275d2f
CC
992 if (cancelled_mic) {
993 int micd_timeout = info->micd_timeout;
994
df9a5ab4
MB
995 queue_delayed_work(system_power_efficient_wq,
996 &info->micd_timeout_work,
c2275d2f
CC
997 msecs_to_jiffies(micd_timeout));
998 }
939c5671 999
a3e2078d
MB
1000 goto out;
1001 }
1002 info->last_jackdet = val;
1003
1004 if (info->last_jackdet == present) {
f2c32a88 1005 dev_dbg(arizona->dev, "Detected jack\n");
325c6423
MB
1006 ret = extcon_set_cable_state_(&info->edev,
1007 ARIZONA_CABLE_MECHANICAL, true);
f2c32a88
MB
1008
1009 if (ret != 0)
1010 dev_err(arizona->dev, "Mechanical report failed: %d\n",
1011 ret);
1012
dd235eea
MB
1013 if (!arizona->pdata.hpdet_acc_id) {
1014 info->detecting = true;
1015 info->mic = false;
1016 info->jack_flips = 0;
1017
1018 arizona_start_mic(info);
1019 } else {
df9a5ab4
MB
1020 queue_delayed_work(system_power_efficient_wq,
1021 &info->hpdet_work,
1022 msecs_to_jiffies(HPDET_DEBOUNCE));
dd235eea 1023 }
4e616877
MB
1024
1025 regmap_update_bits(arizona->regmap,
1026 ARIZONA_JACK_DETECT_DEBOUNCE,
1027 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
f2c32a88
MB
1028 } else {
1029 dev_dbg(arizona->dev, "Detected jack removal\n");
1030
1031 arizona_stop_mic(info);
1032
dd235eea
MB
1033 info->num_hpdet_res = 0;
1034 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1035 info->hpdet_res[i] = 0;
1036 info->mic = false;
bf14ee5a 1037 info->hpdet_done = false;
9dd5e53d 1038 info->hpdet_retried = false;
92a49871 1039
6fed4d86 1040 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 1041 input_report_key(info->input,
6fed4d86 1042 info->micd_ranges[i].key, 0);
34efe4dc
MB
1043 input_sync(info->input);
1044
f2c32a88
MB
1045 ret = extcon_update_state(&info->edev, 0xffffffff, 0);
1046 if (ret != 0)
1047 dev_err(arizona->dev, "Removal report failed: %d\n",
1048 ret);
4e616877
MB
1049
1050 regmap_update_bits(arizona->regmap,
1051 ARIZONA_JACK_DETECT_DEBOUNCE,
1052 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1053 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
f2c32a88
MB
1054 }
1055
7abd4e2a
MB
1056 if (arizona->pdata.micd_timeout)
1057 info->micd_timeout = arizona->pdata.micd_timeout;
1058 else
1059 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1060
cb9005d7 1061out:
5d9ab708
CK
1062 /* Clear trig_sts to make sure DCVDD is not forced up */
1063 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1064 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1065 ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1066 ARIZONA_JD1_FALL_TRIG_STS |
1067 ARIZONA_JD1_RISE_TRIG_STS);
1068
f2c32a88
MB
1069 mutex_unlock(&info->lock);
1070
1071 pm_runtime_mark_last_busy(info->dev);
1072 pm_runtime_put_autosuspend(info->dev);
1073
1074 return IRQ_HANDLED;
1075}
1076
6fed4d86
MB
1077/* Map a level onto a slot in the register bank */
1078static void arizona_micd_set_level(struct arizona *arizona, int index,
1079 unsigned int level)
1080{
1081 int reg;
1082 unsigned int mask;
1083
1084 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1085
1086 if (!(index % 2)) {
1087 mask = 0x3f00;
1088 level <<= 8;
1089 } else {
1090 mask = 0x3f;
1091 }
1092
1093 /* Program the level itself */
1094 regmap_update_bits(arizona->regmap, reg, mask, level);
1095}
1096
44f34fd4 1097static int arizona_extcon_probe(struct platform_device *pdev)
f2c32a88
MB
1098{
1099 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
6ac6b475 1100 struct arizona_pdata *pdata = &arizona->pdata;
f2c32a88 1101 struct arizona_extcon_info *info;
e56a0a57 1102 unsigned int val;
92a49871 1103 int jack_irq_fall, jack_irq_rise;
6fed4d86 1104 int ret, mode, i, j;
f2c32a88 1105
bbbd46e3
MB
1106 if (!arizona->dapm || !arizona->dapm->card)
1107 return -EPROBE_DEFER;
1108
f2c32a88
MB
1109 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1110 if (!info) {
8e5f5018 1111 dev_err(&pdev->dev, "Failed to allocate memory\n");
f2c32a88
MB
1112 ret = -ENOMEM;
1113 goto err;
1114 }
1115
1116 info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
1117 if (IS_ERR(info->micvdd)) {
1118 ret = PTR_ERR(info->micvdd);
1119 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
1120 goto err;
1121 }
1122
1123 mutex_init(&info->lock);
1124 info->arizona = arizona;
1125 info->dev = &pdev->dev;
a3e2078d 1126 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
0e27bd31 1127 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
cd59e796 1128 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
939c5671 1129 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
f2c32a88
MB
1130 platform_set_drvdata(pdev, info);
1131
1132 switch (arizona->type) {
1133 case WM5102:
1134 switch (arizona->rev) {
1135 case 0:
1136 info->micd_reva = true;
1137 break;
1138 default:
dab63eb2 1139 info->micd_clamp = true;
4f340333 1140 info->hpdet_ip = 1;
f2c32a88
MB
1141 break;
1142 }
1143 break;
1144 default:
1145 break;
1146 }
1147
1148 info->edev.name = "Headset Jack";
42d7d753 1149 info->edev.dev.parent = arizona->dev;
f2c32a88 1150 info->edev.supported_cable = arizona_cable;
f2c32a88 1151
42d7d753 1152 ret = extcon_dev_register(&info->edev);
f2c32a88 1153 if (ret < 0) {
8e5f5018 1154 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
f2c32a88
MB
1155 ret);
1156 goto err;
1157 }
1158
6fed4d86
MB
1159 info->input = devm_input_allocate_device(&pdev->dev);
1160 if (!info->input) {
1161 dev_err(arizona->dev, "Can't allocate input dev\n");
1162 ret = -ENOMEM;
1163 goto err_register;
1164 }
1165
1166 info->input->name = "Headset";
1167 info->input->phys = "arizona/extcon";
1168 info->input->dev.parent = &pdev->dev;
1169
f2c32a88
MB
1170 if (pdata->num_micd_configs) {
1171 info->micd_modes = pdata->micd_configs;
1172 info->micd_num_modes = pdata->num_micd_configs;
1173 } else {
1174 info->micd_modes = micd_default_modes;
1175 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1176 }
1177
1178 if (arizona->pdata.micd_pol_gpio > 0) {
1179 if (info->micd_modes[0].gpio)
1180 mode = GPIOF_OUT_INIT_HIGH;
1181 else
1182 mode = GPIOF_OUT_INIT_LOW;
1183
1184 ret = devm_gpio_request_one(&pdev->dev,
1185 arizona->pdata.micd_pol_gpio,
1186 mode,
1187 "MICD polarity");
1188 if (ret != 0) {
1189 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1190 arizona->pdata.micd_pol_gpio, ret);
1191 goto err_register;
1192 }
1193 }
1194
1eda6aa7
MB
1195 if (arizona->pdata.hpdet_id_gpio > 0) {
1196 ret = devm_gpio_request_one(&pdev->dev,
1197 arizona->pdata.hpdet_id_gpio,
1198 GPIOF_OUT_INIT_LOW,
1199 "HPDET");
1200 if (ret != 0) {
1201 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1202 arizona->pdata.hpdet_id_gpio, ret);
1203 goto err_register;
1204 }
1205 }
1206
b17e5462
MB
1207 if (arizona->pdata.micd_bias_start_time)
1208 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1209 ARIZONA_MICD_BIAS_STARTTIME_MASK,
1210 arizona->pdata.micd_bias_start_time
1211 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1212
2e033db5
MB
1213 if (arizona->pdata.micd_rate)
1214 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1215 ARIZONA_MICD_RATE_MASK,
1216 arizona->pdata.micd_rate
1217 << ARIZONA_MICD_RATE_SHIFT);
1218
1219 if (arizona->pdata.micd_dbtime)
1220 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1221 ARIZONA_MICD_DBTIME_MASK,
1222 arizona->pdata.micd_dbtime
1223 << ARIZONA_MICD_DBTIME_SHIFT);
1224
6fed4d86
MB
1225 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1226
1227 if (arizona->pdata.num_micd_ranges) {
1228 info->micd_ranges = pdata->micd_ranges;
1229 info->num_micd_ranges = pdata->num_micd_ranges;
1230 } else {
1231 info->micd_ranges = micd_default_ranges;
1232 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1233 }
1234
1235 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1236 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1237 arizona->pdata.num_micd_ranges);
1238 }
1239
1240 if (info->num_micd_ranges > 1) {
1241 for (i = 1; i < info->num_micd_ranges; i++) {
1242 if (info->micd_ranges[i - 1].max >
1243 info->micd_ranges[i].max) {
1244 dev_err(arizona->dev,
1245 "MICD ranges must be sorted\n");
1246 ret = -EINVAL;
1247 goto err_input;
1248 }
1249 }
1250 }
1251
1252 /* Disable all buttons by default */
1253 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1254 ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1255
1256 /* Set up all the buttons the user specified */
1257 for (i = 0; i < info->num_micd_ranges; i++) {
1258 for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1259 if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1260 break;
1261
1262 if (j == ARRAY_SIZE(arizona_micd_levels)) {
1263 dev_err(arizona->dev, "Unsupported MICD level %d\n",
1264 info->micd_ranges[i].max);
1265 ret = -EINVAL;
1266 goto err_input;
1267 }
1268
1269 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1270 arizona_micd_levels[j], i);
1271
1272 arizona_micd_set_level(arizona, i, j);
1273 input_set_capability(info->input, EV_KEY,
1274 info->micd_ranges[i].key);
1275
1276 /* Enable reporting of that range */
1277 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1278 1 << i, 1 << i);
1279 }
1280
1281 /* Set all the remaining keys to a maximum */
1282 for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1283 arizona_micd_set_level(arizona, i, 0x3f);
1284
dab63eb2 1285 /*
92a49871
MB
1286 * If we have a clamp use it, activating in conjunction with
1287 * GPIO5 if that is connected for jack detect operation.
dab63eb2
MB
1288 */
1289 if (info->micd_clamp) {
92a49871 1290 if (arizona->pdata.jd_gpio5) {
e56a0a57
MB
1291 /* Put the GPIO into input mode with optional pull */
1292 val = 0xc101;
1293 if (arizona->pdata.jd_gpio5_nopull)
1294 val &= ~ARIZONA_GPN_PU;
1295
92a49871 1296 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
e56a0a57 1297 val);
92a49871
MB
1298
1299 regmap_update_bits(arizona->regmap,
1300 ARIZONA_MICD_CLAMP_CONTROL,
1301 ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
1302 } else {
1303 regmap_update_bits(arizona->regmap,
1304 ARIZONA_MICD_CLAMP_CONTROL,
1305 ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
1306 }
1307
dab63eb2
MB
1308 regmap_update_bits(arizona->regmap,
1309 ARIZONA_JACK_DETECT_DEBOUNCE,
1310 ARIZONA_MICD_CLAMP_DB,
1311 ARIZONA_MICD_CLAMP_DB);
1312 }
1313
f2c32a88
MB
1314 arizona_extcon_set_mode(info, 0);
1315
1316 pm_runtime_enable(&pdev->dev);
1317 pm_runtime_idle(&pdev->dev);
1318 pm_runtime_get_sync(&pdev->dev);
1319
92a49871
MB
1320 if (arizona->pdata.jd_gpio5) {
1321 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1322 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1323 } else {
1324 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1325 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1326 }
1327
1328 ret = arizona_request_irq(arizona, jack_irq_rise,
f2c32a88
MB
1329 "JACKDET rise", arizona_jackdet, info);
1330 if (ret != 0) {
1331 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1332 ret);
34efe4dc 1333 goto err_input;
f2c32a88
MB
1334 }
1335
92a49871 1336 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
f2c32a88
MB
1337 if (ret != 0) {
1338 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1339 ret);
1340 goto err_rise;
1341 }
1342
92a49871 1343 ret = arizona_request_irq(arizona, jack_irq_fall,
f2c32a88
MB
1344 "JACKDET fall", arizona_jackdet, info);
1345 if (ret != 0) {
1346 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1347 goto err_rise_wake;
1348 }
1349
92a49871 1350 ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
f2c32a88
MB
1351 if (ret != 0) {
1352 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1353 ret);
1354 goto err_fall;
1355 }
1356
1357 ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1358 "MICDET", arizona_micdet, info);
1359 if (ret != 0) {
1360 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1361 goto err_fall_wake;
1362 }
1363
4f340333
MB
1364 ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1365 "HPDET", arizona_hpdet_irq, info);
1366 if (ret != 0) {
1367 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1368 goto err_micdet;
1369 }
1370
f2c32a88
MB
1371 arizona_clk32k_enable(arizona);
1372 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1373 ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1374 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1375 ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1376
b8575a11
MB
1377 ret = regulator_allow_bypass(info->micvdd, true);
1378 if (ret != 0)
1379 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1380 ret);
1381
f2c32a88
MB
1382 pm_runtime_put(&pdev->dev);
1383
34efe4dc
MB
1384 ret = input_register_device(info->input);
1385 if (ret) {
1386 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
4f340333 1387 goto err_hpdet;
34efe4dc
MB
1388 }
1389
f2c32a88
MB
1390 return 0;
1391
4f340333
MB
1392err_hpdet:
1393 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
80732cc1
MB
1394err_micdet:
1395 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
f2c32a88 1396err_fall_wake:
92a49871 1397 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
f2c32a88 1398err_fall:
92a49871 1399 arizona_free_irq(arizona, jack_irq_fall, info);
f2c32a88 1400err_rise_wake:
92a49871 1401 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
f2c32a88 1402err_rise:
92a49871 1403 arizona_free_irq(arizona, jack_irq_rise, info);
34efe4dc 1404err_input:
f2c32a88
MB
1405err_register:
1406 pm_runtime_disable(&pdev->dev);
1407 extcon_dev_unregister(&info->edev);
1408err:
1409 return ret;
1410}
1411
93ed0327 1412static int arizona_extcon_remove(struct platform_device *pdev)
f2c32a88
MB
1413{
1414 struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1415 struct arizona *arizona = info->arizona;
92a49871 1416 int jack_irq_rise, jack_irq_fall;
f2c32a88
MB
1417
1418 pm_runtime_disable(&pdev->dev);
1419
dab63eb2
MB
1420 regmap_update_bits(arizona->regmap,
1421 ARIZONA_MICD_CLAMP_CONTROL,
1422 ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1423
92a49871
MB
1424 if (arizona->pdata.jd_gpio5) {
1425 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1426 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1427 } else {
1428 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1429 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1430 }
1431
1432 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1433 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1434 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
f2c32a88 1435 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
92a49871
MB
1436 arizona_free_irq(arizona, jack_irq_rise, info);
1437 arizona_free_irq(arizona, jack_irq_fall, info);
0e27bd31 1438 cancel_delayed_work_sync(&info->hpdet_work);
f2c32a88
MB
1439 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1440 ARIZONA_JD1_ENA, 0);
1441 arizona_clk32k_disable(arizona);
1442 extcon_dev_unregister(&info->edev);
1443
1444 return 0;
1445}
1446
1447static struct platform_driver arizona_extcon_driver = {
1448 .driver = {
1449 .name = "arizona-extcon",
1450 .owner = THIS_MODULE,
1451 },
1452 .probe = arizona_extcon_probe,
5f7e2228 1453 .remove = arizona_extcon_remove,
f2c32a88
MB
1454};
1455
1456module_platform_driver(arizona_extcon_driver);
1457
1458MODULE_DESCRIPTION("Arizona Extcon driver");
1459MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1460MODULE_LICENSE("GPL");
1461MODULE_ALIAS("platform:extcon-arizona");
This page took 0.161571 seconds and 5 git commands to generate.