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