1 // SPDX-License-Identifier: GPL-2.0
3 // CS42L43 CODEC driver jack handling
5 // Copyright (C) 2022-2023 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
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>
26 static const unsigned int cs42l43_accdet_us[] = {
27 20, 100, 1000, 10000, 50000, 75000, 100000, 200000
30 static const unsigned int cs42l43_accdet_db_ms[] = {
31 0, 125, 250, 500, 750, 1000, 1250, 1500
34 static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 };
36 static const unsigned int cs42l43_accdet_bias_sense[] = {
37 14, 24, 43, 52, 61, 71, 90, 99, 0,
40 static 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)
44 struct cs42l43 *cs42l43 = priv->core;
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);
56 for (i = 0; i < nvalues; i++)
57 if (defval == values[i])
60 dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval);
64 int cs42l43_set_jack(struct snd_soc_component *component,
65 struct snd_soc_jack *jack, void *d)
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;
75 dev_dbg(priv->dev, "Configure accessory detect\n");
77 ret = pm_runtime_resume_and_get(priv->dev);
79 dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
83 mutex_lock(&priv->jack_lock);
90 ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
93 dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
98 if (ret > CS42L43_N_BUTTONS) {
100 dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
104 device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
107 priv->buttons[0] = 70;
108 priv->buttons[1] = 185;
109 priv->buttons[2] = 355;
110 priv->buttons[3] = 735;
113 ret = cs42l43_find_index(priv, "cirrus,detect-us", 1000, &priv->detect_us,
114 cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us));
118 hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT;
120 priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low");
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));
128 hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT;
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));
136 if (priv->bias_sense_ua)
137 autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT;
139 if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute"))
140 autocontrol |= CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK;
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);
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;
153 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup"))
154 autocontrol |= 0x1 << CS42L43_JACKDET_MODE_SHIFT;
156 autocontrol |= 0x3 << CS42L43_JACKDET_MODE_SHIFT;
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));
164 tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT;
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));
172 tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT;
174 if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) {
175 unsigned int ring_deb = 0;
177 priv->use_ring_sense = true;
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;
183 if (!device_property_read_bool(cs42l43->dev,
184 "cirrus,ring-disable-pullup"))
185 ring_deb |= CS42L43_RINGSENSE_PULLUP_PDNB_MASK;
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));
193 ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT;
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));
201 ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT;
202 pdncntl |= CS42L43_RING_SENSE_EN_MASK;
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,
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);
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);
229 dev_dbg(priv->dev, "Successfully configured accessory detect\n");
232 mutex_unlock(&priv->jack_lock);
234 pm_runtime_mark_last_busy(priv->dev);
235 pm_runtime_put_autosuspend(priv->dev);
240 static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
242 struct cs42l43 *cs42l43 = priv->core;
243 unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT;
245 dev_dbg(priv->dev, "Start headset bias\n");
247 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
248 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
252 val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
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);
263 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
264 CS42L43_HSBIAS_MODE_MASK, val);
266 msleep(priv->bias_ramp_ms);
269 static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv)
271 struct cs42l43 *cs42l43 = priv->core;
273 dev_dbg(priv->dev, "Stop headset bias\n");
275 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
276 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
278 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
279 CS42L43_HS_CLAMP_DISABLE_MASK, 0);
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);
289 irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
291 struct cs42l43_codec *priv = data;
293 queue_delayed_work(system_wq, &priv->bias_sense_timeout,
294 msecs_to_jiffies(1000));
299 #define CS42L43_JACK_PRESENT 0x3
300 #define CS42L43_JACK_ABSENT 0x0
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)
311 static inline bool cs42l43_jack_present(struct cs42l43_codec *priv)
313 struct cs42l43 *cs42l43 = priv->core;
314 unsigned int sts = 0;
316 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
318 sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
320 return sts == CS42L43_JACK_PRESENT;
323 static void cs42l43_start_button_detect(struct cs42l43_codec *priv)
325 struct cs42l43 *cs42l43 = priv->core;
326 unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
328 dev_dbg(priv->dev, "Start button detect\n");
330 priv->button_detect_running = true;
333 val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
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);
340 static void cs42l43_stop_button_detect(struct cs42l43_codec *priv)
342 struct cs42l43 *cs42l43 = priv->core;
344 dev_dbg(priv->dev, "Stop button detect\n");
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);
351 priv->button_detect_running = false;
354 #define CS42L43_BUTTON_COMB_MAX 512
355 #define CS42L43_BUTTON_ROUT 2210
357 void cs42l43_button_press_work(struct work_struct *work)
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;
366 ret = pm_runtime_resume_and_get(priv->dev);
368 dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
372 mutex_lock(&priv->jack_lock);
374 if (!priv->button_detect_running) {
375 dev_dbg(priv->dev, "Spurious button press IRQ\n");
379 regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
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");
387 if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
388 dev_dbg(priv->dev, "Button ignored due to bias sense\n");
392 val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
393 val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
395 val = (CS42L43_BUTTON_ROUT << 20) / val;
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);
408 dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
410 snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
413 mutex_unlock(&priv->jack_lock);
415 pm_runtime_mark_last_busy(priv->dev);
416 pm_runtime_put_autosuspend(priv->dev);
419 irqreturn_t cs42l43_button_press(int irq, void *data)
421 struct cs42l43_codec *priv = data;
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));
430 void cs42l43_button_release_work(struct work_struct *work)
432 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
433 button_release_work);
436 ret = pm_runtime_resume_and_get(priv->dev);
438 dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
442 mutex_lock(&priv->jack_lock);
444 if (priv->button_detect_running) {
445 dev_dbg(priv->dev, "Button release IRQ\n");
447 snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
449 dev_dbg(priv->dev, "Spurious button release IRQ\n");
452 mutex_unlock(&priv->jack_lock);
454 pm_runtime_mark_last_busy(priv->dev);
455 pm_runtime_put_autosuspend(priv->dev);
458 irqreturn_t cs42l43_button_release(int irq, void *data)
460 struct cs42l43_codec *priv = data;
462 queue_work(system_wq, &priv->button_release_work);
467 void cs42l43_bias_sense_timeout(struct work_struct *work)
469 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
470 bias_sense_timeout.work);
471 struct cs42l43 *cs42l43 = priv->core;
474 ret = pm_runtime_resume_and_get(priv->dev);
476 dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
480 mutex_lock(&priv->jack_lock);
482 if (cs42l43_jack_present(priv) && priv->button_detect_running) {
483 dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
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);
494 mutex_unlock(&priv->jack_lock);
496 pm_runtime_mark_last_busy(priv->dev);
497 pm_runtime_put_autosuspend(priv->dev);
500 static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
502 struct cs42l43 *cs42l43 = priv->core;
504 dev_dbg(priv->dev, "Start load detect\n");
506 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
508 priv->load_detect_running = true;
511 unsigned long time_left;
513 reinit_completion(&priv->hp_shutdown);
515 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
516 CS42L43_HP_EN_MASK, 0);
518 time_left = wait_for_completion_timeout(&priv->hp_shutdown,
519 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
521 dev_err(priv->dev, "Load detect HP power down timed out\n");
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);
536 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
537 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
539 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
540 CS42L43_HPLOAD_DET_EN_MASK,
541 CS42L43_HPLOAD_DET_EN_MASK);
543 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
546 static void cs42l43_stop_load_detect(struct cs42l43_codec *priv)
548 struct cs42l43 *cs42l43 = priv->core;
550 dev_dbg(priv->dev, "Stop load detect\n");
552 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
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);
571 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
572 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK,
576 unsigned long time_left;
578 reinit_completion(&priv->hp_startup);
580 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
581 CS42L43_HP_EN_MASK, priv->hp_ena);
583 time_left = wait_for_completion_timeout(&priv->hp_startup,
584 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
586 dev_err(priv->dev, "Load detect HP restore timed out\n");
589 priv->load_detect_running = false;
591 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
594 static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
596 struct cs42l43 *cs42l43 = priv->core;
597 unsigned int val = 0;
598 unsigned long time_left;
600 reinit_completion(&priv->load_detect);
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);
610 regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
612 dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
614 /* Bail if jack removed, the load is irrelevant and likely invalid */
615 if (!cs42l43_jack_present(priv))
619 cs42l43_start_hs_bias(priv, false);
620 cs42l43_start_button_detect(priv);
622 return CS42L43_JACK_HEADSET;
625 switch (val & CS42L43_AMP3_RES_DET_MASK) {
626 case 0x0: // low impedance
627 case 0x1: // high impedance
628 return CS42L43_JACK_HEADPHONE;
630 case 0x3: // Open circuit
631 return CS42L43_JACK_LINEOUT;
637 static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
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;
644 reinit_completion(&priv->type_detect);
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);
650 time_left = wait_for_completion_timeout(&priv->type_detect,
651 msecs_to_jiffies(timeout_ms));
653 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
654 CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);
655 cs42l43_stop_hs_bias(priv);
660 regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
662 dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
664 /* Bail if jack removed, the type is irrelevant and likely invalid */
665 if (!cs42l43_jack_present(priv))
668 switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
671 return cs42l43_run_load_detect(priv, true);
673 return cs42l43_run_load_detect(priv, false);
674 case 0x3: // Open-circuit
675 return CS42L43_JACK_EXTENSION;
681 static void cs42l43_clear_jack(struct cs42l43_codec *priv)
683 struct cs42l43 *cs42l43 = priv->core;
685 cs42l43_stop_button_detect(priv);
686 cs42l43_stop_hs_bias(priv);
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);
698 snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
701 void cs42l43_tip_sense_work(struct work_struct *work)
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;
710 ret = pm_runtime_resume_and_get(priv->dev);
712 dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
716 mutex_lock(&priv->jack_lock);
718 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
720 dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
722 tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
723 ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
725 if (tip == CS42L43_JACK_PRESENT) {
726 if (cs42l43->sdw && !priv->jack_present) {
727 priv->jack_present = true;
728 pm_runtime_get(priv->dev);
731 if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
732 report = CS42L43_JACK_OPTICAL;
734 report = cs42l43_run_type_detect(priv);
736 dev_err(priv->dev, "Jack detect failed: %d\n", report);
741 snd_soc_jack_report(priv->jack_hp, report, report);
743 priv->jack_override = 0;
745 cs42l43_clear_jack(priv);
747 if (cs42l43->sdw && priv->jack_present) {
748 pm_runtime_put(priv->dev);
749 priv->jack_present = false;
754 mutex_unlock(&priv->jack_lock);
756 pm_runtime_mark_last_busy(priv->dev);
757 pm_runtime_put_autosuspend(priv->dev);
760 irqreturn_t cs42l43_tip_sense(int irq, void *data)
762 struct cs42l43_codec *priv = data;
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);
769 queue_delayed_work(system_long_wq, &priv->tip_sense_work,
770 msecs_to_jiffies(priv->tip_debounce_ms));
775 enum 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,
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)
793 static const struct cs42l43_jack_override_mode {
794 unsigned int hsdet_mode;
795 unsigned int mic_ctrl;
796 unsigned int clamp_ctrl;
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,
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,
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,
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,
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,
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,
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,
844 static const char * const cs42l43_jack_text[] = {
845 "None", "CTIA", "OMTP", "Headphone", "Line-Out",
846 "Line-In", "Microphone", "Optical",
849 SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text);
851 int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
853 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
854 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
856 mutex_lock(&priv->jack_lock);
857 ucontrol->value.integer.value[0] = priv->jack_override;
858 mutex_unlock(&priv->jack_lock);
863 int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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];
871 BUILD_BUG_ON(ARRAY_SIZE(cs42l43_jack_override_modes) !=
872 ARRAY_SIZE(cs42l43_jack_text) - 1);
874 if (override >= e->items)
877 mutex_lock(&priv->jack_lock);
879 if (!cs42l43_jack_present(priv)) {
880 mutex_unlock(&priv->jack_lock);
884 if (override == priv->jack_override) {
885 mutex_unlock(&priv->jack_lock);
889 priv->jack_override = override;
891 cs42l43_clear_jack(priv);
894 queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
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);
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);
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);
932 case CS42L43_JACK_RAW_MICROPHONE:
933 cs42l43_start_hs_bias(priv, false);
939 snd_soc_jack_report(priv->jack_hp,
940 cs42l43_jack_override_modes[override].report,
941 cs42l43_jack_override_modes[override].report);
944 mutex_unlock(&priv->jack_lock);