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