Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[deliverable/linux.git] / drivers / extcon / extcon-arizona.c
CommitLineData
f2c32a88
MB
1/*
2 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
3 *
4 * Copyright (C) 2012 Wolfson Microelectronics plc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/i2c.h>
20#include <linux/slab.h>
21#include <linux/interrupt.h>
22#include <linux/err.h>
23#include <linux/gpio.h>
34efe4dc 24#include <linux/input.h>
f2c32a88
MB
25#include <linux/platform_device.h>
26#include <linux/pm_runtime.h>
27#include <linux/regulator/consumer.h>
28#include <linux/extcon.h>
29
bbbd46e3
MB
30#include <sound/soc.h>
31
f2c32a88
MB
32#include <linux/mfd/arizona/core.h>
33#include <linux/mfd/arizona/pdata.h>
34#include <linux/mfd/arizona/registers.h>
35
6fed4d86 36#define ARIZONA_MAX_MICD_RANGE 8
34efe4dc 37
4f340333
MB
38#define ARIZONA_ACCDET_MODE_MIC 0
39#define ARIZONA_ACCDET_MODE_HPL 1
40#define ARIZONA_ACCDET_MODE_HPR 2
41
a288d648
RF
42#define ARIZONA_MICD_CLAMP_MODE_JDL 0x4
43#define ARIZONA_MICD_CLAMP_MODE_JDH 0x5
44#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
45#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
46
9dd5e53d
MB
47#define ARIZONA_HPDET_MAX 10000
48
2643fd64 49#define HPDET_DEBOUNCE 500
7abd4e2a 50#define DEFAULT_MICD_TIMEOUT 2000
a3e2078d 51
ffae24fe
CK
52#define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \
53 ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \
54 ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \
55 ARIZONA_MICD_LVL_7)
56
57#define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)
58
59#define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)
60
f2c32a88
MB
61struct arizona_extcon_info {
62 struct device *dev;
63 struct arizona *arizona;
64 struct mutex lock;
65 struct regulator *micvdd;
34efe4dc 66 struct input_dev *input;
f2c32a88 67
a3e2078d
MB
68 u16 last_jackdet;
69
f2c32a88
MB
70 int micd_mode;
71 const struct arizona_micd_config *micd_modes;
72 int micd_num_modes;
73
6fed4d86
MB
74 const struct arizona_micd_range *micd_ranges;
75 int num_micd_ranges;
76
7abd4e2a
MB
77 int micd_timeout;
78
f2c32a88 79 bool micd_reva;
dab63eb2 80 bool micd_clamp;
f2c32a88 81
0e27bd31 82 struct delayed_work hpdet_work;
cd59e796 83 struct delayed_work micd_detect_work;
939c5671 84 struct delayed_work micd_timeout_work;
0e27bd31 85
4f340333 86 bool hpdet_active;
bf14ee5a 87 bool hpdet_done;
9dd5e53d 88 bool hpdet_retried;
4f340333 89
dd235eea 90 int num_hpdet_res;
1eda6aa7 91 unsigned int hpdet_res[3];
dd235eea 92
f2c32a88
MB
93 bool mic;
94 bool detecting;
95 int jack_flips;
96
4f340333
MB
97 int hpdet_ip;
98
ef70a214 99 struct extcon_dev *edev;
f2c32a88
MB
100};
101
102static const struct arizona_micd_config micd_default_modes[] = {
41024243
CK
103 { ARIZONA_ACCDET_SRC, 1, 0 },
104 { 0, 2, 1 },
f2c32a88
MB
105};
106
6fed4d86
MB
107static const struct arizona_micd_range micd_default_ranges[] = {
108 { .max = 11, .key = BTN_0 },
109 { .max = 28, .key = BTN_1 },
110 { .max = 54, .key = BTN_2 },
111 { .max = 100, .key = BTN_3 },
112 { .max = 186, .key = BTN_4 },
113 { .max = 430, .key = BTN_5 },
114};
115
116static const int arizona_micd_levels[] = {
117 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
118 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
119 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
120 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
121 1257,
34efe4dc
MB
122};
123
325c6423
MB
124#define ARIZONA_CABLE_MECHANICAL 0
125#define ARIZONA_CABLE_MICROPHONE 1
126#define ARIZONA_CABLE_HEADPHONE 2
4f340333 127#define ARIZONA_CABLE_LINEOUT 3
f2c32a88
MB
128
129static const char *arizona_cable[] = {
325c6423
MB
130 "Mechanical",
131 "Microphone",
132 "Headphone",
4f340333 133 "Line-out",
f2c32a88
MB
134 NULL,
135};
136
9dd5e53d
MB
137static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
138
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:
148 mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |
149 ARIZONA_HP1L_SHRTI;
150 if (clamp)
151 val = ARIZONA_HP1L_SHRTO;
152 else
153 val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI;
154 break;
155 default:
156 mask = ARIZONA_RMV_SHRT_HP1L;
157 if (clamp)
158 val = ARIZONA_RMV_SHRT_HP1L;
159 break;
160 };
112bdfaa 161
03409071
MB
162 mutex_lock(&arizona->dapm->card->dapm_mutex);
163
112bdfaa 164 arizona->hpdet_clamp = clamp;
03409071 165
112bdfaa
CK
166 /* Keep the HP output stages disabled while doing the clamp */
167 if (clamp) {
df8c3dbe
MB
168 ret = regmap_update_bits(arizona->regmap,
169 ARIZONA_OUTPUT_ENABLES_1,
170 ARIZONA_OUT1L_ENA |
171 ARIZONA_OUT1R_ENA, 0);
03409071 172 if (ret != 0)
df8c3dbe
MB
173 dev_warn(arizona->dev,
174 "Failed to disable headphone outputs: %d\n",
175 ret);
176 }
177
112bdfaa 178 ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L,
43f0acd9 179 mask, val);
df8c3dbe 180 if (ret != 0)
112bdfaa 181 dev_warn(arizona->dev, "Failed to do clamp: %d\n",
03409071
MB
182 ret);
183
112bdfaa 184 ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R,
43f0acd9 185 mask, val);
df8c3dbe 186 if (ret != 0)
112bdfaa 187 dev_warn(arizona->dev, "Failed to do clamp: %d\n",
df8c3dbe
MB
188 ret);
189
112bdfaa
CK
190 /* Restore the desired state while not doing the clamp */
191 if (!clamp) {
df8c3dbe
MB
192 ret = regmap_update_bits(arizona->regmap,
193 ARIZONA_OUTPUT_ENABLES_1,
194 ARIZONA_OUT1L_ENA |
195 ARIZONA_OUT1R_ENA, arizona->hp_ena);
03409071 196 if (ret != 0)
df8c3dbe
MB
197 dev_warn(arizona->dev,
198 "Failed to restore headphone outputs: %d\n",
03409071
MB
199 ret);
200 }
201
202 mutex_unlock(&arizona->dapm->card->dapm_mutex);
203}
204
f2c32a88
MB
205static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
206{
207 struct arizona *arizona = info->arizona;
208
6fed4d86 209 mode %= info->micd_num_modes;
84eaa136 210
cd74f7b3
MB
211 if (arizona->pdata.micd_pol_gpio > 0)
212 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
213 info->micd_modes[mode].gpio);
f2c32a88
MB
214 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
215 ARIZONA_MICD_BIAS_SRC_MASK,
41024243
CK
216 info->micd_modes[mode].bias <<
217 ARIZONA_MICD_BIAS_SRC_SHIFT);
f2c32a88
MB
218 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
219 ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
220
221 info->micd_mode = mode;
222
223 dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
224}
225
bbbd46e3
MB
226static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
227{
41024243 228 switch (info->micd_modes[0].bias) {
bbbd46e3
MB
229 case 1:
230 return "MICBIAS1";
231 case 2:
232 return "MICBIAS2";
233 case 3:
234 return "MICBIAS3";
235 default:
236 return "MICVDD";
237 }
238}
239
240static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
241{
242 struct arizona *arizona = info->arizona;
243 const char *widget = arizona_extcon_get_micbias(info);
244 struct snd_soc_dapm_context *dapm = arizona->dapm;
245 int ret;
246
bbbd46e3
MB
247 ret = snd_soc_dapm_force_enable_pin(dapm, widget);
248 if (ret != 0)
249 dev_warn(arizona->dev, "Failed to enable %s: %d\n",
250 widget, ret);
251
bbbd46e3
MB
252 snd_soc_dapm_sync(dapm);
253
254 if (!arizona->pdata.micd_force_micbias) {
bbbd46e3
MB
255 ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
256 if (ret != 0)
257 dev_warn(arizona->dev, "Failed to disable %s: %d\n",
258 widget, ret);
259
bbbd46e3
MB
260 snd_soc_dapm_sync(dapm);
261 }
262}
263
9b1270c7
MB
264static void arizona_start_mic(struct arizona_extcon_info *info)
265{
266 struct arizona *arizona = info->arizona;
267 bool change;
268 int ret;
269
9b1270c7
MB
270 /* Microphone detection can't use idle mode */
271 pm_runtime_get(info->dev);
272
bbbd46e3
MB
273 if (info->detecting) {
274 ret = regulator_allow_bypass(info->micvdd, false);
275 if (ret != 0) {
276 dev_err(arizona->dev,
277 "Failed to regulate MICVDD: %d\n",
278 ret);
279 }
280 }
281
9b1270c7
MB
282 ret = regulator_enable(info->micvdd);
283 if (ret != 0) {
284 dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
285 ret);
286 }
287
288 if (info->micd_reva) {
289 regmap_write(arizona->regmap, 0x80, 0x3);
290 regmap_write(arizona->regmap, 0x294, 0);
291 regmap_write(arizona->regmap, 0x80, 0x0);
292 }
293
294 regmap_update_bits(arizona->regmap,
295 ARIZONA_ACCESSORY_DETECT_MODE_1,
296 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
297
bbbd46e3
MB
298 arizona_extcon_pulse_micbias(info);
299
9b1270c7
MB
300 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
301 ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
302 &change);
303 if (!change) {
304 regulator_disable(info->micvdd);
305 pm_runtime_put_autosuspend(info->dev);
306 }
307}
308
309static void arizona_stop_mic(struct arizona_extcon_info *info)
310{
311 struct arizona *arizona = info->arizona;
bbbd46e3
MB
312 const char *widget = arizona_extcon_get_micbias(info);
313 struct snd_soc_dapm_context *dapm = arizona->dapm;
9b1270c7 314 bool change;
bbbd46e3 315 int ret;
9b1270c7
MB
316
317 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
318 ARIZONA_MICD_ENA, 0,
319 &change);
320
bbbd46e3
MB
321 ret = snd_soc_dapm_disable_pin(dapm, widget);
322 if (ret != 0)
323 dev_warn(arizona->dev,
324 "Failed to disable %s: %d\n",
325 widget, ret);
326
bbbd46e3
MB
327 snd_soc_dapm_sync(dapm);
328
9b1270c7
MB
329 if (info->micd_reva) {
330 regmap_write(arizona->regmap, 0x80, 0x3);
331 regmap_write(arizona->regmap, 0x294, 2);
332 regmap_write(arizona->regmap, 0x80, 0x0);
333 }
334
bbbd46e3
MB
335 ret = regulator_allow_bypass(info->micvdd, true);
336 if (ret != 0) {
337 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
338 ret);
339 }
340
9b1270c7
MB
341 if (change) {
342 regulator_disable(info->micvdd);
343 pm_runtime_mark_last_busy(info->dev);
344 pm_runtime_put_autosuspend(info->dev);
345 }
346}
347
4f340333 348static struct {
24a279b1 349 unsigned int threshold;
4f340333
MB
350 unsigned int factor_a;
351 unsigned int factor_b;
352} arizona_hpdet_b_ranges[] = {
24a279b1
CK
353 { 100, 5528, 362464 },
354 { 169, 11084, 6186851 },
355 { 169, 11065, 65460395 },
4f340333
MB
356};
357
24a279b1
CK
358#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
359
4f340333
MB
360static struct {
361 int min;
362 int max;
363} arizona_hpdet_c_ranges[] = {
364 { 0, 30 },
365 { 8, 100 },
366 { 100, 1000 },
367 { 1000, 10000 },
368};
369
370static int arizona_hpdet_read(struct arizona_extcon_info *info)
371{
372 struct arizona *arizona = info->arizona;
373 unsigned int val, range;
374 int ret;
375
376 ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
377 if (ret != 0) {
378 dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
379 ret);
380 return ret;
381 }
382
383 switch (info->hpdet_ip) {
384 case 0:
385 if (!(val & ARIZONA_HP_DONE)) {
386 dev_err(arizona->dev, "HPDET did not complete: %x\n",
387 val);
e6dd8cf2 388 return -EAGAIN;
4f340333
MB
389 }
390
391 val &= ARIZONA_HP_LVL_MASK;
392 break;
393
394 case 1:
395 if (!(val & ARIZONA_HP_DONE_B)) {
396 dev_err(arizona->dev, "HPDET did not complete: %x\n",
397 val);
e6dd8cf2 398 return -EAGAIN;
4f340333
MB
399 }
400
401 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
402 if (ret != 0) {
403 dev_err(arizona->dev, "Failed to read HP value: %d\n",
404 ret);
e6dd8cf2 405 return -EAGAIN;
4f340333
MB
406 }
407
408 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
409 &range);
410 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
411 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
412
413 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
24a279b1
CK
414 (val < arizona_hpdet_b_ranges[range].threshold ||
415 val >= ARIZONA_HPDET_B_RANGE_MAX)) {
4f340333
MB
416 range++;
417 dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
418 range);
419 regmap_update_bits(arizona->regmap,
420 ARIZONA_HEADPHONE_DETECT_1,
421 ARIZONA_HP_IMPEDANCE_RANGE_MASK,
422 range <<
423 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
424 return -EAGAIN;
425 }
426
427 /* If we go out of range report top of range */
24a279b1
CK
428 if (val < arizona_hpdet_b_ranges[range].threshold ||
429 val >= ARIZONA_HPDET_B_RANGE_MAX) {
4f340333 430 dev_dbg(arizona->dev, "Measurement out of range\n");
9dd5e53d 431 return ARIZONA_HPDET_MAX;
4f340333
MB
432 }
433
434 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
435 val, range);
436
437 val = arizona_hpdet_b_ranges[range].factor_b
438 / ((val * 100) -
439 arizona_hpdet_b_ranges[range].factor_a);
440 break;
441
442 default:
443 dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
444 info->hpdet_ip);
445 case 2:
446 if (!(val & ARIZONA_HP_DONE_B)) {
447 dev_err(arizona->dev, "HPDET did not complete: %x\n",
448 val);
e6dd8cf2 449 return -EAGAIN;
4f340333
MB
450 }
451
452 val &= ARIZONA_HP_LVL_B_MASK;
77438610
CK
453 /* Convert to ohms, the value is in 0.5 ohm increments */
454 val /= 2;
4f340333
MB
455
456 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
457 &range);
458 range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
459 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
460
9141461d 461 /* Skip up a range, or report? */
4f340333
MB
462 if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
463 (val >= arizona_hpdet_c_ranges[range].max)) {
464 range++;
465 dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
466 arizona_hpdet_c_ranges[range].min,
467 arizona_hpdet_c_ranges[range].max);
468 regmap_update_bits(arizona->regmap,
469 ARIZONA_HEADPHONE_DETECT_1,
470 ARIZONA_HP_IMPEDANCE_RANGE_MASK,
471 range <<
472 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
473 return -EAGAIN;
474 }
9141461d
CK
475
476 if (range && (val < arizona_hpdet_c_ranges[range].min)) {
477 dev_dbg(arizona->dev, "Reporting range boundary %d\n",
478 arizona_hpdet_c_ranges[range].min);
479 val = arizona_hpdet_c_ranges[range].min;
480 }
4f340333
MB
481 }
482
483 dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
484 return val;
485}
486
9c2ba270
MB
487static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
488 bool *mic)
dd235eea
MB
489{
490 struct arizona *arizona = info->arizona;
1eda6aa7 491 int id_gpio = arizona->pdata.hpdet_id_gpio;
dd235eea
MB
492
493 /*
494 * If we're using HPDET for accessory identification we need
495 * to take multiple measurements, step through them in sequence.
496 */
497 if (arizona->pdata.hpdet_acc_id) {
498 info->hpdet_res[info->num_hpdet_res++] = *reading;
1eda6aa7
MB
499
500 /* Only check the mic directly if we didn't already ID it */
9c2ba270 501 if (id_gpio && info->num_hpdet_res == 1) {
1eda6aa7
MB
502 dev_dbg(arizona->dev, "Measuring mic\n");
503
504 regmap_update_bits(arizona->regmap,
505 ARIZONA_ACCESSORY_DETECT_MODE_1,
506 ARIZONA_ACCDET_MODE_MASK |
507 ARIZONA_ACCDET_SRC,
508 ARIZONA_ACCDET_MODE_HPR |
509 info->micd_modes[0].src);
510
511 gpio_set_value_cansleep(id_gpio, 1);
512
dd235eea
MB
513 regmap_update_bits(arizona->regmap,
514 ARIZONA_HEADPHONE_DETECT_1,
515 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
516 return -EAGAIN;
517 }
518
519 /* OK, got both. Now, compare... */
9c2ba270
MB
520 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
521 info->hpdet_res[0], info->hpdet_res[1]);
c37b387f
MB
522
523 /* Take the headphone impedance for the main report */
524 *reading = info->hpdet_res[0];
525
9dd5e53d
MB
526 /* Sometimes we get false readings due to slow insert */
527 if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
528 dev_dbg(arizona->dev, "Retrying high impedance\n");
529 info->num_hpdet_res = 0;
530 info->hpdet_retried = true;
531 arizona_start_hpdet_acc_id(info);
532 pm_runtime_put(info->dev);
533 return -EAGAIN;
534 }
535
1eda6aa7 536 /*
d97abdde 537 * If we measure the mic as high impedance
1eda6aa7 538 */
9c2ba270 539 if (!id_gpio || info->hpdet_res[1] > 50) {
dd235eea 540 dev_dbg(arizona->dev, "Detected mic\n");
9c2ba270 541 *mic = true;
bf14ee5a 542 info->detecting = true;
dd235eea
MB
543 } else {
544 dev_dbg(arizona->dev, "Detected headphone\n");
545 }
546
547 /* Make sure everything is reset back to the real polarity */
548 regmap_update_bits(arizona->regmap,
549 ARIZONA_ACCESSORY_DETECT_MODE_1,
550 ARIZONA_ACCDET_SRC,
551 info->micd_modes[0].src);
552 }
553
554 return 0;
555}
556
4f340333
MB
557static irqreturn_t arizona_hpdet_irq(int irq, void *data)
558{
559 struct arizona_extcon_info *info = data;
560 struct arizona *arizona = info->arizona;
1eda6aa7 561 int id_gpio = arizona->pdata.hpdet_id_gpio;
4f340333 562 int report = ARIZONA_CABLE_HEADPHONE;
dd235eea 563 int ret, reading;
9c2ba270 564 bool mic = false;
4f340333
MB
565
566 mutex_lock(&info->lock);
567
568 /* If we got a spurious IRQ for some reason then ignore it */
569 if (!info->hpdet_active) {
570 dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
571 mutex_unlock(&info->lock);
572 return IRQ_NONE;
573 }
574
575 /* If the cable was removed while measuring ignore the result */
ef70a214 576 ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL);
4f340333
MB
577 if (ret < 0) {
578 dev_err(arizona->dev, "Failed to check cable state: %d\n",
579 ret);
580 goto out;
581 } else if (!ret) {
582 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
583 goto done;
584 }
585
586 ret = arizona_hpdet_read(info);
d6675667 587 if (ret == -EAGAIN)
4f340333 588 goto out;
d6675667 589 else if (ret < 0)
4f340333 590 goto done;
dd235eea 591 reading = ret;
4f340333
MB
592
593 /* Reset back to starting range */
594 regmap_update_bits(arizona->regmap,
595 ARIZONA_HEADPHONE_DETECT_1,
dd235eea
MB
596 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
597 0);
598
9c2ba270 599 ret = arizona_hpdet_do_id(info, &reading, &mic);
d6675667 600 if (ret == -EAGAIN)
dd235eea 601 goto out;
d6675667 602 else if (ret < 0)
dd235eea 603 goto done;
4f340333
MB
604
605 /* Report high impedence cables as line outputs */
dd235eea 606 if (reading >= 5000)
4f340333
MB
607 report = ARIZONA_CABLE_LINEOUT;
608 else
609 report = ARIZONA_CABLE_HEADPHONE;
610
ef70a214 611 ret = extcon_set_cable_state_(info->edev, report, true);
4f340333
MB
612 if (ret != 0)
613 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
614 ret);
615
a3e00d4b
CK
616done:
617 /* Reset back to starting range */
618 regmap_update_bits(arizona->regmap,
619 ARIZONA_HEADPHONE_DETECT_1,
620 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
621 0);
622
112bdfaa 623 arizona_extcon_hp_clamp(info, false);
4f340333 624
1eda6aa7
MB
625 if (id_gpio)
626 gpio_set_value_cansleep(id_gpio, 0);
4f340333
MB
627
628 /* Revert back to MICDET mode */
629 regmap_update_bits(arizona->regmap,
630 ARIZONA_ACCESSORY_DETECT_MODE_1,
631 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
632
633 /* If we have a mic then reenable MICDET */
9c2ba270 634 if (mic || info->mic)
4f340333
MB
635 arizona_start_mic(info);
636
637 if (info->hpdet_active) {
638 pm_runtime_put_autosuspend(info->dev);
639 info->hpdet_active = false;
640 }
641
bf14ee5a
MB
642 info->hpdet_done = true;
643
4f340333
MB
644out:
645 mutex_unlock(&info->lock);
646
647 return IRQ_HANDLED;
648}
649
650static void arizona_identify_headphone(struct arizona_extcon_info *info)
651{
652 struct arizona *arizona = info->arizona;
653 int ret;
654
bf14ee5a
MB
655 if (info->hpdet_done)
656 return;
657
4f340333
MB
658 dev_dbg(arizona->dev, "Starting HPDET\n");
659
660 /* Make sure we keep the device enabled during the measurement */
661 pm_runtime_get(info->dev);
662
663 info->hpdet_active = true;
664
665 if (info->mic)
666 arizona_stop_mic(info);
667
112bdfaa 668 arizona_extcon_hp_clamp(info, true);
4f340333
MB
669
670 ret = regmap_update_bits(arizona->regmap,
671 ARIZONA_ACCESSORY_DETECT_MODE_1,
672 ARIZONA_ACCDET_MODE_MASK,
673 ARIZONA_ACCDET_MODE_HPL);
674 if (ret != 0) {
675 dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
676 goto err;
677 }
678
679 ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
680 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
681 if (ret != 0) {
682 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
683 ret);
684 goto err;
685 }
686
687 return;
688
689err:
690 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
691 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
692
693 /* Just report headphone */
34602486
NO
694 ret = extcon_set_cable_state_(info->edev,
695 ARIZONA_CABLE_HEADPHONE, true);
4f340333
MB
696 if (ret != 0)
697 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
698
699 if (info->mic)
700 arizona_start_mic(info);
701
702 info->hpdet_active = false;
703}
dd235eea
MB
704
705static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
706{
707 struct arizona *arizona = info->arizona;
9c2ba270
MB
708 int hp_reading = 32;
709 bool mic;
dd235eea
MB
710 int ret;
711
712 dev_dbg(arizona->dev, "Starting identification via HPDET\n");
713
714 /* Make sure we keep the device enabled during the measurement */
0e27bd31 715 pm_runtime_get_sync(info->dev);
dd235eea
MB
716
717 info->hpdet_active = true;
718
112bdfaa 719 arizona_extcon_hp_clamp(info, true);
dd235eea
MB
720
721 ret = regmap_update_bits(arizona->regmap,
722 ARIZONA_ACCESSORY_DETECT_MODE_1,
723 ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
724 info->micd_modes[0].src |
725 ARIZONA_ACCDET_MODE_HPL);
726 if (ret != 0) {
727 dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
728 goto err;
729 }
730
9c2ba270
MB
731 if (arizona->pdata.hpdet_acc_id_line) {
732 ret = regmap_update_bits(arizona->regmap,
733 ARIZONA_HEADPHONE_DETECT_1,
734 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
735 if (ret != 0) {
736 dev_err(arizona->dev,
737 "Can't start HPDETL measurement: %d\n",
738 ret);
739 goto err;
740 }
741 } else {
742 arizona_hpdet_do_id(info, &hp_reading, &mic);
4f340333
MB
743 }
744
dd235eea
MB
745 return;
746
747err:
748 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
749 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
750
751 /* Just report headphone */
34602486
NO
752 ret = extcon_set_cable_state_(info->edev,
753 ARIZONA_CABLE_HEADPHONE, true);
dd235eea
MB
754 if (ret != 0)
755 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
756
4f340333
MB
757 info->hpdet_active = false;
758}
759
939c5671
MB
760static void arizona_micd_timeout_work(struct work_struct *work)
761{
762 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
763 struct arizona_extcon_info,
764 micd_timeout_work.work);
939c5671
MB
765
766 mutex_lock(&info->lock);
767
768 dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
769 arizona_identify_headphone(info);
770
771 info->detecting = false;
772
773 arizona_stop_mic(info);
774
775 mutex_unlock(&info->lock);
776}
777
cd59e796 778static void arizona_micd_detect(struct work_struct *work)
f2c32a88 779{
cd59e796 780 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
781 struct arizona_extcon_info,
782 micd_detect_work.work);
f2c32a88 783 struct arizona *arizona = info->arizona;
e2c0f476 784 unsigned int val = 0, lvl;
6fed4d86 785 int ret, i, key;
f2c32a88 786
939c5671
MB
787 cancel_delayed_work_sync(&info->micd_timeout_work);
788
f2c32a88
MB
789 mutex_lock(&info->lock);
790
31a847e6 791 /* If the cable was removed while measuring ignore the result */
ef70a214 792 ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL);
31a847e6
CK
793 if (ret < 0) {
794 dev_err(arizona->dev, "Failed to check cable state: %d\n",
795 ret);
796 mutex_unlock(&info->lock);
797 return;
798 } else if (!ret) {
799 dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
800 mutex_unlock(&info->lock);
801 return;
802 }
803
ffae24fe 804 for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
e2c0f476
CK
805 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
806 if (ret != 0) {
c2275d2f
CC
807 dev_err(arizona->dev,
808 "Failed to read MICDET: %d\n", ret);
e2c0f476 809 mutex_unlock(&info->lock);
cd59e796 810 return;
e2c0f476
CK
811 }
812
813 dev_dbg(arizona->dev, "MICDET: %x\n", val);
f2c32a88 814
e2c0f476 815 if (!(val & ARIZONA_MICD_VALID)) {
c2275d2f
CC
816 dev_warn(arizona->dev,
817 "Microphone detection state invalid\n");
e2c0f476 818 mutex_unlock(&info->lock);
cd59e796 819 return;
e2c0f476
CK
820 }
821 }
f2c32a88 822
ffae24fe 823 if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
e2c0f476 824 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
f2c32a88 825 mutex_unlock(&info->lock);
cd59e796 826 return;
f2c32a88
MB
827 }
828
829 /* Due to jack detect this should never happen */
830 if (!(val & ARIZONA_MICD_STS)) {
831 dev_warn(arizona->dev, "Detected open circuit\n");
832 info->detecting = false;
833 goto handled;
834 }
835
836 /* If we got a high impedence we should have a headset, report it. */
ffae24fe 837 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
4f340333
MB
838 arizona_identify_headphone(info);
839
34602486
NO
840 ret = extcon_set_cable_state_(info->edev,
841 ARIZONA_CABLE_MICROPHONE, true);
f2c32a88
MB
842
843 if (ret != 0)
844 dev_err(arizona->dev, "Headset report failed: %d\n",
845 ret);
846
bbbd46e3 847 /* Don't need to regulate for button detection */
e368f525 848 ret = regulator_allow_bypass(info->micvdd, true);
bbbd46e3
MB
849 if (ret != 0) {
850 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
851 ret);
852 }
853
f2c32a88
MB
854 info->mic = true;
855 info->detecting = false;
856 goto handled;
857 }
858
859 /* If we detected a lower impedence during initial startup
860 * then we probably have the wrong polarity, flip it. Don't
861 * do this for the lowest impedences to speed up detection of
862 * plain headphones. If both polarities report a low
863 * impedence then give up and report headphones.
864 */
ffae24fe 865 if (info->detecting && (val & MICD_LVL_1_TO_7)) {
84eaa136 866 if (info->jack_flips >= info->micd_num_modes * 10) {
4f340333
MB
867 dev_dbg(arizona->dev, "Detected HP/line\n");
868 arizona_identify_headphone(info);
869
f2c32a88 870 info->detecting = false;
9ef2224d 871
4f340333 872 arizona_stop_mic(info);
f2c32a88
MB
873 } else {
874 info->micd_mode++;
875 if (info->micd_mode == info->micd_num_modes)
876 info->micd_mode = 0;
877 arizona_extcon_set_mode(info, info->micd_mode);
878
879 info->jack_flips++;
880 }
881
882 goto handled;
883 }
884
885 /*
886 * If we're still detecting and we detect a short then we've
34efe4dc 887 * got a headphone. Otherwise it's a button press.
f2c32a88 888 */
ffae24fe 889 if (val & MICD_LVL_0_TO_7) {
f2c32a88
MB
890 if (info->mic) {
891 dev_dbg(arizona->dev, "Mic button detected\n");
892
34efe4dc
MB
893 lvl = val & ARIZONA_MICD_LVL_MASK;
894 lvl >>= ARIZONA_MICD_LVL_SHIFT;
895
41a57850
MB
896 for (i = 0; i < info->num_micd_ranges; i++)
897 input_report_key(info->input,
898 info->micd_ranges[i].key, 0);
899
6fed4d86
MB
900 WARN_ON(!lvl);
901 WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
902 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
903 key = info->micd_ranges[ffs(lvl) - 1].key;
904 input_report_key(info->input, key, 1);
905 input_sync(info->input);
906 }
34efe4dc 907
f2c32a88
MB
908 } else if (info->detecting) {
909 dev_dbg(arizona->dev, "Headphone detected\n");
910 info->detecting = false;
911 arizona_stop_mic(info);
912
4f340333 913 arizona_identify_headphone(info);
f2c32a88
MB
914 } else {
915 dev_warn(arizona->dev, "Button with no mic: %x\n",
916 val);
917 }
918 } else {
919 dev_dbg(arizona->dev, "Mic button released\n");
6fed4d86 920 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 921 input_report_key(info->input,
6fed4d86 922 info->micd_ranges[i].key, 0);
34efe4dc 923 input_sync(info->input);
bbbd46e3 924 arizona_extcon_pulse_micbias(info);
f2c32a88
MB
925 }
926
927handled:
939c5671 928 if (info->detecting)
df9a5ab4
MB
929 queue_delayed_work(system_power_efficient_wq,
930 &info->micd_timeout_work,
931 msecs_to_jiffies(info->micd_timeout));
939c5671 932
f2c32a88
MB
933 pm_runtime_mark_last_busy(info->dev);
934 mutex_unlock(&info->lock);
cd59e796
MB
935}
936
937static irqreturn_t arizona_micdet(int irq, void *data)
938{
939 struct arizona_extcon_info *info = data;
940 struct arizona *arizona = info->arizona;
941 int debounce = arizona->pdata.micd_detect_debounce;
942
943 cancel_delayed_work_sync(&info->micd_detect_work);
944 cancel_delayed_work_sync(&info->micd_timeout_work);
945
946 mutex_lock(&info->lock);
947 if (!info->detecting)
948 debounce = 0;
949 mutex_unlock(&info->lock);
950
951 if (debounce)
df9a5ab4
MB
952 queue_delayed_work(system_power_efficient_wq,
953 &info->micd_detect_work,
954 msecs_to_jiffies(debounce));
cd59e796
MB
955 else
956 arizona_micd_detect(&info->micd_detect_work.work);
f2c32a88
MB
957
958 return IRQ_HANDLED;
959}
960
0e27bd31
MB
961static void arizona_hpdet_work(struct work_struct *work)
962{
963 struct arizona_extcon_info *info = container_of(work,
c2275d2f
CC
964 struct arizona_extcon_info,
965 hpdet_work.work);
0e27bd31
MB
966
967 mutex_lock(&info->lock);
968 arizona_start_hpdet_acc_id(info);
969 mutex_unlock(&info->lock);
970}
971
f2c32a88
MB
972static irqreturn_t arizona_jackdet(int irq, void *data)
973{
974 struct arizona_extcon_info *info = data;
975 struct arizona *arizona = info->arizona;
92a49871 976 unsigned int val, present, mask;
939c5671 977 bool cancelled_hp, cancelled_mic;
34efe4dc 978 int ret, i;
f2c32a88 979
939c5671
MB
980 cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
981 cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
f2c32a88 982
a3e2078d 983 pm_runtime_get_sync(info->dev);
0e27bd31 984
f2c32a88
MB
985 mutex_lock(&info->lock);
986
92a49871
MB
987 if (arizona->pdata.jd_gpio5) {
988 mask = ARIZONA_MICD_CLAMP_STS;
a288d648
RF
989 if (arizona->pdata.jd_invert)
990 present = ARIZONA_MICD_CLAMP_STS;
991 else
992 present = 0;
92a49871
MB
993 } else {
994 mask = ARIZONA_JD1_STS;
a288d648
RF
995 if (arizona->pdata.jd_invert)
996 present = 0;
997 else
998 present = ARIZONA_JD1_STS;
92a49871
MB
999 }
1000
f2c32a88
MB
1001 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
1002 if (ret != 0) {
1003 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
1004 ret);
1005 mutex_unlock(&info->lock);
1006 pm_runtime_put_autosuspend(info->dev);
1007 return IRQ_NONE;
1008 }
1009
a3e2078d
MB
1010 val &= mask;
1011 if (val == info->last_jackdet) {
1012 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
939c5671 1013 if (cancelled_hp)
df9a5ab4
MB
1014 queue_delayed_work(system_power_efficient_wq,
1015 &info->hpdet_work,
1016 msecs_to_jiffies(HPDET_DEBOUNCE));
a3e2078d 1017
c2275d2f
CC
1018 if (cancelled_mic) {
1019 int micd_timeout = info->micd_timeout;
1020
df9a5ab4
MB
1021 queue_delayed_work(system_power_efficient_wq,
1022 &info->micd_timeout_work,
c2275d2f
CC
1023 msecs_to_jiffies(micd_timeout));
1024 }
939c5671 1025
a3e2078d
MB
1026 goto out;
1027 }
1028 info->last_jackdet = val;
1029
1030 if (info->last_jackdet == present) {
f2c32a88 1031 dev_dbg(arizona->dev, "Detected jack\n");
ef70a214 1032 ret = extcon_set_cable_state_(info->edev,
325c6423 1033 ARIZONA_CABLE_MECHANICAL, true);
f2c32a88
MB
1034
1035 if (ret != 0)
1036 dev_err(arizona->dev, "Mechanical report failed: %d\n",
1037 ret);
1038
dd235eea
MB
1039 if (!arizona->pdata.hpdet_acc_id) {
1040 info->detecting = true;
1041 info->mic = false;
1042 info->jack_flips = 0;
1043
1044 arizona_start_mic(info);
1045 } else {
df9a5ab4
MB
1046 queue_delayed_work(system_power_efficient_wq,
1047 &info->hpdet_work,
1048 msecs_to_jiffies(HPDET_DEBOUNCE));
dd235eea 1049 }
4e616877
MB
1050
1051 regmap_update_bits(arizona->regmap,
1052 ARIZONA_JACK_DETECT_DEBOUNCE,
1053 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
f2c32a88
MB
1054 } else {
1055 dev_dbg(arizona->dev, "Detected jack removal\n");
1056
1057 arizona_stop_mic(info);
1058
dd235eea
MB
1059 info->num_hpdet_res = 0;
1060 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1061 info->hpdet_res[i] = 0;
1062 info->mic = false;
bf14ee5a 1063 info->hpdet_done = false;
9dd5e53d 1064 info->hpdet_retried = false;
92a49871 1065
6fed4d86 1066 for (i = 0; i < info->num_micd_ranges; i++)
34efe4dc 1067 input_report_key(info->input,
6fed4d86 1068 info->micd_ranges[i].key, 0);
34efe4dc
MB
1069 input_sync(info->input);
1070
ef70a214 1071 ret = extcon_update_state(info->edev, 0xffffffff, 0);
f2c32a88
MB
1072 if (ret != 0)
1073 dev_err(arizona->dev, "Removal report failed: %d\n",
1074 ret);
4e616877
MB
1075
1076 regmap_update_bits(arizona->regmap,
1077 ARIZONA_JACK_DETECT_DEBOUNCE,
1078 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1079 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
f2c32a88
MB
1080 }
1081
7abd4e2a
MB
1082 if (arizona->pdata.micd_timeout)
1083 info->micd_timeout = arizona->pdata.micd_timeout;
1084 else
1085 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1086
cb9005d7 1087out:
5d9ab708
CK
1088 /* Clear trig_sts to make sure DCVDD is not forced up */
1089 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1090 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1091 ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1092 ARIZONA_JD1_FALL_TRIG_STS |
1093 ARIZONA_JD1_RISE_TRIG_STS);
1094
f2c32a88
MB
1095 mutex_unlock(&info->lock);
1096
1097 pm_runtime_mark_last_busy(info->dev);
1098 pm_runtime_put_autosuspend(info->dev);
1099
1100 return IRQ_HANDLED;
1101}
1102
6fed4d86
MB
1103/* Map a level onto a slot in the register bank */
1104static void arizona_micd_set_level(struct arizona *arizona, int index,
1105 unsigned int level)
1106{
1107 int reg;
1108 unsigned int mask;
1109
1110 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1111
1112 if (!(index % 2)) {
1113 mask = 0x3f00;
1114 level <<= 8;
1115 } else {
1116 mask = 0x3f;
1117 }
1118
1119 /* Program the level itself */
1120 regmap_update_bits(arizona->regmap, reg, mask, level);
1121}
1122
44f34fd4 1123static int arizona_extcon_probe(struct platform_device *pdev)
f2c32a88
MB
1124{
1125 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
6ac6b475 1126 struct arizona_pdata *pdata = &arizona->pdata;
f2c32a88 1127 struct arizona_extcon_info *info;
e56a0a57 1128 unsigned int val;
a288d648 1129 unsigned int clamp_mode;
92a49871 1130 int jack_irq_fall, jack_irq_rise;
6fed4d86 1131 int ret, mode, i, j;
f2c32a88 1132
bbbd46e3
MB
1133 if (!arizona->dapm || !arizona->dapm->card)
1134 return -EPROBE_DEFER;
1135
f2c32a88 1136 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0a16ee63 1137 if (!info)
d88cc367 1138 return -ENOMEM;
f2c32a88 1139
17271f60 1140 info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
f2c32a88
MB
1141 if (IS_ERR(info->micvdd)) {
1142 ret = PTR_ERR(info->micvdd);
1143 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
d88cc367 1144 return ret;
f2c32a88
MB
1145 }
1146
1147 mutex_init(&info->lock);
1148 info->arizona = arizona;
1149 info->dev = &pdev->dev;
a3e2078d 1150 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
0e27bd31 1151 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
cd59e796 1152 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
939c5671 1153 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
f2c32a88
MB
1154 platform_set_drvdata(pdev, info);
1155
1156 switch (arizona->type) {
1157 case WM5102:
1158 switch (arizona->rev) {
1159 case 0:
1160 info->micd_reva = true;
1161 break;
1162 default:
dab63eb2 1163 info->micd_clamp = true;
4f340333 1164 info->hpdet_ip = 1;
f2c32a88
MB
1165 break;
1166 }
1167 break;
77438610 1168 case WM5110:
2f2b6aa8 1169 case WM8280:
77438610
CK
1170 switch (arizona->rev) {
1171 case 0 ... 2:
1172 break;
1173 default:
1174 info->micd_clamp = true;
1175 info->hpdet_ip = 2;
1176 break;
1177 }
1178 break;
f2c32a88
MB
1179 default:
1180 break;
1181 }
1182
ef70a214
CC
1183 info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
1184 if (IS_ERR(info->edev)) {
1185 dev_err(&pdev->dev, "failed to allocate extcon device\n");
1186 return -ENOMEM;
1187 }
1188 info->edev->name = "Headset Jack";
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.270904 seconds and 5 git commands to generate.