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