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