Loading...
1// SPDX-License-Identifier: GPL-2.0
2//
3// CS42L43 CODEC driver jack handling
4//
5// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7
8#include <linux/build_bug.h>
9#include <linux/completion.h>
10#include <linux/delay.h>
11#include <linux/errno.h>
12#include <linux/irq.h>
13#include <linux/jiffies.h>
14#include <linux/mfd/cs42l43.h>
15#include <linux/mfd/cs42l43-regs.h>
16#include <linux/mutex.h>
17#include <linux/pm_runtime.h>
18#include <linux/property.h>
19#include <linux/regmap.h>
20#include <linux/time.h>
21#include <linux/workqueue.h>
22#include <sound/control.h>
23#include <sound/jack.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc-component.h>
27#include <sound/soc-jack.h>
28#include <sound/soc.h>
29
30#include "cs42l43.h"
31
32static const unsigned int cs42l43_accdet_us[] = {
33 20, 100, 1000, 10000, 50000, 75000, 100000, 200000,
34};
35
36static const unsigned int cs42l43_accdet_db_ms[] = {
37 0, 125, 250, 500, 750, 1000, 1250, 1500,
38};
39
40static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 };
41
42static const unsigned int cs42l43_accdet_bias_sense[] = {
43 14, 24, 43, 52, 61, 71, 90, 99, 0,
44};
45
46static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const prop,
47 unsigned int defval, unsigned int *val,
48 const unsigned int *values, const int nvalues)
49{
50 struct cs42l43 *cs42l43 = priv->core;
51 int i, ret;
52
53 ret = device_property_read_u32(cs42l43->dev, prop, &defval);
54 if (ret != -EINVAL && ret < 0) {
55 dev_err(priv->dev, "Property %s malformed: %d\n", prop, ret);
56 return ret;
57 }
58
59 if (val)
60 *val = defval;
61
62 for (i = 0; i < nvalues; i++)
63 if (defval == values[i])
64 return i;
65
66 dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval);
67 return -EINVAL;
68}
69
70int cs42l43_set_jack(struct snd_soc_component *component,
71 struct snd_soc_jack *jack, void *d)
72{
73 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
74 struct cs42l43 *cs42l43 = priv->core;
75 /* This tip sense invert is always set, HW wants an inverted signal */
76 unsigned int tip_deb = CS42L43_TIPSENSE_INV_MASK;
77 unsigned int hs2 = 0x2 << CS42L43_HSDET_MODE_SHIFT;
78 unsigned int autocontrol = 0, pdncntl = 0;
79 int ret;
80
81 dev_dbg(priv->dev, "Configure accessory detect\n");
82
83 ret = pm_runtime_resume_and_get(priv->dev);
84 if (ret) {
85 dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
86 return ret;
87 }
88
89 mutex_lock(&priv->jack_lock);
90
91 priv->jack_hp = jack;
92
93 if (!jack)
94 goto done;
95
96 ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
97 if (ret != -EINVAL) {
98 if (ret < 0) {
99 dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
100 ret);
101 goto error;
102 }
103
104 if (ret > CS42L43_N_BUTTONS) {
105 ret = -EINVAL;
106 dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
107 goto error;
108 }
109
110 ret = device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
111 priv->buttons, ret);
112 if (ret < 0) {
113 dev_err(priv->dev, "Property cirrus,button-ohms malformed: %d\n",
114 ret);
115 goto error;
116 }
117 } else {
118 priv->buttons[0] = 70;
119 priv->buttons[1] = 185;
120 priv->buttons[2] = 355;
121 priv->buttons[3] = 735;
122 }
123
124 ret = cs42l43_find_index(priv, "cirrus,detect-us", 50000, &priv->detect_us,
125 cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us));
126 if (ret < 0)
127 goto error;
128
129 hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT;
130
131 priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low");
132
133 ret = cs42l43_find_index(priv, "cirrus,bias-ramp-ms", 170,
134 &priv->bias_ramp_ms, cs42l43_accdet_ramp_ms,
135 ARRAY_SIZE(cs42l43_accdet_ramp_ms));
136 if (ret < 0)
137 goto error;
138
139 hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT;
140
141 ret = cs42l43_find_index(priv, "cirrus,bias-sense-microamp", 14,
142 &priv->bias_sense_ua, cs42l43_accdet_bias_sense,
143 ARRAY_SIZE(cs42l43_accdet_bias_sense));
144 if (ret < 0)
145 goto error;
146
147 if (priv->bias_sense_ua)
148 autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT;
149
150 if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute"))
151 autocontrol |= CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK;
152
153 ret = device_property_read_u32(cs42l43->dev, "cirrus,tip-debounce-ms",
154 &priv->tip_debounce_ms);
155 if (ret < 0 && ret != -EINVAL) {
156 dev_err(priv->dev, "Property cirrus,tip-debounce-ms malformed: %d\n", ret);
157 goto error;
158 }
159
160 /* This tip sense invert is set normally, as TIPSENSE_INV already inverted */
161 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-invert"))
162 autocontrol |= 0x1 << CS42L43_JACKDET_INV_SHIFT;
163
164 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup"))
165 autocontrol |= 0x1 << CS42L43_JACKDET_MODE_SHIFT;
166 else
167 autocontrol |= 0x3 << CS42L43_JACKDET_MODE_SHIFT;
168
169 ret = cs42l43_find_index(priv, "cirrus,tip-fall-db-ms", 500,
170 NULL, cs42l43_accdet_db_ms,
171 ARRAY_SIZE(cs42l43_accdet_db_ms));
172 if (ret < 0)
173 goto error;
174
175 tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT;
176
177 ret = cs42l43_find_index(priv, "cirrus,tip-rise-db-ms", 500,
178 NULL, cs42l43_accdet_db_ms,
179 ARRAY_SIZE(cs42l43_accdet_db_ms));
180 if (ret < 0)
181 goto error;
182
183 tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT;
184
185 if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) {
186 unsigned int ring_deb = 0;
187
188 priv->use_ring_sense = true;
189
190 /* HW wants an inverted signal, so invert the invert */
191 if (!device_property_read_bool(cs42l43->dev, "cirrus,ring-invert"))
192 ring_deb |= CS42L43_RINGSENSE_INV_MASK;
193
194 if (!device_property_read_bool(cs42l43->dev,
195 "cirrus,ring-disable-pullup"))
196 ring_deb |= CS42L43_RINGSENSE_PULLUP_PDNB_MASK;
197
198 ret = cs42l43_find_index(priv, "cirrus,ring-fall-db-ms", 500,
199 NULL, cs42l43_accdet_db_ms,
200 ARRAY_SIZE(cs42l43_accdet_db_ms));
201 if (ret < 0)
202 goto error;
203
204 ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT;
205
206 ret = cs42l43_find_index(priv, "cirrus,ring-rise-db-ms", 500,
207 NULL, cs42l43_accdet_db_ms,
208 ARRAY_SIZE(cs42l43_accdet_db_ms));
209 if (ret < 0)
210 goto error;
211
212 ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT;
213 pdncntl |= CS42L43_RING_SENSE_EN_MASK;
214
215 regmap_update_bits(cs42l43->regmap, CS42L43_RINGSENSE_DEB_CTRL,
216 CS42L43_RINGSENSE_INV_MASK |
217 CS42L43_RINGSENSE_PULLUP_PDNB_MASK |
218 CS42L43_RINGSENSE_FALLING_DB_TIME_MASK |
219 CS42L43_RINGSENSE_RISING_DB_TIME_MASK,
220 ring_deb);
221 }
222
223 regmap_update_bits(cs42l43->regmap, CS42L43_TIPSENSE_DEB_CTRL,
224 CS42L43_TIPSENSE_INV_MASK |
225 CS42L43_TIPSENSE_FALLING_DB_TIME_MASK |
226 CS42L43_TIPSENSE_RISING_DB_TIME_MASK, tip_deb);
227 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
228 CS42L43_HSBIAS_RAMP_MASK | CS42L43_HSDET_MODE_MASK |
229 CS42L43_AUTO_HSDET_TIME_MASK, hs2);
230
231done:
232 ret = 0;
233
234 regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
235 CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK |
236 CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol);
237 regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
238 CS42L43_RING_SENSE_EN_MASK, pdncntl);
239
240 dev_dbg(priv->dev, "Successfully configured accessory detect\n");
241
242error:
243 mutex_unlock(&priv->jack_lock);
244
245 pm_runtime_mark_last_busy(priv->dev);
246 pm_runtime_put_autosuspend(priv->dev);
247
248 return ret;
249}
250
251static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
252{
253 struct cs42l43 *cs42l43 = priv->core;
254 unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT;
255
256 dev_dbg(priv->dev, "Start headset bias\n");
257
258 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
259 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
260
261 if (!type_detect) {
262 if (priv->bias_low)
263 val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
264
265 if (priv->bias_sense_ua)
266 regmap_update_bits(cs42l43->regmap,
267 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
268 CS42L43_HSBIAS_SENSE_EN_MASK |
269 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
270 CS42L43_HSBIAS_SENSE_EN_MASK |
271 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
272 }
273
274 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
275 CS42L43_HSBIAS_MODE_MASK, val);
276
277 msleep(priv->bias_ramp_ms);
278}
279
280static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv)
281{
282 struct cs42l43 *cs42l43 = priv->core;
283
284 dev_dbg(priv->dev, "Stop headset bias\n");
285
286 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
287 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
288
289 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
290 CS42L43_HS_CLAMP_DISABLE_MASK, 0);
291
292 if (priv->bias_sense_ua) {
293 regmap_update_bits(cs42l43->regmap,
294 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
295 CS42L43_HSBIAS_SENSE_EN_MASK |
296 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
297 }
298}
299
300irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
301{
302 struct cs42l43_codec *priv = data;
303
304 queue_delayed_work(system_wq, &priv->bias_sense_timeout,
305 msecs_to_jiffies(1000));
306
307 return IRQ_HANDLED;
308}
309
310#define CS42L43_JACK_PRESENT 0x3
311#define CS42L43_JACK_ABSENT 0x0
312
313#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
314#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
315#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
316#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
317#define CS42L43_JACK_LINEIN (SND_JACK_MECHANICAL | SND_JACK_LINEIN)
318#define CS42L43_JACK_EXTENSION (SND_JACK_MECHANICAL)
319#define CS42L43_JACK_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | \
320 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5)
321
322static inline bool cs42l43_jack_present(struct cs42l43_codec *priv)
323{
324 struct cs42l43 *cs42l43 = priv->core;
325 unsigned int sts = 0;
326
327 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
328
329 sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
330
331 return sts == CS42L43_JACK_PRESENT;
332}
333
334static void cs42l43_start_button_detect(struct cs42l43_codec *priv)
335{
336 struct cs42l43 *cs42l43 = priv->core;
337 unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
338
339 dev_dbg(priv->dev, "Start button detect\n");
340
341 priv->button_detect_running = true;
342
343 if (priv->bias_low)
344 val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
345
346 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
347 CS42L43_BUTTON_DETECT_MODE_MASK |
348 CS42L43_MIC_LVL_DET_DISABLE_MASK, val);
349}
350
351static void cs42l43_stop_button_detect(struct cs42l43_codec *priv)
352{
353 struct cs42l43 *cs42l43 = priv->core;
354
355 dev_dbg(priv->dev, "Stop button detect\n");
356
357 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
358 CS42L43_BUTTON_DETECT_MODE_MASK |
359 CS42L43_MIC_LVL_DET_DISABLE_MASK,
360 CS42L43_MIC_LVL_DET_DISABLE_MASK);
361
362 priv->button_detect_running = false;
363}
364
365#define CS42L43_BUTTON_COMB_MAX 512
366#define CS42L43_BUTTON_ROUT 2210
367
368void cs42l43_button_press_work(struct work_struct *work)
369{
370 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
371 button_press_work.work);
372 struct cs42l43 *cs42l43 = priv->core;
373 unsigned int buttons = 0;
374 unsigned int val = 0;
375 int i, ret;
376
377 ret = pm_runtime_resume_and_get(priv->dev);
378 if (ret) {
379 dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
380 return;
381 }
382
383 mutex_lock(&priv->jack_lock);
384
385 if (!priv->button_detect_running) {
386 dev_dbg(priv->dev, "Spurious button press IRQ\n");
387 goto error;
388 }
389
390 regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
391
392 /* Bail if jack removed, the button is irrelevant and likely invalid */
393 if (!cs42l43_jack_present(priv)) {
394 dev_dbg(priv->dev, "Button ignored due to removal\n");
395 goto error;
396 }
397
398 if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
399 dev_dbg(priv->dev, "Button ignored due to bias sense\n");
400 goto error;
401 }
402
403 val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
404 val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
405 if (val)
406 val = (CS42L43_BUTTON_ROUT << 20) / val;
407 else
408 val = UINT_MAX;
409
410 for (i = 0; i < CS42L43_N_BUTTONS; i++) {
411 if (val < priv->buttons[i]) {
412 buttons = SND_JACK_BTN_0 >> i;
413 dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val);
414 break;
415 }
416 }
417
418 if (!buttons)
419 dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
420
421 snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
422
423error:
424 mutex_unlock(&priv->jack_lock);
425
426 pm_runtime_mark_last_busy(priv->dev);
427 pm_runtime_put_autosuspend(priv->dev);
428}
429
430irqreturn_t cs42l43_button_press(int irq, void *data)
431{
432 struct cs42l43_codec *priv = data;
433
434 // Wait for 2 full cycles of comb filter to ensure good reading
435 queue_delayed_work(system_wq, &priv->button_press_work,
436 msecs_to_jiffies(20));
437
438 return IRQ_HANDLED;
439}
440
441void cs42l43_button_release_work(struct work_struct *work)
442{
443 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
444 button_release_work);
445 int ret;
446
447 ret = pm_runtime_resume_and_get(priv->dev);
448 if (ret) {
449 dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
450 return;
451 }
452
453 mutex_lock(&priv->jack_lock);
454
455 if (priv->button_detect_running) {
456 dev_dbg(priv->dev, "Button release IRQ\n");
457
458 snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
459 } else {
460 dev_dbg(priv->dev, "Spurious button release IRQ\n");
461 }
462
463 mutex_unlock(&priv->jack_lock);
464
465 pm_runtime_mark_last_busy(priv->dev);
466 pm_runtime_put_autosuspend(priv->dev);
467}
468
469irqreturn_t cs42l43_button_release(int irq, void *data)
470{
471 struct cs42l43_codec *priv = data;
472
473 queue_work(system_wq, &priv->button_release_work);
474
475 return IRQ_HANDLED;
476}
477
478void cs42l43_bias_sense_timeout(struct work_struct *work)
479{
480 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
481 bias_sense_timeout.work);
482 struct cs42l43 *cs42l43 = priv->core;
483 int ret;
484
485 ret = pm_runtime_resume_and_get(priv->dev);
486 if (ret) {
487 dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
488 return;
489 }
490
491 mutex_lock(&priv->jack_lock);
492
493 if (cs42l43_jack_present(priv) && priv->button_detect_running) {
494 dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
495
496 regmap_update_bits(cs42l43->regmap,
497 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
498 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
499 regmap_update_bits(cs42l43->regmap,
500 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
501 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
502 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
503 }
504
505 mutex_unlock(&priv->jack_lock);
506
507 pm_runtime_mark_last_busy(priv->dev);
508 pm_runtime_put_autosuspend(priv->dev);
509}
510
511static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
512{
513 struct cs42l43 *cs42l43 = priv->core;
514
515 dev_dbg(priv->dev, "Start load detect\n");
516
517 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
518
519 priv->load_detect_running = true;
520
521 if (priv->hp_ena && !priv->hp_ilimited) {
522 unsigned long time_left;
523
524 reinit_completion(&priv->hp_shutdown);
525
526 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
527 CS42L43_HP_EN_MASK, 0);
528
529 time_left = wait_for_completion_timeout(&priv->hp_shutdown,
530 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
531 if (!time_left)
532 dev_err(priv->dev, "Load detect HP power down timed out\n");
533 }
534
535 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
536 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
537 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
538 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
539 CS42L43_HSBIAS_MODE_MASK, 0);
540 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
541 CS42L43_ADPTPWR_MODE_MASK, 0x4 << CS42L43_ADPTPWR_MODE_SHIFT);
542 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
543 CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 0x6);
544 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
545 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 0);
546
547 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
548 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
549
550 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
551 CS42L43_HPLOAD_DET_EN_MASK,
552 CS42L43_HPLOAD_DET_EN_MASK);
553
554 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
555}
556
557static void cs42l43_stop_load_detect(struct cs42l43_codec *priv)
558{
559 struct cs42l43 *cs42l43 = priv->core;
560
561 dev_dbg(priv->dev, "Stop load detect\n");
562
563 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
564
565 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
566 CS42L43_HPLOAD_DET_EN_MASK, 0);
567 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
568 CS42L43_HS_CLAMP_DISABLE_MASK, 0);
569 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
570 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK,
571 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK);
572 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
573 CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK,
574 0x4 << CS42L43_HP_DIG_VOL_RAMP_SHIFT);
575 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
576 CS42L43_ADPTPWR_MODE_MASK, 0x7 << CS42L43_ADPTPWR_MODE_SHIFT);
577 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
578 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
579 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2,
580 CS42L43_HP_HPF_EN_MASK, CS42L43_HP_HPF_EN_MASK);
581
582 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
583 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK,
584 priv->adc_ena);
585
586 if (priv->hp_ena && !priv->hp_ilimited) {
587 unsigned long time_left;
588
589 reinit_completion(&priv->hp_startup);
590
591 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
592 CS42L43_HP_EN_MASK, priv->hp_ena);
593
594 time_left = wait_for_completion_timeout(&priv->hp_startup,
595 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
596 if (!time_left)
597 dev_err(priv->dev, "Load detect HP restore timed out\n");
598 }
599
600 priv->load_detect_running = false;
601
602 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
603}
604
605static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
606{
607 struct cs42l43 *cs42l43 = priv->core;
608 unsigned int val = 0;
609 unsigned long time_left;
610
611 reinit_completion(&priv->load_detect);
612
613 cs42l43_start_load_detect(priv);
614 time_left = wait_for_completion_timeout(&priv->load_detect,
615 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
616 cs42l43_stop_load_detect(priv);
617
618 if (!time_left)
619 return -ETIMEDOUT;
620
621 regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
622
623 dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
624
625 /* Bail if jack removed, the load is irrelevant and likely invalid */
626 if (!cs42l43_jack_present(priv))
627 return -ENODEV;
628
629 if (mic) {
630 cs42l43_start_hs_bias(priv, false);
631 cs42l43_start_button_detect(priv);
632
633 return CS42L43_JACK_HEADSET;
634 }
635
636 switch (val & CS42L43_AMP3_RES_DET_MASK) {
637 case 0x0: // low impedance
638 case 0x1: // high impedance
639 return CS42L43_JACK_HEADPHONE;
640 case 0x2: // lineout
641 case 0x3: // Open circuit
642 return CS42L43_JACK_LINEOUT;
643 default:
644 return -EINVAL;
645 }
646}
647
648static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
649{
650 struct cs42l43 *cs42l43 = priv->core;
651 int timeout_ms = ((2 * priv->detect_us) / USEC_PER_MSEC) + 200;
652 unsigned int type = 0xff;
653 unsigned long time_left;
654
655 reinit_completion(&priv->type_detect);
656
657 cs42l43_start_hs_bias(priv, true);
658 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
659 CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT);
660
661 time_left = wait_for_completion_timeout(&priv->type_detect,
662 msecs_to_jiffies(timeout_ms));
663
664 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
665 CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);
666 cs42l43_stop_hs_bias(priv);
667
668 if (!time_left)
669 return -ETIMEDOUT;
670
671 regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
672
673 dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
674
675 /* Bail if jack removed, the type is irrelevant and likely invalid */
676 if (!cs42l43_jack_present(priv))
677 return -ENODEV;
678
679 switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
680 case 0x0: // CTIA
681 case 0x1: // OMTP
682 return cs42l43_run_load_detect(priv, true);
683 case 0x2: // 3-pole
684 return cs42l43_run_load_detect(priv, false);
685 case 0x3: // Open-circuit
686 return CS42L43_JACK_EXTENSION;
687 default:
688 return -EINVAL;
689 }
690}
691
692static void cs42l43_clear_jack(struct cs42l43_codec *priv)
693{
694 struct cs42l43 *cs42l43 = priv->core;
695
696 cs42l43_stop_button_detect(priv);
697 cs42l43_stop_hs_bias(priv);
698
699 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
700 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
701 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
702 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
703 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
704 CS42L43_JACK_STEREO_CONFIG_MASK, 0);
705 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
706 CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
707 0x2 << CS42L43_HSDET_MODE_SHIFT);
708
709 snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
710}
711
712void cs42l43_tip_sense_work(struct work_struct *work)
713{
714 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
715 tip_sense_work.work);
716 struct cs42l43 *cs42l43 = priv->core;
717 unsigned int sts = 0;
718 unsigned int tip, ring;
719 int ret, report;
720
721 ret = pm_runtime_resume_and_get(priv->dev);
722 if (ret) {
723 dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
724 return;
725 }
726
727 mutex_lock(&priv->jack_lock);
728
729 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
730
731 dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
732
733 tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
734 ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
735
736 if (tip == CS42L43_JACK_PRESENT) {
737 if (cs42l43->sdw && !priv->jack_present) {
738 priv->jack_present = true;
739 pm_runtime_get(priv->dev);
740 }
741
742 if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
743 report = CS42L43_JACK_OPTICAL;
744 } else {
745 report = cs42l43_run_type_detect(priv);
746 if (report < 0) {
747 dev_err(priv->dev, "Jack detect failed: %d\n", report);
748 goto error;
749 }
750 }
751
752 snd_soc_jack_report(priv->jack_hp, report, report);
753 } else {
754 priv->jack_override = 0;
755
756 cs42l43_clear_jack(priv);
757
758 if (cs42l43->sdw && priv->jack_present) {
759 pm_runtime_put(priv->dev);
760 priv->jack_present = false;
761 }
762 }
763
764error:
765 mutex_unlock(&priv->jack_lock);
766
767 pm_runtime_mark_last_busy(priv->dev);
768 pm_runtime_put_autosuspend(priv->dev);
769}
770
771irqreturn_t cs42l43_tip_sense(int irq, void *data)
772{
773 struct cs42l43_codec *priv = data;
774
775 cancel_delayed_work(&priv->bias_sense_timeout);
776 cancel_delayed_work(&priv->tip_sense_work);
777 cancel_delayed_work(&priv->button_press_work);
778 cancel_work(&priv->button_release_work);
779
780 queue_delayed_work(system_long_wq, &priv->tip_sense_work,
781 msecs_to_jiffies(priv->tip_debounce_ms));
782
783 return IRQ_HANDLED;
784}
785
786enum cs42l43_raw_jack {
787 CS42L43_JACK_RAW_CTIA = 0,
788 CS42L43_JACK_RAW_OMTP,
789 CS42L43_JACK_RAW_HEADPHONE,
790 CS42L43_JACK_RAW_LINE_OUT,
791 CS42L43_JACK_RAW_LINE_IN,
792 CS42L43_JACK_RAW_MICROPHONE,
793 CS42L43_JACK_RAW_OPTICAL,
794};
795
796#define CS42L43_JACK_3_POLE_SWITCHES ((0x2 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | \
797 CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | \
798 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | \
799 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | \
800 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | \
801 CS42L43_HSGND_HS3_SEL_MASK | \
802 CS42L43_HSGND_HS4_SEL_MASK)
803
804static const struct cs42l43_jack_override_mode {
805 unsigned int hsdet_mode;
806 unsigned int mic_ctrl;
807 unsigned int clamp_ctrl;
808 int report;
809} cs42l43_jack_override_modes[] = {
810 [CS42L43_JACK_RAW_CTIA] = {
811 .hsdet_mode = CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
812 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
813 CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
814 CS42L43_HSGND_HS3_SEL_MASK,
815 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
816 .report = CS42L43_JACK_HEADSET,
817 },
818 [CS42L43_JACK_RAW_OMTP] = {
819 .hsdet_mode = (0x1 << CS42L43_HSDET_MANUAL_MODE_SHIFT) |
820 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
821 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
822 CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
823 CS42L43_HSGND_HS4_SEL_MASK,
824 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
825 .report = CS42L43_JACK_HEADSET,
826 },
827 [CS42L43_JACK_RAW_HEADPHONE] = {
828 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
829 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
830 .report = CS42L43_JACK_HEADPHONE,
831 },
832 [CS42L43_JACK_RAW_LINE_OUT] = {
833 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
834 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
835 .report = CS42L43_JACK_LINEOUT,
836 },
837 [CS42L43_JACK_RAW_LINE_IN] = {
838 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
839 .mic_ctrl = 0x2 << CS42L43_JACK_STEREO_CONFIG_SHIFT,
840 .report = CS42L43_JACK_LINEIN,
841 },
842 [CS42L43_JACK_RAW_MICROPHONE] = {
843 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
844 .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
845 CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
846 .report = CS42L43_JACK_LINEIN,
847 },
848 [CS42L43_JACK_RAW_OPTICAL] = {
849 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
850 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
851 .report = CS42L43_JACK_OPTICAL,
852 },
853};
854
855static const char * const cs42l43_jack_text[] = {
856 "None", "CTIA", "OMTP", "Headphone", "Line-Out",
857 "Line-In", "Microphone", "Optical",
858};
859
860static_assert(ARRAY_SIZE(cs42l43_jack_override_modes) ==
861 ARRAY_SIZE(cs42l43_jack_text) - 1);
862
863SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text);
864
865int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
866{
867 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
868 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
869
870 mutex_lock(&priv->jack_lock);
871 ucontrol->value.integer.value[0] = priv->jack_override;
872 mutex_unlock(&priv->jack_lock);
873
874 return 0;
875}
876
877int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
878{
879 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
880 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
881 struct cs42l43 *cs42l43 = priv->core;
882 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
883 unsigned int override = ucontrol->value.integer.value[0];
884
885 if (override >= e->items)
886 return -EINVAL;
887
888 mutex_lock(&priv->jack_lock);
889
890 if (!cs42l43_jack_present(priv)) {
891 mutex_unlock(&priv->jack_lock);
892 return -EBUSY;
893 }
894
895 if (override == priv->jack_override) {
896 mutex_unlock(&priv->jack_lock);
897 return 0;
898 }
899
900 priv->jack_override = override;
901
902 cs42l43_clear_jack(priv);
903
904 if (!override) {
905 queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
906 } else {
907 override--;
908
909 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
910 CS42L43_HSDET_MODE_MASK |
911 CS42L43_HSDET_MANUAL_MODE_MASK |
912 CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
913 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
914 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
915 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
916 CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
917 CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
918 CS42L43_HSGND_HS3_SEL_MASK |
919 CS42L43_HSGND_HS4_SEL_MASK,
920 cs42l43_jack_override_modes[override].hsdet_mode);
921 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
922 CS42L43_HS2_BIAS_EN_MASK | CS42L43_HS1_BIAS_EN_MASK |
923 CS42L43_JACK_STEREO_CONFIG_MASK,
924 cs42l43_jack_override_modes[override].mic_ctrl);
925 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
926 CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
927 cs42l43_jack_override_modes[override].clamp_ctrl);
928
929 switch (override) {
930 case CS42L43_JACK_RAW_CTIA:
931 case CS42L43_JACK_RAW_OMTP:
932 cs42l43_start_hs_bias(priv, false);
933 cs42l43_start_button_detect(priv);
934 break;
935 case CS42L43_JACK_RAW_LINE_IN:
936 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
937 CS42L43_PGA_WIDESWING_MODE_EN_MASK,
938 CS42L43_PGA_WIDESWING_MODE_EN_MASK);
939 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
940 CS42L43_PGA_WIDESWING_MODE_EN_MASK,
941 CS42L43_PGA_WIDESWING_MODE_EN_MASK);
942 break;
943 case CS42L43_JACK_RAW_MICROPHONE:
944 cs42l43_start_hs_bias(priv, false);
945 break;
946 default:
947 break;
948 }
949
950 snd_soc_jack_report(priv->jack_hp,
951 cs42l43_jack_override_modes[override].report,
952 cs42l43_jack_override_modes[override].report);
953 }
954
955 mutex_unlock(&priv->jack_lock);
956
957 return 1;
958}
1// SPDX-License-Identifier: GPL-2.0
2//
3// CS42L43 CODEC driver jack handling
4//
5// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7
8#include <linux/build_bug.h>
9#include <linux/delay.h>
10#include <linux/errno.h>
11#include <linux/irq.h>
12#include <linux/jiffies.h>
13#include <linux/mfd/cs42l43.h>
14#include <linux/mfd/cs42l43-regs.h>
15#include <linux/pm_runtime.h>
16#include <linux/property.h>
17#include <sound/control.h>
18#include <sound/jack.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc-component.h>
22#include <sound/soc.h>
23
24#include "cs42l43.h"
25
26static const unsigned int cs42l43_accdet_us[] = {
27 20, 100, 1000, 10000, 50000, 75000, 100000, 200000
28};
29
30static const unsigned int cs42l43_accdet_db_ms[] = {
31 0, 125, 250, 500, 750, 1000, 1250, 1500
32};
33
34static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 };
35
36static const unsigned int cs42l43_accdet_bias_sense[] = {
37 14, 24, 43, 52, 61, 71, 90, 99, 0,
38};
39
40static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const prop,
41 unsigned int defval, unsigned int *val,
42 const unsigned int *values, const int nvalues)
43{
44 struct cs42l43 *cs42l43 = priv->core;
45 int i, ret;
46
47 ret = device_property_read_u32(cs42l43->dev, prop, &defval);
48 if (ret != -EINVAL && ret < 0) {
49 dev_err(priv->dev, "Property %s malformed: %d\n", prop, ret);
50 return ret;
51 }
52
53 if (val)
54 *val = defval;
55
56 for (i = 0; i < nvalues; i++)
57 if (defval == values[i])
58 return i;
59
60 dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval);
61 return -EINVAL;
62}
63
64int cs42l43_set_jack(struct snd_soc_component *component,
65 struct snd_soc_jack *jack, void *d)
66{
67 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
68 struct cs42l43 *cs42l43 = priv->core;
69 /* This tip sense invert is always set, HW wants an inverted signal */
70 unsigned int tip_deb = CS42L43_TIPSENSE_INV_MASK;
71 unsigned int hs2 = 0x2 << CS42L43_HSDET_MODE_SHIFT;
72 unsigned int autocontrol = 0, pdncntl = 0;
73 int ret;
74
75 dev_dbg(priv->dev, "Configure accessory detect\n");
76
77 ret = pm_runtime_resume_and_get(priv->dev);
78 if (ret) {
79 dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
80 return ret;
81 }
82
83 mutex_lock(&priv->jack_lock);
84
85 priv->jack_hp = jack;
86
87 if (!jack)
88 goto done;
89
90 ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
91 if (ret != -EINVAL) {
92 if (ret < 0) {
93 dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
94 ret);
95 goto error;
96 }
97
98 if (ret > CS42L43_N_BUTTONS) {
99 ret = -EINVAL;
100 dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
101 goto error;
102 }
103
104 device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
105 priv->buttons, ret);
106 } else {
107 priv->buttons[0] = 70;
108 priv->buttons[1] = 185;
109 priv->buttons[2] = 355;
110 priv->buttons[3] = 735;
111 }
112
113 ret = cs42l43_find_index(priv, "cirrus,detect-us", 1000, &priv->detect_us,
114 cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us));
115 if (ret < 0)
116 goto error;
117
118 hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT;
119
120 priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low");
121
122 ret = cs42l43_find_index(priv, "cirrus,bias-ramp-ms", 170,
123 &priv->bias_ramp_ms, cs42l43_accdet_ramp_ms,
124 ARRAY_SIZE(cs42l43_accdet_ramp_ms));
125 if (ret < 0)
126 goto error;
127
128 hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT;
129
130 ret = cs42l43_find_index(priv, "cirrus,bias-sense-microamp", 14,
131 &priv->bias_sense_ua, cs42l43_accdet_bias_sense,
132 ARRAY_SIZE(cs42l43_accdet_bias_sense));
133 if (ret < 0)
134 goto error;
135
136 if (priv->bias_sense_ua)
137 autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT;
138
139 if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute"))
140 autocontrol |= CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK;
141
142 ret = device_property_read_u32(cs42l43->dev, "cirrus,tip-debounce-ms",
143 &priv->tip_debounce_ms);
144 if (ret < 0 && ret != -EINVAL) {
145 dev_err(priv->dev, "Property cirrus,tip-debounce-ms malformed: %d\n", ret);
146 goto error;
147 }
148
149 /* This tip sense invert is set normally, as TIPSENSE_INV already inverted */
150 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-invert"))
151 autocontrol |= 0x1 << CS42L43_JACKDET_INV_SHIFT;
152
153 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup"))
154 autocontrol |= 0x1 << CS42L43_JACKDET_MODE_SHIFT;
155 else
156 autocontrol |= 0x3 << CS42L43_JACKDET_MODE_SHIFT;
157
158 ret = cs42l43_find_index(priv, "cirrus,tip-fall-db-ms", 500,
159 NULL, cs42l43_accdet_db_ms,
160 ARRAY_SIZE(cs42l43_accdet_db_ms));
161 if (ret < 0)
162 goto error;
163
164 tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT;
165
166 ret = cs42l43_find_index(priv, "cirrus,tip-rise-db-ms", 500,
167 NULL, cs42l43_accdet_db_ms,
168 ARRAY_SIZE(cs42l43_accdet_db_ms));
169 if (ret < 0)
170 goto error;
171
172 tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT;
173
174 if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) {
175 unsigned int ring_deb = 0;
176
177 priv->use_ring_sense = true;
178
179 /* HW wants an inverted signal, so invert the invert */
180 if (!device_property_read_bool(cs42l43->dev, "cirrus,ring-invert"))
181 ring_deb |= CS42L43_RINGSENSE_INV_MASK;
182
183 if (!device_property_read_bool(cs42l43->dev,
184 "cirrus,ring-disable-pullup"))
185 ring_deb |= CS42L43_RINGSENSE_PULLUP_PDNB_MASK;
186
187 ret = cs42l43_find_index(priv, "cirrus,ring-fall-db-ms", 500,
188 NULL, cs42l43_accdet_db_ms,
189 ARRAY_SIZE(cs42l43_accdet_db_ms));
190 if (ret < 0)
191 goto error;
192
193 ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT;
194
195 ret = cs42l43_find_index(priv, "cirrus,ring-rise-db-ms", 500,
196 NULL, cs42l43_accdet_db_ms,
197 ARRAY_SIZE(cs42l43_accdet_db_ms));
198 if (ret < 0)
199 goto error;
200
201 ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT;
202 pdncntl |= CS42L43_RING_SENSE_EN_MASK;
203
204 regmap_update_bits(cs42l43->regmap, CS42L43_RINGSENSE_DEB_CTRL,
205 CS42L43_RINGSENSE_INV_MASK |
206 CS42L43_RINGSENSE_PULLUP_PDNB_MASK |
207 CS42L43_RINGSENSE_FALLING_DB_TIME_MASK |
208 CS42L43_RINGSENSE_RISING_DB_TIME_MASK,
209 ring_deb);
210 }
211
212 regmap_update_bits(cs42l43->regmap, CS42L43_TIPSENSE_DEB_CTRL,
213 CS42L43_TIPSENSE_INV_MASK |
214 CS42L43_TIPSENSE_FALLING_DB_TIME_MASK |
215 CS42L43_TIPSENSE_RISING_DB_TIME_MASK, tip_deb);
216 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
217 CS42L43_HSBIAS_RAMP_MASK | CS42L43_HSDET_MODE_MASK |
218 CS42L43_AUTO_HSDET_TIME_MASK, hs2);
219
220done:
221 ret = 0;
222
223 regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
224 CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK |
225 CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol);
226 regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
227 CS42L43_RING_SENSE_EN_MASK, pdncntl);
228
229 dev_dbg(priv->dev, "Successfully configured accessory detect\n");
230
231error:
232 mutex_unlock(&priv->jack_lock);
233
234 pm_runtime_mark_last_busy(priv->dev);
235 pm_runtime_put_autosuspend(priv->dev);
236
237 return ret;
238}
239
240static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
241{
242 struct cs42l43 *cs42l43 = priv->core;
243 unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT;
244
245 dev_dbg(priv->dev, "Start headset bias\n");
246
247 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
248 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
249
250 if (!type_detect) {
251 if (priv->bias_low)
252 val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
253
254 if (priv->bias_sense_ua)
255 regmap_update_bits(cs42l43->regmap,
256 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
257 CS42L43_HSBIAS_SENSE_EN_MASK |
258 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
259 CS42L43_HSBIAS_SENSE_EN_MASK |
260 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
261 }
262
263 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
264 CS42L43_HSBIAS_MODE_MASK, val);
265
266 msleep(priv->bias_ramp_ms);
267}
268
269static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv)
270{
271 struct cs42l43 *cs42l43 = priv->core;
272
273 dev_dbg(priv->dev, "Stop headset bias\n");
274
275 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
276 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
277
278 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
279 CS42L43_HS_CLAMP_DISABLE_MASK, 0);
280
281 if (priv->bias_sense_ua) {
282 regmap_update_bits(cs42l43->regmap,
283 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
284 CS42L43_HSBIAS_SENSE_EN_MASK |
285 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
286 }
287}
288
289irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
290{
291 struct cs42l43_codec *priv = data;
292
293 queue_delayed_work(system_wq, &priv->bias_sense_timeout,
294 msecs_to_jiffies(1000));
295
296 return IRQ_HANDLED;
297}
298
299#define CS42L43_JACK_PRESENT 0x3
300#define CS42L43_JACK_ABSENT 0x0
301
302#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
303#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
304#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
305#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
306#define CS42L43_JACK_LINEIN (SND_JACK_MECHANICAL | SND_JACK_LINEIN)
307#define CS42L43_JACK_EXTENSION (SND_JACK_MECHANICAL)
308#define CS42L43_JACK_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | \
309 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5)
310
311static inline bool cs42l43_jack_present(struct cs42l43_codec *priv)
312{
313 struct cs42l43 *cs42l43 = priv->core;
314 unsigned int sts = 0;
315
316 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
317
318 sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
319
320 return sts == CS42L43_JACK_PRESENT;
321}
322
323static void cs42l43_start_button_detect(struct cs42l43_codec *priv)
324{
325 struct cs42l43 *cs42l43 = priv->core;
326 unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
327
328 dev_dbg(priv->dev, "Start button detect\n");
329
330 priv->button_detect_running = true;
331
332 if (priv->bias_low)
333 val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
334
335 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
336 CS42L43_BUTTON_DETECT_MODE_MASK |
337 CS42L43_MIC_LVL_DET_DISABLE_MASK, val);
338}
339
340static void cs42l43_stop_button_detect(struct cs42l43_codec *priv)
341{
342 struct cs42l43 *cs42l43 = priv->core;
343
344 dev_dbg(priv->dev, "Stop button detect\n");
345
346 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
347 CS42L43_BUTTON_DETECT_MODE_MASK |
348 CS42L43_MIC_LVL_DET_DISABLE_MASK,
349 CS42L43_MIC_LVL_DET_DISABLE_MASK);
350
351 priv->button_detect_running = false;
352}
353
354#define CS42L43_BUTTON_COMB_MAX 512
355#define CS42L43_BUTTON_ROUT 2210
356
357void cs42l43_button_press_work(struct work_struct *work)
358{
359 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
360 button_press_work.work);
361 struct cs42l43 *cs42l43 = priv->core;
362 unsigned int buttons = 0;
363 unsigned int val = 0;
364 int i, ret;
365
366 ret = pm_runtime_resume_and_get(priv->dev);
367 if (ret) {
368 dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
369 return;
370 }
371
372 mutex_lock(&priv->jack_lock);
373
374 if (!priv->button_detect_running) {
375 dev_dbg(priv->dev, "Spurious button press IRQ\n");
376 goto error;
377 }
378
379 regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
380
381 /* Bail if jack removed, the button is irrelevant and likely invalid */
382 if (!cs42l43_jack_present(priv)) {
383 dev_dbg(priv->dev, "Button ignored due to removal\n");
384 goto error;
385 }
386
387 if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
388 dev_dbg(priv->dev, "Button ignored due to bias sense\n");
389 goto error;
390 }
391
392 val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
393 val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
394 if (val)
395 val = (CS42L43_BUTTON_ROUT << 20) / val;
396 else
397 val = UINT_MAX;
398
399 for (i = 0; i < CS42L43_N_BUTTONS; i++) {
400 if (val < priv->buttons[i]) {
401 buttons = SND_JACK_BTN_0 >> i;
402 dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val);
403 break;
404 }
405 }
406
407 if (!buttons)
408 dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
409
410 snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
411
412error:
413 mutex_unlock(&priv->jack_lock);
414
415 pm_runtime_mark_last_busy(priv->dev);
416 pm_runtime_put_autosuspend(priv->dev);
417}
418
419irqreturn_t cs42l43_button_press(int irq, void *data)
420{
421 struct cs42l43_codec *priv = data;
422
423 // Wait for 2 full cycles of comb filter to ensure good reading
424 queue_delayed_work(system_wq, &priv->button_press_work,
425 msecs_to_jiffies(10));
426
427 return IRQ_HANDLED;
428}
429
430void cs42l43_button_release_work(struct work_struct *work)
431{
432 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
433 button_release_work);
434 int ret;
435
436 ret = pm_runtime_resume_and_get(priv->dev);
437 if (ret) {
438 dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
439 return;
440 }
441
442 mutex_lock(&priv->jack_lock);
443
444 if (priv->button_detect_running) {
445 dev_dbg(priv->dev, "Button release IRQ\n");
446
447 snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
448 } else {
449 dev_dbg(priv->dev, "Spurious button release IRQ\n");
450 }
451
452 mutex_unlock(&priv->jack_lock);
453
454 pm_runtime_mark_last_busy(priv->dev);
455 pm_runtime_put_autosuspend(priv->dev);
456}
457
458irqreturn_t cs42l43_button_release(int irq, void *data)
459{
460 struct cs42l43_codec *priv = data;
461
462 queue_work(system_wq, &priv->button_release_work);
463
464 return IRQ_HANDLED;
465}
466
467void cs42l43_bias_sense_timeout(struct work_struct *work)
468{
469 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
470 bias_sense_timeout.work);
471 struct cs42l43 *cs42l43 = priv->core;
472 int ret;
473
474 ret = pm_runtime_resume_and_get(priv->dev);
475 if (ret) {
476 dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
477 return;
478 }
479
480 mutex_lock(&priv->jack_lock);
481
482 if (cs42l43_jack_present(priv) && priv->button_detect_running) {
483 dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
484
485 regmap_update_bits(cs42l43->regmap,
486 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
487 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
488 regmap_update_bits(cs42l43->regmap,
489 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
490 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
491 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
492 }
493
494 mutex_unlock(&priv->jack_lock);
495
496 pm_runtime_mark_last_busy(priv->dev);
497 pm_runtime_put_autosuspend(priv->dev);
498}
499
500static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
501{
502 struct cs42l43 *cs42l43 = priv->core;
503
504 dev_dbg(priv->dev, "Start load detect\n");
505
506 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
507
508 priv->load_detect_running = true;
509
510 if (priv->hp_ena && !priv->hp_ilimited) {
511 unsigned long time_left;
512
513 reinit_completion(&priv->hp_shutdown);
514
515 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
516 CS42L43_HP_EN_MASK, 0);
517
518 time_left = wait_for_completion_timeout(&priv->hp_shutdown,
519 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
520 if (!time_left)
521 dev_err(priv->dev, "Load detect HP power down timed out\n");
522 }
523
524 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
525 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
526 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
527 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
528 CS42L43_HSBIAS_MODE_MASK, 0);
529 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
530 CS42L43_ADPTPWR_MODE_MASK, 0x4 << CS42L43_ADPTPWR_MODE_SHIFT);
531 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
532 CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 0x6);
533 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
534 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 0);
535
536 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
537 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
538
539 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
540 CS42L43_HPLOAD_DET_EN_MASK,
541 CS42L43_HPLOAD_DET_EN_MASK);
542
543 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
544}
545
546static void cs42l43_stop_load_detect(struct cs42l43_codec *priv)
547{
548 struct cs42l43 *cs42l43 = priv->core;
549
550 dev_dbg(priv->dev, "Stop load detect\n");
551
552 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
553
554 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
555 CS42L43_HPLOAD_DET_EN_MASK, 0);
556 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
557 CS42L43_HS_CLAMP_DISABLE_MASK, 0);
558 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
559 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK,
560 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK);
561 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
562 CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK,
563 0x4 << CS42L43_HP_DIG_VOL_RAMP_SHIFT);
564 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
565 CS42L43_ADPTPWR_MODE_MASK, 0x7 << CS42L43_ADPTPWR_MODE_SHIFT);
566 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
567 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
568 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2,
569 CS42L43_HP_HPF_EN_MASK, CS42L43_HP_HPF_EN_MASK);
570
571 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
572 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK,
573 priv->adc_ena);
574
575 if (priv->hp_ena && !priv->hp_ilimited) {
576 unsigned long time_left;
577
578 reinit_completion(&priv->hp_startup);
579
580 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
581 CS42L43_HP_EN_MASK, priv->hp_ena);
582
583 time_left = wait_for_completion_timeout(&priv->hp_startup,
584 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
585 if (!time_left)
586 dev_err(priv->dev, "Load detect HP restore timed out\n");
587 }
588
589 priv->load_detect_running = false;
590
591 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
592}
593
594static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
595{
596 struct cs42l43 *cs42l43 = priv->core;
597 unsigned int val = 0;
598 unsigned long time_left;
599
600 reinit_completion(&priv->load_detect);
601
602 cs42l43_start_load_detect(priv);
603 time_left = wait_for_completion_timeout(&priv->load_detect,
604 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
605 cs42l43_stop_load_detect(priv);
606
607 if (!time_left)
608 return -ETIMEDOUT;
609
610 regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
611
612 dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
613
614 /* Bail if jack removed, the load is irrelevant and likely invalid */
615 if (!cs42l43_jack_present(priv))
616 return -ENODEV;
617
618 if (mic) {
619 cs42l43_start_hs_bias(priv, false);
620 cs42l43_start_button_detect(priv);
621
622 return CS42L43_JACK_HEADSET;
623 }
624
625 switch (val & CS42L43_AMP3_RES_DET_MASK) {
626 case 0x0: // low impedance
627 case 0x1: // high impedance
628 return CS42L43_JACK_HEADPHONE;
629 case 0x2: // lineout
630 case 0x3: // Open circuit
631 return CS42L43_JACK_LINEOUT;
632 default:
633 return -EINVAL;
634 }
635}
636
637static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
638{
639 struct cs42l43 *cs42l43 = priv->core;
640 int timeout_ms = ((2 * priv->detect_us) / 1000) + 200;
641 unsigned int type = 0xff;
642 unsigned long time_left;
643
644 reinit_completion(&priv->type_detect);
645
646 cs42l43_start_hs_bias(priv, true);
647 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
648 CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT);
649
650 time_left = wait_for_completion_timeout(&priv->type_detect,
651 msecs_to_jiffies(timeout_ms));
652
653 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
654 CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);
655 cs42l43_stop_hs_bias(priv);
656
657 if (!time_left)
658 return -ETIMEDOUT;
659
660 regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
661
662 dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
663
664 /* Bail if jack removed, the type is irrelevant and likely invalid */
665 if (!cs42l43_jack_present(priv))
666 return -ENODEV;
667
668 switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
669 case 0x0: // CTIA
670 case 0x1: // OMTP
671 return cs42l43_run_load_detect(priv, true);
672 case 0x2: // 3-pole
673 return cs42l43_run_load_detect(priv, false);
674 case 0x3: // Open-circuit
675 return CS42L43_JACK_EXTENSION;
676 default:
677 return -EINVAL;
678 }
679}
680
681static void cs42l43_clear_jack(struct cs42l43_codec *priv)
682{
683 struct cs42l43 *cs42l43 = priv->core;
684
685 cs42l43_stop_button_detect(priv);
686 cs42l43_stop_hs_bias(priv);
687
688 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
689 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
690 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
691 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
692 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
693 CS42L43_JACK_STEREO_CONFIG_MASK, 0);
694 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
695 CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
696 0x2 << CS42L43_HSDET_MODE_SHIFT);
697
698 snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
699}
700
701void cs42l43_tip_sense_work(struct work_struct *work)
702{
703 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
704 tip_sense_work.work);
705 struct cs42l43 *cs42l43 = priv->core;
706 unsigned int sts = 0;
707 unsigned int tip, ring;
708 int ret, report;
709
710 ret = pm_runtime_resume_and_get(priv->dev);
711 if (ret) {
712 dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
713 return;
714 }
715
716 mutex_lock(&priv->jack_lock);
717
718 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
719
720 dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
721
722 tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
723 ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
724
725 if (tip == CS42L43_JACK_PRESENT) {
726 if (cs42l43->sdw && !priv->jack_present) {
727 priv->jack_present = true;
728 pm_runtime_get(priv->dev);
729 }
730
731 if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
732 report = CS42L43_JACK_OPTICAL;
733 } else {
734 report = cs42l43_run_type_detect(priv);
735 if (report < 0) {
736 dev_err(priv->dev, "Jack detect failed: %d\n", report);
737 goto error;
738 }
739 }
740
741 snd_soc_jack_report(priv->jack_hp, report, report);
742 } else {
743 priv->jack_override = 0;
744
745 cs42l43_clear_jack(priv);
746
747 if (cs42l43->sdw && priv->jack_present) {
748 pm_runtime_put(priv->dev);
749 priv->jack_present = false;
750 }
751 }
752
753error:
754 mutex_unlock(&priv->jack_lock);
755
756 pm_runtime_mark_last_busy(priv->dev);
757 pm_runtime_put_autosuspend(priv->dev);
758}
759
760irqreturn_t cs42l43_tip_sense(int irq, void *data)
761{
762 struct cs42l43_codec *priv = data;
763
764 cancel_delayed_work(&priv->bias_sense_timeout);
765 cancel_delayed_work(&priv->tip_sense_work);
766 cancel_delayed_work(&priv->button_press_work);
767 cancel_work(&priv->button_release_work);
768
769 queue_delayed_work(system_long_wq, &priv->tip_sense_work,
770 msecs_to_jiffies(priv->tip_debounce_ms));
771
772 return IRQ_HANDLED;
773}
774
775enum cs42l43_raw_jack {
776 CS42L43_JACK_RAW_CTIA = 0,
777 CS42L43_JACK_RAW_OMTP,
778 CS42L43_JACK_RAW_HEADPHONE,
779 CS42L43_JACK_RAW_LINE_OUT,
780 CS42L43_JACK_RAW_LINE_IN,
781 CS42L43_JACK_RAW_MICROPHONE,
782 CS42L43_JACK_RAW_OPTICAL,
783};
784
785#define CS42L43_JACK_3_POLE_SWITCHES ((0x2 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | \
786 CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | \
787 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | \
788 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | \
789 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | \
790 CS42L43_HSGND_HS3_SEL_MASK | \
791 CS42L43_HSGND_HS4_SEL_MASK)
792
793static const struct cs42l43_jack_override_mode {
794 unsigned int hsdet_mode;
795 unsigned int mic_ctrl;
796 unsigned int clamp_ctrl;
797 int report;
798} cs42l43_jack_override_modes[] = {
799 [CS42L43_JACK_RAW_CTIA] = {
800 .hsdet_mode = CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
801 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
802 CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
803 CS42L43_HSGND_HS3_SEL_MASK,
804 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
805 .report = CS42L43_JACK_HEADSET,
806 },
807 [CS42L43_JACK_RAW_OMTP] = {
808 .hsdet_mode = (0x1 << CS42L43_HSDET_MANUAL_MODE_SHIFT) |
809 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
810 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
811 CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
812 CS42L43_HSGND_HS4_SEL_MASK,
813 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
814 .report = CS42L43_JACK_HEADSET,
815 },
816 [CS42L43_JACK_RAW_HEADPHONE] = {
817 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
818 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
819 .report = CS42L43_JACK_HEADPHONE,
820 },
821 [CS42L43_JACK_RAW_LINE_OUT] = {
822 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
823 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
824 .report = CS42L43_JACK_LINEOUT,
825 },
826 [CS42L43_JACK_RAW_LINE_IN] = {
827 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
828 .mic_ctrl = 0x2 << CS42L43_JACK_STEREO_CONFIG_SHIFT,
829 .report = CS42L43_JACK_LINEIN,
830 },
831 [CS42L43_JACK_RAW_MICROPHONE] = {
832 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
833 .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
834 CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
835 .report = CS42L43_JACK_LINEIN,
836 },
837 [CS42L43_JACK_RAW_OPTICAL] = {
838 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
839 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
840 .report = CS42L43_JACK_OPTICAL,
841 },
842};
843
844static const char * const cs42l43_jack_text[] = {
845 "None", "CTIA", "OMTP", "Headphone", "Line-Out",
846 "Line-In", "Microphone", "Optical",
847};
848
849SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text);
850
851int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
852{
853 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
854 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
855
856 mutex_lock(&priv->jack_lock);
857 ucontrol->value.integer.value[0] = priv->jack_override;
858 mutex_unlock(&priv->jack_lock);
859
860 return 0;
861}
862
863int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
864{
865 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
866 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
867 struct cs42l43 *cs42l43 = priv->core;
868 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
869 unsigned int override = ucontrol->value.integer.value[0];
870
871 BUILD_BUG_ON(ARRAY_SIZE(cs42l43_jack_override_modes) !=
872 ARRAY_SIZE(cs42l43_jack_text) - 1);
873
874 if (override >= e->items)
875 return -EINVAL;
876
877 mutex_lock(&priv->jack_lock);
878
879 if (!cs42l43_jack_present(priv)) {
880 mutex_unlock(&priv->jack_lock);
881 return -EBUSY;
882 }
883
884 if (override == priv->jack_override) {
885 mutex_unlock(&priv->jack_lock);
886 return 0;
887 }
888
889 priv->jack_override = override;
890
891 cs42l43_clear_jack(priv);
892
893 if (!override) {
894 queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
895 } else {
896 override--;
897
898 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
899 CS42L43_HSDET_MODE_MASK |
900 CS42L43_HSDET_MANUAL_MODE_MASK |
901 CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
902 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
903 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
904 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
905 CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
906 CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
907 CS42L43_HSGND_HS3_SEL_MASK |
908 CS42L43_HSGND_HS4_SEL_MASK,
909 cs42l43_jack_override_modes[override].hsdet_mode);
910 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
911 CS42L43_HS2_BIAS_EN_MASK | CS42L43_HS1_BIAS_EN_MASK |
912 CS42L43_JACK_STEREO_CONFIG_MASK,
913 cs42l43_jack_override_modes[override].mic_ctrl);
914 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
915 CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
916 cs42l43_jack_override_modes[override].clamp_ctrl);
917
918 switch (override) {
919 case CS42L43_JACK_RAW_CTIA:
920 case CS42L43_JACK_RAW_OMTP:
921 cs42l43_start_hs_bias(priv, false);
922 cs42l43_start_button_detect(priv);
923 break;
924 case CS42L43_JACK_RAW_LINE_IN:
925 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
926 CS42L43_PGA_WIDESWING_MODE_EN_MASK,
927 CS42L43_PGA_WIDESWING_MODE_EN_MASK);
928 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
929 CS42L43_PGA_WIDESWING_MODE_EN_MASK,
930 CS42L43_PGA_WIDESWING_MODE_EN_MASK);
931 break;
932 case CS42L43_JACK_RAW_MICROPHONE:
933 cs42l43_start_hs_bias(priv, false);
934 break;
935 default:
936 break;
937 }
938
939 snd_soc_jack_report(priv->jack_hp,
940 cs42l43_jack_override_modes[override].report,
941 cs42l43_jack_override_modes[override].report);
942 }
943
944 mutex_unlock(&priv->jack_lock);
945
946 return 1;
947}