extcon: arizona: Remove the setting of device name
[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:
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
d0fd5fbc 383 switch (info->hpdet_ip_version) {
4f340333
MB
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",
d0fd5fbc 444 info->hpdet_ip_version);
4f340333
MB
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;
d0fd5fbc 1164 info->hpdet_ip_version = 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;
d0fd5fbc 1175 info->hpdet_ip_version = 2;
77438610
CK
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 }
f2c32a88 1188
ef70a214 1189 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
f2c32a88 1190 if (ret < 0) {
8e5f5018 1191 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
f2c32a88 1192 ret);
d88cc367 1193 return ret;
f2c32a88
MB
1194 }
1195
6fed4d86
MB
1196 info->input = devm_input_allocate_device(&pdev->dev);
1197 if (!info->input) {
1198 dev_err(arizona->dev, "Can't allocate input dev\n");
1199 ret = -ENOMEM;
1200 goto err_register;
1201 }
1202
1203 info->input->name = "Headset";
1204 info->input->phys = "arizona/extcon";
6fed4d86 1205
f2c32a88
MB
1206 if (pdata->num_micd_configs) {
1207 info->micd_modes = pdata->micd_configs;
1208 info->micd_num_modes = pdata->num_micd_configs;
1209 } else {
1210 info->micd_modes = micd_default_modes;
1211 info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1212 }
1213
1214 if (arizona->pdata.micd_pol_gpio > 0) {
1215 if (info->micd_modes[0].gpio)
1216 mode = GPIOF_OUT_INIT_HIGH;
1217 else
1218 mode = GPIOF_OUT_INIT_LOW;
1219
1220 ret = devm_gpio_request_one(&pdev->dev,
1221 arizona->pdata.micd_pol_gpio,
1222 mode,
1223 "MICD polarity");
1224 if (ret != 0) {
1225 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1226 arizona->pdata.micd_pol_gpio, ret);
1227 goto err_register;
1228 }
1229 }
1230
1eda6aa7
MB
1231 if (arizona->pdata.hpdet_id_gpio > 0) {
1232 ret = devm_gpio_request_one(&pdev->dev,
1233 arizona->pdata.hpdet_id_gpio,
1234 GPIOF_OUT_INIT_LOW,
1235 "HPDET");
1236 if (ret != 0) {
1237 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1238 arizona->pdata.hpdet_id_gpio, ret);
1239 goto err_register;
1240 }
1241 }
1242
b17e5462
MB
1243 if (arizona->pdata.micd_bias_start_time)
1244 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1245 ARIZONA_MICD_BIAS_STARTTIME_MASK,
1246 arizona->pdata.micd_bias_start_time
1247 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1248
2e033db5
MB
1249 if (arizona->pdata.micd_rate)
1250 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1251 ARIZONA_MICD_RATE_MASK,
1252 arizona->pdata.micd_rate
1253 << ARIZONA_MICD_RATE_SHIFT);
1254
1255 if (arizona->pdata.micd_dbtime)
1256 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1257 ARIZONA_MICD_DBTIME_MASK,
1258 arizona->pdata.micd_dbtime
1259 << ARIZONA_MICD_DBTIME_SHIFT);
1260
6fed4d86
MB
1261 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1262
1263 if (arizona->pdata.num_micd_ranges) {
1264 info->micd_ranges = pdata->micd_ranges;
1265 info->num_micd_ranges = pdata->num_micd_ranges;
1266 } else {
1267 info->micd_ranges = micd_default_ranges;
1268 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1269 }
1270
1271 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1272 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1273 arizona->pdata.num_micd_ranges);
1274 }
1275
1276 if (info->num_micd_ranges > 1) {
1277 for (i = 1; i < info->num_micd_ranges; i++) {
1278 if (info->micd_ranges[i - 1].max >
1279 info->micd_ranges[i].max) {
1280 dev_err(arizona->dev,
1281 "MICD ranges must be sorted\n");
1282 ret = -EINVAL;
1283 goto err_input;
1284 }
1285 }
1286 }
1287
1288 /* Disable all buttons by default */
1289 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1290 ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1291
1292 /* Set up all the buttons the user specified */
1293 for (i = 0; i < info->num_micd_ranges; i++) {
1294 for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1295 if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1296 break;
1297
1298 if (j == ARRAY_SIZE(arizona_micd_levels)) {
1299 dev_err(arizona->dev, "Unsupported MICD level %d\n",
1300 info->micd_ranges[i].max);
1301 ret = -EINVAL;
1302 goto err_input;
1303 }
1304
1305 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1306 arizona_micd_levels[j], i);
1307
1308 arizona_micd_set_level(arizona, i, j);
1309 input_set_capability(info->input, EV_KEY,
1310 info->micd_ranges[i].key);
1311
1312 /* Enable reporting of that range */
1313 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1314 1 << i, 1 << i);
1315 }
1316
1317 /* Set all the remaining keys to a maximum */
1318 for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1319 arizona_micd_set_level(arizona, i, 0x3f);
1320
dab63eb2 1321 /*
92a49871
MB
1322 * If we have a clamp use it, activating in conjunction with
1323 * GPIO5 if that is connected for jack detect operation.
dab63eb2
MB
1324 */
1325 if (info->micd_clamp) {
92a49871 1326 if (arizona->pdata.jd_gpio5) {
e56a0a57
MB
1327 /* Put the GPIO into input mode with optional pull */
1328 val = 0xc101;
1329 if (arizona->pdata.jd_gpio5_nopull)
1330 val &= ~ARIZONA_GPN_PU;
1331
92a49871 1332 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
e56a0a57 1333 val);
92a49871 1334
a288d648
RF
1335 if (arizona->pdata.jd_invert)
1336 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
1337 else
1338 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
92a49871 1339 } else {
a288d648
RF
1340 if (arizona->pdata.jd_invert)
1341 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
1342 else
1343 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
92a49871
MB
1344 }
1345
a288d648
RF
1346 regmap_update_bits(arizona->regmap,
1347 ARIZONA_MICD_CLAMP_CONTROL,
1348 ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
1349
dab63eb2
MB
1350 regmap_update_bits(arizona->regmap,
1351 ARIZONA_JACK_DETECT_DEBOUNCE,
1352 ARIZONA_MICD_CLAMP_DB,
1353 ARIZONA_MICD_CLAMP_DB);
1354 }
1355
f2c32a88
MB
1356 arizona_extcon_set_mode(info, 0);
1357
1358 pm_runtime_enable(&pdev->dev);
1359 pm_runtime_idle(&pdev->dev);
1360 pm_runtime_get_sync(&pdev->dev);
1361
92a49871
MB
1362 if (arizona->pdata.jd_gpio5) {
1363 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1364 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1365 } else {
1366 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1367 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1368 }
1369
1370 ret = arizona_request_irq(arizona, jack_irq_rise,
f2c32a88
MB
1371 "JACKDET rise", arizona_jackdet, info);
1372 if (ret != 0) {
1373 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1374 ret);
34efe4dc 1375 goto err_input;
f2c32a88
MB
1376 }
1377
92a49871 1378 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
f2c32a88
MB
1379 if (ret != 0) {
1380 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1381 ret);
1382 goto err_rise;
1383 }
1384
92a49871 1385 ret = arizona_request_irq(arizona, jack_irq_fall,
f2c32a88
MB
1386 "JACKDET fall", arizona_jackdet, info);
1387 if (ret != 0) {
1388 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1389 goto err_rise_wake;
1390 }
1391
92a49871 1392 ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
f2c32a88
MB
1393 if (ret != 0) {
1394 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1395 ret);
1396 goto err_fall;
1397 }
1398
1399 ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1400 "MICDET", arizona_micdet, info);
1401 if (ret != 0) {
1402 dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1403 goto err_fall_wake;
1404 }
1405
4f340333
MB
1406 ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1407 "HPDET", arizona_hpdet_irq, info);
1408 if (ret != 0) {
1409 dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1410 goto err_micdet;
1411 }
1412
f2c32a88
MB
1413 arizona_clk32k_enable(arizona);
1414 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1415 ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1416 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1417 ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1418
b8575a11
MB
1419 ret = regulator_allow_bypass(info->micvdd, true);
1420 if (ret != 0)
1421 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1422 ret);
1423
f2c32a88
MB
1424 pm_runtime_put(&pdev->dev);
1425
34efe4dc
MB
1426 ret = input_register_device(info->input);
1427 if (ret) {
1428 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
4f340333 1429 goto err_hpdet;
34efe4dc
MB
1430 }
1431
f2c32a88
MB
1432 return 0;
1433
4f340333
MB
1434err_hpdet:
1435 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
80732cc1
MB
1436err_micdet:
1437 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
f2c32a88 1438err_fall_wake:
92a49871 1439 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
f2c32a88 1440err_fall:
92a49871 1441 arizona_free_irq(arizona, jack_irq_fall, info);
f2c32a88 1442err_rise_wake:
92a49871 1443 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
f2c32a88 1444err_rise:
92a49871 1445 arizona_free_irq(arizona, jack_irq_rise, info);
34efe4dc 1446err_input:
f2c32a88
MB
1447err_register:
1448 pm_runtime_disable(&pdev->dev);
f2c32a88
MB
1449 return ret;
1450}
1451
93ed0327 1452static int arizona_extcon_remove(struct platform_device *pdev)
f2c32a88
MB
1453{
1454 struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1455 struct arizona *arizona = info->arizona;
92a49871 1456 int jack_irq_rise, jack_irq_fall;
f2c32a88
MB
1457
1458 pm_runtime_disable(&pdev->dev);
1459
dab63eb2
MB
1460 regmap_update_bits(arizona->regmap,
1461 ARIZONA_MICD_CLAMP_CONTROL,
1462 ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1463
92a49871
MB
1464 if (arizona->pdata.jd_gpio5) {
1465 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1466 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1467 } else {
1468 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1469 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1470 }
1471
1472 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1473 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1474 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
f2c32a88 1475 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
92a49871
MB
1476 arizona_free_irq(arizona, jack_irq_rise, info);
1477 arizona_free_irq(arizona, jack_irq_fall, info);
0e27bd31 1478 cancel_delayed_work_sync(&info->hpdet_work);
f2c32a88
MB
1479 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1480 ARIZONA_JD1_ENA, 0);
1481 arizona_clk32k_disable(arizona);
f2c32a88
MB
1482
1483 return 0;
1484}
1485
1486static struct platform_driver arizona_extcon_driver = {
1487 .driver = {
1488 .name = "arizona-extcon",
f2c32a88
MB
1489 },
1490 .probe = arizona_extcon_probe,
5f7e2228 1491 .remove = arizona_extcon_remove,
f2c32a88
MB
1492};
1493
1494module_platform_driver(arizona_extcon_driver);
1495
1496MODULE_DESCRIPTION("Arizona Extcon driver");
1497MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1498MODULE_LICENSE("GPL");
1499MODULE_ALIAS("platform:extcon-arizona");
This page took 0.232936 seconds and 5 git commands to generate.