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