Lines Matching +full:bias +full:- +full:high +full:- +full:impedance
1 // SPDX-License-Identifier: GPL-2.0
5 // Copyright (C) 2022-2023 Cirrus Logic, Inc. and
15 #include <linux/mfd/cs42l43-regs.h>
26 #include <sound/soc-component.h>
27 #include <sound/soc-jack.h>
50 struct cs42l43 *cs42l43 = priv->core;
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);
66 dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval);
67 return -EINVAL;
74 struct cs42l43 *cs42l43 = priv->core;
81 dev_dbg(priv->dev, "Configure accessory detect\n");
83 ret = pm_runtime_resume_and_get(priv->dev);
85 dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
89 mutex_lock(&priv->jack_lock);
91 priv->jack_hp = jack;
96 ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
97 if (ret != -EINVAL) {
99 dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
105 ret = -EINVAL;
106 dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
110 ret = device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
111 priv->buttons, ret);
113 dev_err(priv->dev, "Property cirrus,button-ohms malformed: %d\n",
118 priv->buttons[0] = 70;
119 priv->buttons[1] = 185;
120 priv->buttons[2] = 355;
121 priv->buttons[3] = 735;
124 ret = cs42l43_find_index(priv, "cirrus,detect-us", 50000, &priv->detect_us,
131 priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low");
133 ret = cs42l43_find_index(priv, "cirrus,bias-ramp-ms", 170,
134 &priv->bias_ramp_ms, cs42l43_accdet_ramp_ms,
141 ret = cs42l43_find_index(priv, "cirrus,bias-sense-microamp", 14,
142 &priv->bias_sense_ua, cs42l43_accdet_bias_sense,
147 if (priv->bias_sense_ua)
150 if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute"))
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);
161 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-invert"))
164 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup"))
169 ret = cs42l43_find_index(priv, "cirrus,tip-fall-db-ms", 500,
170 &priv->tip_fall_db_ms, cs42l43_accdet_db_ms,
177 ret = cs42l43_find_index(priv, "cirrus,tip-rise-db-ms", 500,
178 &priv->tip_rise_db_ms, cs42l43_accdet_db_ms,
185 if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) {
188 priv->use_ring_sense = true;
191 if (!device_property_read_bool(cs42l43->dev, "cirrus,ring-invert"))
194 if (!device_property_read_bool(cs42l43->dev,
195 "cirrus,ring-disable-pullup"))
198 ret = cs42l43_find_index(priv, "cirrus,ring-fall-db-ms", 500,
206 ret = cs42l43_find_index(priv, "cirrus,ring-rise-db-ms", 500,
215 regmap_update_bits(cs42l43->regmap, CS42L43_RINGSENSE_DEB_CTRL,
223 regmap_update_bits(cs42l43->regmap, CS42L43_TIPSENSE_DEB_CTRL,
227 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
234 regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
237 regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
240 dev_dbg(priv->dev, "Successfully configured accessory detect\n");
243 mutex_unlock(&priv->jack_lock);
245 pm_runtime_put_autosuspend(priv->dev);
252 struct cs42l43 *cs42l43 = priv->core;
255 dev_dbg(priv->dev, "Start headset bias\n");
257 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
261 if (priv->bias_low)
264 if (priv->bias_sense_ua)
265 regmap_update_bits(cs42l43->regmap,
273 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
276 msleep(priv->bias_ramp_ms);
281 struct cs42l43 *cs42l43 = priv->core;
283 dev_dbg(priv->dev, "Stop headset bias\n");
285 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
288 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
291 if (priv->bias_sense_ua) {
292 regmap_update_bits(cs42l43->regmap,
303 queue_delayed_work(system_wq, &priv->bias_sense_timeout,
323 struct cs42l43 *cs42l43 = priv->core;
326 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
335 struct cs42l43 *cs42l43 = priv->core;
338 dev_dbg(priv->dev, "Start button detect\n");
340 priv->button_detect_running = true;
342 if (priv->bias_low)
345 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
352 struct cs42l43 *cs42l43 = priv->core;
354 dev_dbg(priv->dev, "Stop button detect\n");
356 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
361 priv->button_detect_running = false;
371 struct cs42l43 *cs42l43 = priv->core;
377 ret = pm_runtime_resume_and_get(priv->dev);
379 dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
383 mutex_lock(&priv->jack_lock);
385 if (!priv->button_detect_running) {
386 dev_dbg(priv->dev, "Spurious button press IRQ\n");
393 regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
397 dev_dbg(priv->dev, "Button ignored due to removal\n");
402 dev_dbg(priv->dev, "Button ignored due to bias sense\n");
407 val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
414 if (val < priv->buttons[i]) {
416 dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val);
422 dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
424 snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
429 mutex_unlock(&priv->jack_lock);
431 pm_runtime_put_autosuspend(priv->dev);
442 ret = pm_runtime_resume_and_get(priv->dev);
444 dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
448 mutex_lock(&priv->jack_lock);
450 if (priv->button_detect_running) {
451 dev_dbg(priv->dev, "Button release IRQ\n");
453 snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
457 dev_dbg(priv->dev, "Spurious button release IRQ\n");
460 mutex_unlock(&priv->jack_lock);
462 pm_runtime_put_autosuspend(priv->dev);
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,
488 regmap_update_bits(cs42l43->regmap,
494 mutex_unlock(&priv->jack_lock);
496 pm_runtime_put_autosuspend(priv->dev);
501 struct cs42l43 *cs42l43 = priv->core;
503 dev_dbg(priv->dev, "Start load detect\n");
505 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
507 priv->load_detect_running = true;
509 if (priv->hp_ena && !priv->hp_ilimited) {
512 reinit_completion(&priv->hp_shutdown);
514 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
517 time_left = wait_for_completion_timeout(&priv->hp_shutdown,
520 dev_err(priv->dev, "Load detect HP power down timed out\n");
523 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
525 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
526 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
528 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
530 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
532 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
535 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
538 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
542 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
547 struct cs42l43 *cs42l43 = priv->core;
549 dev_dbg(priv->dev, "Stop load detect\n");
551 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
553 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
555 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
557 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
560 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
563 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
565 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
567 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2,
570 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
572 priv->adc_ena);
574 if (priv->hp_ena && !priv->hp_ilimited) {
577 reinit_completion(&priv->hp_startup);
579 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
580 CS42L43_HP_EN_MASK, priv->hp_ena);
582 time_left = wait_for_completion_timeout(&priv->hp_startup,
585 dev_err(priv->dev, "Load detect HP restore timed out\n");
588 priv->load_detect_running = false;
590 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
595 struct cs42l43 *cs42l43 = priv->core;
599 reinit_completion(&priv->load_detect);
602 time_left = wait_for_completion_timeout(&priv->load_detect,
607 return -ETIMEDOUT;
609 regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
611 dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
615 return -ENODEV;
625 case 0x0: // low impedance
626 case 0x1: // high impedance
632 return -EINVAL;
638 struct cs42l43 *cs42l43 = priv->core;
639 int timeout_ms = ((2 * priv->detect_us) / USEC_PER_MSEC) + 200;
643 reinit_completion(&priv->type_detect);
645 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
650 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
653 time_left = wait_for_completion_timeout(&priv->type_detect,
656 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
660 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
664 return -ETIMEDOUT;
666 regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
668 dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
672 return -ENODEV;
678 case 0x2: // 3-pole
680 case 0x3: // Open-circuit
683 return -EINVAL;
689 struct cs42l43 *cs42l43 = priv->core;
694 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
696 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
698 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
700 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
703 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
712 struct cs42l43 *cs42l43 = priv->core;
717 ret = pm_runtime_resume_and_get(priv->dev);
719 dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
723 mutex_lock(&priv->jack_lock);
725 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
727 dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
733 if (cs42l43->sdw && !priv->jack_present) {
734 priv->jack_present = true;
735 pm_runtime_get(priv->dev);
738 if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
743 dev_err(priv->dev, "Jack detect failed: %d\n", report);
748 snd_soc_jack_report(priv->jack_hp, report, report);
750 priv->jack_override = 0;
754 snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
756 if (cs42l43->sdw && priv->jack_present) {
757 pm_runtime_put(priv->dev);
758 priv->jack_present = false;
763 mutex_unlock(&priv->jack_lock);
765 priv->suspend_jack_debounce = false;
767 pm_runtime_put_autosuspend(priv->dev);
773 unsigned int db_delay = priv->tip_debounce_ms;
775 cancel_delayed_work(&priv->bias_sense_timeout);
776 cancel_delayed_work(&priv->tip_sense_work);
779 if (priv->suspend_jack_debounce)
780 db_delay += priv->tip_fall_db_ms + priv->tip_rise_db_ms;
782 queue_delayed_work(system_long_wq, &priv->tip_sense_work,
858 "None", "CTIA", "OMTP", "Headphone", "Line-Out",
859 "Line-In", "Microphone", "Optical",
863 ARRAY_SIZE(cs42l43_jack_text) - 1);
872 mutex_lock(&priv->jack_lock);
873 ucontrol->value.integer.value[0] = priv->jack_override;
874 mutex_unlock(&priv->jack_lock);
883 struct cs42l43 *cs42l43 = priv->core;
884 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
885 unsigned int override = ucontrol->value.integer.value[0];
887 if (override >= e->items)
888 return -EINVAL;
890 mutex_lock(&priv->jack_lock);
893 mutex_unlock(&priv->jack_lock);
894 return -EBUSY;
897 if (override == priv->jack_override) {
898 mutex_unlock(&priv->jack_lock);
902 priv->jack_override = override;
906 snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
909 queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
911 override--;
913 regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
925 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
929 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
940 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
943 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
954 snd_soc_jack_report(priv->jack_hp,
959 mutex_unlock(&priv->jack_lock);