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