extcon: max14577: Use devm_extcon_dev_allocate for extcon_dev
[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
bbbd46e3
MB
225 ret = snd_soc_dapm_force_enable_pin(dapm, widget);
226 if (ret != 0)
227 dev_warn(arizona->dev, "Failed to enable %s: %d\n",
228 widget, ret);
229
bbbd46e3
MB
230 snd_soc_dapm_sync(dapm);
231
232 if (!arizona->pdata.micd_force_micbias) {
bbbd46e3
MB
233 ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
234 if (ret != 0)
235 dev_warn(arizona->dev, "Failed to disable %s: %d\n",
236 widget, ret);
237
bbbd46e3
MB
238 snd_soc_dapm_sync(dapm);
239 }
240}
241
9b1270c7
MB
242static void arizona_start_mic(struct arizona_extcon_info *info)
243{
244 struct arizona *arizona = info->arizona;
245 bool change;
246 int ret;
247
9b1270c7
MB
248 /* Microphone detection can't use idle mode */
249 pm_runtime_get(info->dev);
250
bbbd46e3
MB
251 if (info->detecting) {
252 ret = regulator_allow_bypass(info->micvdd, false);
253 if (ret != 0) {
254 dev_err(arizona->dev,
255 "Failed to regulate MICVDD: %d\n",
256 ret);
257 }
258 }
259
9b1270c7
MB
260 ret = regulator_enable(info->micvdd);
261 if (ret != 0) {
262 dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
263 ret);
264 }
265
266 if (info->micd_reva) {
267 regmap_write(arizona->regmap, 0x80, 0x3);
268 regmap_write(arizona->regmap, 0x294, 0);
269 regmap_write(arizona->regmap, 0x80, 0x0);
270 }
271
272 regmap_update_bits(arizona->regmap,
273 ARIZONA_ACCESSORY_DETECT_MODE_1,
274 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
275
bbbd46e3
MB
276 arizona_extcon_pulse_micbias(info);
277
9b1270c7
MB
278 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
279 ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
280 &change);
281 if (!change) {
282 regulator_disable(info->micvdd);
283 pm_runtime_put_autosuspend(info->dev);
284 }
285}
286
287static void arizona_stop_mic(struct arizona_extcon_info *info)
288{
289 struct arizona *arizona = info->arizona;
bbbd46e3
MB
290 const char *widget = arizona_extcon_get_micbias(info);
291 struct snd_soc_dapm_context *dapm = arizona->dapm;
9b1270c7 292 bool change;
bbbd46e3 293 int ret;
9b1270c7
MB
294
295 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
296 ARIZONA_MICD_ENA, 0,
297 &change);
298
bbbd46e3
MB
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
bbbd46e3
MB
305 snd_soc_dapm_sync(dapm);
306
9b1270c7
MB
307 if (info->micd_reva) {
308 regmap_write(arizona->regmap, 0x80, 0x3);
309 regmap_write(arizona->regmap, 0x294, 2);
310 regmap_write(arizona->regmap, 0x80, 0x0);
311 }
312
bbbd46e3
MB
313 ret = regulator_allow_bypass(info->micvdd, true);
314 if (ret != 0) {
315 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
316 ret);
317 }
318
9b1270c7
MB
319 if (change) {
320 regulator_disable(info->micvdd);
321 pm_runtime_mark_last_busy(info->dev);
322 pm_runtime_put_autosuspend(info->dev);
323 }
324}
325
4f340333
MB
326static struct {
327 unsigned int factor_a;
328 unsigned int factor_b;
329} arizona_hpdet_b_ranges[] = {
330 { 5528, 362464 },
331 { 11084, 6186851 },
332 { 11065, 65460395 },
333};
334
335static struct {
336 int min;
337 int max;
338} arizona_hpdet_c_ranges[] = {
339 { 0, 30 },
340 { 8, 100 },
341 { 100, 1000 },
342 { 1000, 10000 },
343};
344
345static int arizona_hpdet_read(struct arizona_extcon_info *info)
346{
347 struct arizona *arizona = info->arizona;
348 unsigned int val, range;
349 int ret;
350
351 ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
352 if (ret != 0) {
353 dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
354 ret);
355 return ret;
356 }
357
358 switch (info->hpdet_ip) {
359 case 0:
360 if (!(val & ARIZONA_HP_DONE)) {
361 dev_err(arizona->dev, "HPDET did not complete: %x\n",
362 val);
e6dd8cf2 363 return -EAGAIN;
4f340333
MB
364 }
365
366 val &= ARIZONA_HP_LVL_MASK;
367 break;
368
369 case 1:
370 if (!(val & ARIZONA_HP_DONE_B)) {
371 dev_err(arizona->dev, "HPDET did not complete: %x\n",
372 val);
e6dd8cf2 373 return -EAGAIN;
4f340333
MB
374 }
375
376 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
377 if (ret != 0) {
378 dev_err(arizona->dev, "Failed to read HP value: %d\n",
379 ret);
e6dd8cf2 380 return -EAGAIN;
4f340333
MB
381 }
382
383 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
384 &range);
385 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
386 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
387
388 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
4ba1a9ff 389 (val < 100 || val >= 0x3fb)) {
4f340333
MB
390 range++;
391 dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
392 range);
393 regmap_update_bits(arizona->regmap,
394 ARIZONA_HEADPHONE_DETECT_1,
395 ARIZONA_HP_IMPEDANCE_RANGE_MASK,
396 range <<
397 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
398 return -EAGAIN;
399 }
400
401 /* If we go out of range report top of range */
4ba1a9ff 402 if (val < 100 || val >= 0x3fb) {
4f340333 403 dev_dbg(arizona->dev, "Measurement out of range\n");
9dd5e53d 404 return ARIZONA_HPDET_MAX;
4f340333
MB
405 }
406
407 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
408 val, range);
409
410 val = arizona_hpdet_b_ranges[range].factor_b
411 / ((val * 100) -
412 arizona_hpdet_b_ranges[range].factor_a);
413 break;
414
415 default:
416 dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
417 info->hpdet_ip);
418 case 2:
419 if (!(val & ARIZONA_HP_DONE_B)) {
420 dev_err(arizona->dev, "HPDET did not complete: %x\n",
421 val);
e6dd8cf2 422 return -EAGAIN;
4f340333
MB
423 }
424
425 val &= ARIZONA_HP_LVL_B_MASK;
77438610
CK
426 /* Convert to ohms, the value is in 0.5 ohm increments */
427 val /= 2;
4f340333
MB
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
9141461d 434 /* Skip up a range, or report? */
4f340333
MB
435 if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
436 (val >= arizona_hpdet_c_ranges[range].max)) {
437 range++;
438 dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
439 arizona_hpdet_c_ranges[range].min,
440 arizona_hpdet_c_ranges[range].max);
441 regmap_update_bits(arizona->regmap,
442 ARIZONA_HEADPHONE_DETECT_1,
443 ARIZONA_HP_IMPEDANCE_RANGE_MASK,
444 range <<
445 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
446 return -EAGAIN;
447 }
9141461d
CK
448
449 if (range && (val < arizona_hpdet_c_ranges[range].min)) {
450 dev_dbg(arizona->dev, "Reporting range boundary %d\n",
451 arizona_hpdet_c_ranges[range].min);
452 val = arizona_hpdet_c_ranges[range].min;
453 }
4f340333
MB
454 }
455
456 dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
457 return val;
458}
459
9c2ba270
MB
460static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
461 bool *mic)
dd235eea
MB
462{
463 struct arizona *arizona = info->arizona;
1eda6aa7 464 int id_gpio = arizona->pdata.hpdet_id_gpio;
dd235eea
MB
465
466 /*
467 * If we're using HPDET for accessory identification we need
468 * to take multiple measurements, step through them in sequence.
469 */
470 if (arizona->pdata.hpdet_acc_id) {
471 info->hpdet_res[info->num_hpdet_res++] = *reading;
1eda6aa7
MB
472
473 /* Only check the mic directly if we didn't already ID it */
9c2ba270 474 if (id_gpio && info->num_hpdet_res == 1) {
1eda6aa7
MB
475 dev_dbg(arizona->dev, "Measuring mic\n");
476
477 regmap_update_bits(arizona->regmap,
478 ARIZONA_ACCESSORY_DETECT_MODE_1,
479 ARIZONA_ACCDET_MODE_MASK |
480 ARIZONA_ACCDET_SRC,
481 ARIZONA_ACCDET_MODE_HPR |
482 info->micd_modes[0].src);
483
484 gpio_set_value_cansleep(id_gpio, 1);
485
dd235eea
MB
486 regmap_update_bits(arizona->regmap,
487 ARIZONA_HEADPHONE_DETECT_1,
488 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
489 return -EAGAIN;
490 }
491
492 /* OK, got both. Now, compare... */
9c2ba270
MB
493 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
494 info->hpdet_res[0], info->hpdet_res[1]);
c37b387f
MB
495
496 /* Take the headphone impedance for the main report */
497 *reading = info->hpdet_res[0];
498
9dd5e53d
MB
499 /* Sometimes we get false readings due to slow insert */
500 if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
501 dev_dbg(arizona->dev, "Retrying high impedance\n");
502 info->num_hpdet_res = 0;
503 info->hpdet_retried = true;
504 arizona_start_hpdet_acc_id(info);
505 pm_runtime_put(info->dev);
506 return -EAGAIN;
507 }
508
1eda6aa7 509 /*
d97abdde 510 * If we measure the mic as high impedance
1eda6aa7 511 */
9c2ba270 512 if (!id_gpio || info->hpdet_res[1] > 50) {
dd235eea 513 dev_dbg(arizona->dev, "Detected mic\n");
9c2ba270 514 *mic = true;
bf14ee5a 515 info->detecting = true;
dd235eea
MB
516 } else {
517 dev_dbg(arizona->dev, "Detected headphone\n");
518 }
519
520 /* Make sure everything is reset back to the real polarity */
521 regmap_update_bits(arizona->regmap,
522 ARIZONA_ACCESSORY_DETECT_MODE_1,
523 ARIZONA_ACCDET_SRC,
524 info->micd_modes[0].src);
525 }
526
527 return 0;
528}
529
4f340333
MB
530static irqreturn_t arizona_hpdet_irq(int irq, void *data)
531{
532 struct arizona_extcon_info *info = data;
533 struct arizona *arizona = info->arizona;
1eda6aa7 534 int id_gpio = arizona->pdata.hpdet_id_gpio;
4f340333 535 int report = ARIZONA_CABLE_HEADPHONE;
dd235eea 536 int ret, reading;
9c2ba270 537 bool mic = false;
4f340333
MB
538
539 mutex_lock(&info->lock);
540
541 /* If we got a spurious IRQ for some reason then ignore it */
542 if (!info->hpdet_active) {
543 dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
544 mutex_unlock(&info->lock);
545 return IRQ_NONE;
546 }
547
548 /* If the cable was removed while measuring ignore the result */
549 ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL);
550 if (ret < 0) {
551 dev_err(arizona->dev, "Failed to check cable state: %d\n",
552 ret);
553 goto out;
554 } else if (!ret) {
555 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
556 goto done;
557 }
558
559 ret = arizona_hpdet_read(info);
d6675667 560 if (ret == -EAGAIN)
4f340333 561 goto out;
d6675667 562 else if (ret < 0)
4f340333 563 goto done;
dd235eea 564 reading = ret;
4f340333
MB
565
566 /* Reset back to starting range */
567 regmap_update_bits(arizona->regmap,
568 ARIZONA_HEADPHONE_DETECT_1,
dd235eea
MB
569 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
570 0);
571
9c2ba270 572 ret = arizona_hpdet_do_id(info, &reading, &mic);
d6675667 573 if (ret == -EAGAIN)
dd235eea 574 goto out;
d6675667 575 else if (ret < 0)
dd235eea 576 goto done;
4f340333
MB
577
578 /* Report high impedence cables as line outputs */
dd235eea 579 if (reading >= 5000)
4f340333
MB
580 report = ARIZONA_CABLE_LINEOUT;
581 else
582 report = ARIZONA_CABLE_HEADPHONE;
583
584 ret = extcon_set_cable_state_(&info->edev, report, true);
585 if (ret != 0)
586 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
587 ret);
588
a3e00d4b
CK
589done:
590 /* Reset back to starting range */
591 regmap_update_bits(arizona->regmap,
592 ARIZONA_HEADPHONE_DETECT_1,
593 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
594 0);
595
03409071 596 arizona_extcon_do_magic(info, 0);
4f340333 597
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,
c2275d2f
CC
738 struct arizona_extcon_info,
739 micd_timeout_work.work);
939c5671
MB
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
cd59e796 753static void arizona_micd_detect(struct work_struct *work)
f2c32a88 754{
cd59e796 755 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
756 struct arizona_extcon_info,
757 micd_detect_work.work);
f2c32a88 758 struct arizona *arizona = info->arizona;
e2c0f476 759 unsigned int val = 0, lvl;
6fed4d86 760 int ret, i, key;
f2c32a88 761
939c5671
MB
762 cancel_delayed_work_sync(&info->micd_timeout_work);
763
f2c32a88
MB
764 mutex_lock(&info->lock);
765
31a847e6
CK
766 /* If the cable was removed while measuring ignore the result */
767 ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL);
768 if (ret < 0) {
769 dev_err(arizona->dev, "Failed to check cable state: %d\n",
770 ret);
771 mutex_unlock(&info->lock);
772 return;
773 } else if (!ret) {
774 dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
775 mutex_unlock(&info->lock);
776 return;
777 }
778
ffae24fe 779 for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
e2c0f476
CK
780 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
781 if (ret != 0) {
c2275d2f
CC
782 dev_err(arizona->dev,
783 "Failed to read MICDET: %d\n", ret);
e2c0f476 784 mutex_unlock(&info->lock);
cd59e796 785 return;
e2c0f476
CK
786 }
787
788 dev_dbg(arizona->dev, "MICDET: %x\n", val);
f2c32a88 789
e2c0f476 790 if (!(val & ARIZONA_MICD_VALID)) {
c2275d2f
CC
791 dev_warn(arizona->dev,
792 "Microphone detection state invalid\n");
e2c0f476 793 mutex_unlock(&info->lock);
cd59e796 794 return;
e2c0f476
CK
795 }
796 }
f2c32a88 797
ffae24fe 798 if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
e2c0f476 799 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
f2c32a88 800 mutex_unlock(&info->lock);
cd59e796 801 return;
f2c32a88
MB
802 }
803
804 /* Due to jack detect this should never happen */
805 if (!(val & ARIZONA_MICD_STS)) {
806 dev_warn(arizona->dev, "Detected open circuit\n");
807 info->detecting = false;
808 goto handled;
809 }
810
811 /* If we got a high impedence we should have a headset, report it. */
ffae24fe 812 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
4f340333
MB
813 arizona_identify_headphone(info);
814
325c6423 815 ret = extcon_update_state(&info->edev,
4f340333
MB
816 1 << ARIZONA_CABLE_MICROPHONE,
817 1 << ARIZONA_CABLE_MICROPHONE);
f2c32a88
MB
818
819 if (ret != 0)
820 dev_err(arizona->dev, "Headset report failed: %d\n",
821 ret);
822
bbbd46e3
MB
823 /* Don't need to regulate for button detection */
824 ret = regulator_allow_bypass(info->micvdd, false);
825 if (ret != 0) {
826 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
827 ret);
828 }
829
f2c32a88
MB
830 info->mic = true;
831 info->detecting = false;
832 goto handled;
833 }
834
835 /* If we detected a lower impedence during initial startup
836 * then we probably have the wrong polarity, flip it. Don't
837 * do this for the lowest impedences to speed up detection of
838 * plain headphones. If both polarities report a low
839 * impedence then give up and report headphones.
840 */
ffae24fe 841 if (info->detecting && (val & MICD_LVL_1_TO_7)) {
84eaa136 842 if (info->jack_flips >= info->micd_num_modes * 10) {
4f340333
MB
843 dev_dbg(arizona->dev, "Detected HP/line\n");
844 arizona_identify_headphone(info);
845
f2c32a88 846 info->detecting = false;
9ef2224d 847
4f340333 848 arizona_stop_mic(info);
f2c32a88
MB
849 } else {
850 info->micd_mode++;
851 if (info->micd_mode == info->micd_num_modes)
852 info->micd_mode = 0;
853 arizona_extcon_set_mode(info, info->micd_mode);
854
855 info->jack_flips++;
856 }
857
858 goto handled;
859 }
860
861 /*
862 * If we're still detecting and we detect a short then we've
34efe4dc 863 * got a headphone. Otherwise it's a button press.
f2c32a88 864 */
ffae24fe 865 if (val & MICD_LVL_0_TO_7) {
f2c32a88
MB
866 if (info->mic) {
867 dev_dbg(arizona->dev, "Mic button detected\n");
868
34efe4dc
MB
869 lvl = val & ARIZONA_MICD_LVL_MASK;
870 lvl >>= ARIZONA_MICD_LVL_SHIFT;
871
41a57850
MB
872 for (i = 0; i < info->num_micd_ranges; i++)
873 input_report_key(info->input,
874 info->micd_ranges[i].key, 0);
875
6fed4d86
MB
876 WARN_ON(!lvl);
877 WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
878 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
879 key = info->micd_ranges[ffs(lvl) - 1].key;
880 input_report_key(info->input, key, 1);
881 input_sync(info->input);
882 }
34efe4dc 883
f2c32a88
MB
884 } else if (info->detecting) {
885 dev_dbg(arizona->dev, "Headphone detected\n");
886 info->detecting = false;
887 arizona_stop_mic(info);
888
4f340333 889 arizona_identify_headphone(info);
f2c32a88
MB
890 } else {
891 dev_warn(arizona->dev, "Button with no mic: %x\n",
892 val);
893 }
894 } else {
895 dev_dbg(arizona->dev, "Mic button released\n");
6fed4d86 896 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 897 input_report_key(info->input,
6fed4d86 898 info->micd_ranges[i].key, 0);
34efe4dc 899 input_sync(info->input);
bbbd46e3 900 arizona_extcon_pulse_micbias(info);
f2c32a88
MB
901 }
902
903handled:
939c5671 904 if (info->detecting)
df9a5ab4
MB
905 queue_delayed_work(system_power_efficient_wq,
906 &info->micd_timeout_work,
907 msecs_to_jiffies(info->micd_timeout));
939c5671 908
f2c32a88
MB
909 pm_runtime_mark_last_busy(info->dev);
910 mutex_unlock(&info->lock);
cd59e796
MB
911}
912
913static irqreturn_t arizona_micdet(int irq, void *data)
914{
915 struct arizona_extcon_info *info = data;
916 struct arizona *arizona = info->arizona;
917 int debounce = arizona->pdata.micd_detect_debounce;
918
919 cancel_delayed_work_sync(&info->micd_detect_work);
920 cancel_delayed_work_sync(&info->micd_timeout_work);
921
922 mutex_lock(&info->lock);
923 if (!info->detecting)
924 debounce = 0;
925 mutex_unlock(&info->lock);
926
927 if (debounce)
df9a5ab4
MB
928 queue_delayed_work(system_power_efficient_wq,
929 &info->micd_detect_work,
930 msecs_to_jiffies(debounce));
cd59e796
MB
931 else
932 arizona_micd_detect(&info->micd_detect_work.work);
f2c32a88
MB
933
934 return IRQ_HANDLED;
935}
936
0e27bd31
MB
937static void arizona_hpdet_work(struct work_struct *work)
938{
939 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
940 struct arizona_extcon_info,
941 hpdet_work.work);
0e27bd31
MB
942
943 mutex_lock(&info->lock);
944 arizona_start_hpdet_acc_id(info);
945 mutex_unlock(&info->lock);
946}
947
f2c32a88
MB
948static irqreturn_t arizona_jackdet(int irq, void *data)
949{
950 struct arizona_extcon_info *info = data;
951 struct arizona *arizona = info->arizona;
92a49871 952 unsigned int val, present, mask;
939c5671 953 bool cancelled_hp, cancelled_mic;
34efe4dc 954 int ret, i;
f2c32a88 955
939c5671
MB
956 cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
957 cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
f2c32a88 958
a3e2078d 959 pm_runtime_get_sync(info->dev);
0e27bd31 960
f2c32a88
MB
961 mutex_lock(&info->lock);
962
92a49871
MB
963 if (arizona->pdata.jd_gpio5) {
964 mask = ARIZONA_MICD_CLAMP_STS;
965 present = 0;
966 } else {
967 mask = ARIZONA_JD1_STS;
968 present = ARIZONA_JD1_STS;
969 }
970
f2c32a88
MB
971 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
972 if (ret != 0) {
973 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
974 ret);
975 mutex_unlock(&info->lock);
976 pm_runtime_put_autosuspend(info->dev);
977 return IRQ_NONE;
978 }
979
a3e2078d
MB
980 val &= mask;
981 if (val == info->last_jackdet) {
982 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
939c5671 983 if (cancelled_hp)
df9a5ab4
MB
984 queue_delayed_work(system_power_efficient_wq,
985 &info->hpdet_work,
986 msecs_to_jiffies(HPDET_DEBOUNCE));
a3e2078d 987
c2275d2f
CC
988 if (cancelled_mic) {
989 int micd_timeout = info->micd_timeout;
990
df9a5ab4
MB
991 queue_delayed_work(system_power_efficient_wq,
992 &info->micd_timeout_work,
c2275d2f
CC
993 msecs_to_jiffies(micd_timeout));
994 }
939c5671 995
a3e2078d
MB
996 goto out;
997 }
998 info->last_jackdet = val;
999
1000 if (info->last_jackdet == present) {
f2c32a88 1001 dev_dbg(arizona->dev, "Detected jack\n");
325c6423
MB
1002 ret = extcon_set_cable_state_(&info->edev,
1003 ARIZONA_CABLE_MECHANICAL, true);
f2c32a88
MB
1004
1005 if (ret != 0)
1006 dev_err(arizona->dev, "Mechanical report failed: %d\n",
1007 ret);
1008
dd235eea
MB
1009 if (!arizona->pdata.hpdet_acc_id) {
1010 info->detecting = true;
1011 info->mic = false;
1012 info->jack_flips = 0;
1013
1014 arizona_start_mic(info);
1015 } else {
df9a5ab4
MB
1016 queue_delayed_work(system_power_efficient_wq,
1017 &info->hpdet_work,
1018 msecs_to_jiffies(HPDET_DEBOUNCE));
dd235eea 1019 }
4e616877
MB
1020
1021 regmap_update_bits(arizona->regmap,
1022 ARIZONA_JACK_DETECT_DEBOUNCE,
1023 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
f2c32a88
MB
1024 } else {
1025 dev_dbg(arizona->dev, "Detected jack removal\n");
1026
1027 arizona_stop_mic(info);
1028
dd235eea
MB
1029 info->num_hpdet_res = 0;
1030 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1031 info->hpdet_res[i] = 0;
1032 info->mic = false;
bf14ee5a 1033 info->hpdet_done = false;
9dd5e53d 1034 info->hpdet_retried = false;
92a49871 1035
6fed4d86 1036 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 1037 input_report_key(info->input,
6fed4d86 1038 info->micd_ranges[i].key, 0);
34efe4dc
MB
1039 input_sync(info->input);
1040
f2c32a88
MB
1041 ret = extcon_update_state(&info->edev, 0xffffffff, 0);
1042 if (ret != 0)
1043 dev_err(arizona->dev, "Removal report failed: %d\n",
1044 ret);
4e616877
MB
1045
1046 regmap_update_bits(arizona->regmap,
1047 ARIZONA_JACK_DETECT_DEBOUNCE,
1048 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1049 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
f2c32a88
MB
1050 }
1051
7abd4e2a
MB
1052 if (arizona->pdata.micd_timeout)
1053 info->micd_timeout = arizona->pdata.micd_timeout;
1054 else
1055 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1056
cb9005d7 1057out:
5d9ab708
CK
1058 /* Clear trig_sts to make sure DCVDD is not forced up */
1059 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1060 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1061 ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1062 ARIZONA_JD1_FALL_TRIG_STS |
1063 ARIZONA_JD1_RISE_TRIG_STS);
1064
f2c32a88
MB
1065 mutex_unlock(&info->lock);
1066
1067 pm_runtime_mark_last_busy(info->dev);
1068 pm_runtime_put_autosuspend(info->dev);
1069
1070 return IRQ_HANDLED;
1071}
1072
6fed4d86
MB
1073/* Map a level onto a slot in the register bank */
1074static void arizona_micd_set_level(struct arizona *arizona, int index,
1075 unsigned int level)
1076{
1077 int reg;
1078 unsigned int mask;
1079
1080 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1081
1082 if (!(index % 2)) {
1083 mask = 0x3f00;
1084 level <<= 8;
1085 } else {
1086 mask = 0x3f;
1087 }
1088
1089 /* Program the level itself */
1090 regmap_update_bits(arizona->regmap, reg, mask, level);
1091}
1092
44f34fd4 1093static int arizona_extcon_probe(struct platform_device *pdev)
f2c32a88
MB
1094{
1095 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
6ac6b475 1096 struct arizona_pdata *pdata = &arizona->pdata;
f2c32a88 1097 struct arizona_extcon_info *info;
e56a0a57 1098 unsigned int val;
92a49871 1099 int jack_irq_fall, jack_irq_rise;
6fed4d86 1100 int ret, mode, i, j;
f2c32a88 1101
bbbd46e3
MB
1102 if (!arizona->dapm || !arizona->dapm->card)
1103 return -EPROBE_DEFER;
1104
f2c32a88
MB
1105 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1106 if (!info) {
8e5f5018 1107 dev_err(&pdev->dev, "Failed to allocate memory\n");
d88cc367 1108 return -ENOMEM;
f2c32a88
MB
1109 }
1110
1111 info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
1112 if (IS_ERR(info->micvdd)) {
1113 ret = PTR_ERR(info->micvdd);
1114 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
d88cc367 1115 return ret;
f2c32a88
MB
1116 }
1117
1118 mutex_init(&info->lock);
1119 info->arizona = arizona;
1120 info->dev = &pdev->dev;
a3e2078d 1121 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
0e27bd31 1122 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
cd59e796 1123 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
939c5671 1124 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
f2c32a88
MB
1125 platform_set_drvdata(pdev, info);
1126
1127 switch (arizona->type) {
1128 case WM5102:
1129 switch (arizona->rev) {
1130 case 0:
1131 info->micd_reva = true;
1132 break;
1133 default:
dab63eb2 1134 info->micd_clamp = true;
4f340333 1135 info->hpdet_ip = 1;
f2c32a88
MB
1136 break;
1137 }
1138 break;
77438610
CK
1139 case WM5110:
1140 switch (arizona->rev) {
1141 case 0 ... 2:
1142 break;
1143 default:
1144 info->micd_clamp = true;
1145 info->hpdet_ip = 2;
1146 break;
1147 }
1148 break;
f2c32a88
MB
1149 default:
1150 break;
1151 }
1152
1153 info->edev.name = "Headset Jack";
42d7d753 1154 info->edev.dev.parent = arizona->dev;
f2c32a88 1155 info->edev.supported_cable = arizona_cable;
f2c32a88 1156
d88cc367 1157 ret = devm_extcon_dev_register(&pdev->dev, &info->edev);
f2c32a88 1158 if (ret < 0) {
8e5f5018 1159 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
f2c32a88 1160 ret);
d88cc367 1161 return ret;
f2c32a88
MB
1162 }
1163
6fed4d86
MB
1164 info->input = devm_input_allocate_device(&pdev->dev);
1165 if (!info->input) {
1166 dev_err(arizona->dev, "Can't allocate input dev\n");
1167 ret = -ENOMEM;
1168 goto err_register;
1169 }
1170
1171 info->input->name = "Headset";
1172 info->input->phys = "arizona/extcon";
1173 info->input->dev.parent = &pdev->dev;
1174
f2c32a88
MB
1175 if (pdata->num_micd_configs) {
1176 info->micd_modes = pdata->micd_configs;
1177 info->micd_num_modes = pdata->num_micd_configs;
1178 } else {
1179 info->micd_modes = micd_default_modes;
1180 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1181 }
1182
1183 if (arizona->pdata.micd_pol_gpio > 0) {
1184 if (info->micd_modes[0].gpio)
1185 mode = GPIOF_OUT_INIT_HIGH;
1186 else
1187 mode = GPIOF_OUT_INIT_LOW;
1188
1189 ret = devm_gpio_request_one(&pdev->dev,
1190 arizona->pdata.micd_pol_gpio,
1191 mode,
1192 "MICD polarity");
1193 if (ret != 0) {
1194 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1195 arizona->pdata.micd_pol_gpio, ret);
1196 goto err_register;
1197 }
1198 }
1199
1eda6aa7
MB
1200 if (arizona->pdata.hpdet_id_gpio > 0) {
1201 ret = devm_gpio_request_one(&pdev->dev,
1202 arizona->pdata.hpdet_id_gpio,
1203 GPIOF_OUT_INIT_LOW,
1204 "HPDET");
1205 if (ret != 0) {
1206 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1207 arizona->pdata.hpdet_id_gpio, ret);
1208 goto err_register;
1209 }
1210 }
1211
b17e5462
MB
1212 if (arizona->pdata.micd_bias_start_time)
1213 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1214 ARIZONA_MICD_BIAS_STARTTIME_MASK,
1215 arizona->pdata.micd_bias_start_time
1216 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1217
2e033db5
MB
1218 if (arizona->pdata.micd_rate)
1219 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1220 ARIZONA_MICD_RATE_MASK,
1221 arizona->pdata.micd_rate
1222 << ARIZONA_MICD_RATE_SHIFT);
1223
1224 if (arizona->pdata.micd_dbtime)
1225 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1226 ARIZONA_MICD_DBTIME_MASK,
1227 arizona->pdata.micd_dbtime
1228 << ARIZONA_MICD_DBTIME_SHIFT);
1229
6fed4d86
MB
1230 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1231
1232 if (arizona->pdata.num_micd_ranges) {
1233 info->micd_ranges = pdata->micd_ranges;
1234 info->num_micd_ranges = pdata->num_micd_ranges;
1235 } else {
1236 info->micd_ranges = micd_default_ranges;
1237 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1238 }
1239
1240 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1241 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1242 arizona->pdata.num_micd_ranges);
1243 }
1244
1245 if (info->num_micd_ranges > 1) {
1246 for (i = 1; i < info->num_micd_ranges; i++) {
1247 if (info->micd_ranges[i - 1].max >
1248 info->micd_ranges[i].max) {
1249 dev_err(arizona->dev,
1250 "MICD ranges must be sorted\n");
1251 ret = -EINVAL;
1252 goto err_input;
1253 }
1254 }
1255 }
1256
1257 /* Disable all buttons by default */
1258 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1259 ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1260
1261 /* Set up all the buttons the user specified */
1262 for (i = 0; i < info->num_micd_ranges; i++) {
1263 for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1264 if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1265 break;
1266
1267 if (j == ARRAY_SIZE(arizona_micd_levels)) {
1268 dev_err(arizona->dev, "Unsupported MICD level %d\n",
1269 info->micd_ranges[i].max);
1270 ret = -EINVAL;
1271 goto err_input;
1272 }
1273
1274 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1275 arizona_micd_levels[j], i);
1276
1277 arizona_micd_set_level(arizona, i, j);
1278 input_set_capability(info->input, EV_KEY,
1279 info->micd_ranges[i].key);
1280
1281 /* Enable reporting of that range */
1282 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1283 1 << i, 1 << i);
1284 }
1285
1286 /* Set all the remaining keys to a maximum */
1287 for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1288 arizona_micd_set_level(arizona, i, 0x3f);
1289
dab63eb2 1290 /*
92a49871
MB
1291 * If we have a clamp use it, activating in conjunction with
1292 * GPIO5 if that is connected for jack detect operation.
dab63eb2
MB
1293 */
1294 if (info->micd_clamp) {
92a49871 1295 if (arizona->pdata.jd_gpio5) {
e56a0a57
MB
1296 /* Put the GPIO into input mode with optional pull */
1297 val = 0xc101;
1298 if (arizona->pdata.jd_gpio5_nopull)
1299 val &= ~ARIZONA_GPN_PU;
1300
92a49871 1301 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
e56a0a57 1302 val);
92a49871
MB
1303
1304 regmap_update_bits(arizona->regmap,
1305 ARIZONA_MICD_CLAMP_CONTROL,
1306 ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
1307 } else {
1308 regmap_update_bits(arizona->regmap,
1309 ARIZONA_MICD_CLAMP_CONTROL,
1310 ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
1311 }
1312
dab63eb2
MB
1313 regmap_update_bits(arizona->regmap,
1314 ARIZONA_JACK_DETECT_DEBOUNCE,
1315 ARIZONA_MICD_CLAMP_DB,
1316 ARIZONA_MICD_CLAMP_DB);
1317 }
1318
f2c32a88
MB
1319 arizona_extcon_set_mode(info, 0);
1320
1321 pm_runtime_enable(&pdev->dev);
1322 pm_runtime_idle(&pdev->dev);
1323 pm_runtime_get_sync(&pdev->dev);
1324
92a49871
MB
1325 if (arizona->pdata.jd_gpio5) {
1326 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1327 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1328 } else {
1329 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1330 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1331 }
1332
1333 ret = arizona_request_irq(arizona, jack_irq_rise,
f2c32a88
MB
1334 "JACKDET rise", arizona_jackdet, info);
1335 if (ret != 0) {
1336 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1337 ret);
34efe4dc 1338 goto err_input;
f2c32a88
MB
1339 }
1340
92a49871 1341 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
f2c32a88
MB
1342 if (ret != 0) {
1343 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1344 ret);
1345 goto err_rise;
1346 }
1347
92a49871 1348 ret = arizona_request_irq(arizona, jack_irq_fall,
f2c32a88
MB
1349 "JACKDET fall", arizona_jackdet, info);
1350 if (ret != 0) {
1351 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1352 goto err_rise_wake;
1353 }
1354
92a49871 1355 ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
f2c32a88
MB
1356 if (ret != 0) {
1357 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1358 ret);
1359 goto err_fall;
1360 }
1361
1362 ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1363 "MICDET", arizona_micdet, info);
1364 if (ret != 0) {
1365 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1366 goto err_fall_wake;
1367 }
1368
4f340333
MB
1369 ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1370 "HPDET", arizona_hpdet_irq, info);
1371 if (ret != 0) {
1372 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1373 goto err_micdet;
1374 }
1375
f2c32a88
MB
1376 arizona_clk32k_enable(arizona);
1377 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1378 ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1379 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1380 ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1381
b8575a11
MB
1382 ret = regulator_allow_bypass(info->micvdd, true);
1383 if (ret != 0)
1384 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1385 ret);
1386
f2c32a88
MB
1387 pm_runtime_put(&pdev->dev);
1388
34efe4dc
MB
1389 ret = input_register_device(info->input);
1390 if (ret) {
1391 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
4f340333 1392 goto err_hpdet;
34efe4dc
MB
1393 }
1394
f2c32a88
MB
1395 return 0;
1396
4f340333
MB
1397err_hpdet:
1398 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
80732cc1
MB
1399err_micdet:
1400 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
f2c32a88 1401err_fall_wake:
92a49871 1402 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
f2c32a88 1403err_fall:
92a49871 1404 arizona_free_irq(arizona, jack_irq_fall, info);
f2c32a88 1405err_rise_wake:
92a49871 1406 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
f2c32a88 1407err_rise:
92a49871 1408 arizona_free_irq(arizona, jack_irq_rise, info);
34efe4dc 1409err_input:
f2c32a88
MB
1410err_register:
1411 pm_runtime_disable(&pdev->dev);
f2c32a88
MB
1412 return ret;
1413}
1414
93ed0327 1415static int arizona_extcon_remove(struct platform_device *pdev)
f2c32a88
MB
1416{
1417 struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1418 struct arizona *arizona = info->arizona;
92a49871 1419 int jack_irq_rise, jack_irq_fall;
f2c32a88
MB
1420
1421 pm_runtime_disable(&pdev->dev);
1422
dab63eb2
MB
1423 regmap_update_bits(arizona->regmap,
1424 ARIZONA_MICD_CLAMP_CONTROL,
1425 ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1426
92a49871
MB
1427 if (arizona->pdata.jd_gpio5) {
1428 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1429 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1430 } else {
1431 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1432 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1433 }
1434
1435 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1436 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1437 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
f2c32a88 1438 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
92a49871
MB
1439 arizona_free_irq(arizona, jack_irq_rise, info);
1440 arizona_free_irq(arizona, jack_irq_fall, info);
0e27bd31 1441 cancel_delayed_work_sync(&info->hpdet_work);
f2c32a88
MB
1442 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1443 ARIZONA_JD1_ENA, 0);
1444 arizona_clk32k_disable(arizona);
f2c32a88
MB
1445
1446 return 0;
1447}
1448
1449static struct platform_driver arizona_extcon_driver = {
1450 .driver = {
1451 .name = "arizona-extcon",
1452 .owner = THIS_MODULE,
1453 },
1454 .probe = arizona_extcon_probe,
5f7e2228 1455 .remove = arizona_extcon_remove,
f2c32a88
MB
1456};
1457
1458module_platform_driver(arizona_extcon_driver);
1459
1460MODULE_DESCRIPTION("Arizona Extcon driver");
1461MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1462MODULE_LICENSE("GPL");
1463MODULE_ALIAS("platform:extcon-arizona");
This page took 0.170881 seconds and 5 git commands to generate.