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