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