Lines Matching +full:wcd9380 +full:- +full:codec
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
21 #include <sound/soc-dapm.h>
24 #include "wcd-clsh-v2.h"
25 #include "wcd-mbhc-v2.h"
77 WCD9380 = 0, enumerator
188 static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
189 static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, 0);
345 struct regmap *rm = wcd938x->regmap; in wcd938x_io_init()
404 port_num = ch_info->port_num; in wcd938x_sdw_connect_port()
405 ch_mask = ch_info->ch_mask; in wcd938x_sdw_connect_port()
407 port_config->num = port_num; in wcd938x_sdw_connect_port()
410 port_config->ch_mask |= ch_mask; in wcd938x_sdw_connect_port()
412 port_config->ch_mask &= ~ch_mask; in wcd938x_sdw_connect_port()
419 return wcd938x_sdw_connect_port(&wcd->ch_info[ch_id], in wcd938x_connect_port()
420 &wcd->port_config[port_num - 1], in wcd938x_connect_port()
428 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_rxclk()
467 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_hphl_dac_event()
486 if (wcd938x->comp1_enable) { in wcd938x_codec_hphl_dac_event()
491 if (!wcd938x->comp2_enable || (snd_soc_component_read(component, in wcd938x_codec_hphl_dac_event()
521 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_hphr_dac_event()
540 if (wcd938x->comp2_enable) { in wcd938x_codec_hphr_dac_event()
545 if (!wcd938x->comp1_enable || in wcd938x_codec_hphr_dac_event()
575 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_ear_dac_event()
580 wcd938x->ear_rx_path = in wcd938x_codec_ear_dac_event()
583 if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { in wcd938x_codec_ear_dac_event()
603 if (wcd938x->comp1_enable) in wcd938x_codec_ear_dac_event()
610 if (wcd938x->flyback_cur_det_disable == 0) in wcd938x_codec_ear_dac_event()
613 wcd938x->flyback_cur_det_disable++; in wcd938x_codec_ear_dac_event()
614 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, in wcd938x_codec_ear_dac_event()
617 wcd938x->hph_mode); in wcd938x_codec_ear_dac_event()
620 if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { in wcd938x_codec_ear_dac_event()
634 if (wcd938x->comp1_enable) in wcd938x_codec_ear_dac_event()
654 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_aux_dac_event()
668 if (wcd938x->flyback_cur_det_disable == 0) in wcd938x_codec_aux_dac_event()
671 wcd938x->flyback_cur_det_disable++; in wcd938x_codec_aux_dac_event()
672 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, in wcd938x_codec_aux_dac_event()
675 wcd938x->hph_mode); in wcd938x_codec_aux_dac_event()
690 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_hphr_pa()
692 int hph_mode = wcd938x->hph_mode; in wcd938x_codec_enable_hphr_pa()
696 if (wcd938x->ldoh) in wcd938x_codec_enable_hphr_pa()
699 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, in wcd938x_codec_enable_hphr_pa()
701 wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI); in wcd938x_codec_enable_hphr_pa()
711 wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode); in wcd938x_codec_enable_hphr_pa()
714 set_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphr_pa()
725 if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { in wcd938x_codec_enable_hphr_pa()
726 if (!wcd938x->comp2_enable) in wcd938x_codec_enable_hphr_pa()
736 clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphr_pa()
745 enable_irq(wcd938x->hphr_pdm_wd_int); in wcd938x_codec_enable_hphr_pa()
748 disable_irq_nosync(wcd938x->hphr_pdm_wd_int); in wcd938x_codec_enable_hphr_pa()
754 if (!wcd938x->comp2_enable) in wcd938x_codec_enable_hphr_pa()
760 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_codec_enable_hphr_pa()
762 set_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphr_pa()
770 if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { in wcd938x_codec_enable_hphr_pa()
771 if (!wcd938x->comp2_enable) in wcd938x_codec_enable_hphr_pa()
775 clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphr_pa()
777 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_codec_enable_hphr_pa()
783 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, in wcd938x_codec_enable_hphr_pa()
785 if (wcd938x->ldoh) in wcd938x_codec_enable_hphr_pa()
797 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_hphl_pa()
799 int hph_mode = wcd938x->hph_mode; in wcd938x_codec_enable_hphl_pa()
803 if (wcd938x->ldoh) in wcd938x_codec_enable_hphl_pa()
806 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, in wcd938x_codec_enable_hphl_pa()
808 wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI); in wcd938x_codec_enable_hphl_pa()
817 wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode); in wcd938x_codec_enable_hphl_pa()
820 set_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphl_pa()
831 if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { in wcd938x_codec_enable_hphl_pa()
832 if (!wcd938x->comp1_enable) in wcd938x_codec_enable_hphl_pa()
841 clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphl_pa()
851 enable_irq(wcd938x->hphl_pdm_wd_int); in wcd938x_codec_enable_hphl_pa()
854 disable_irq_nosync(wcd938x->hphl_pdm_wd_int); in wcd938x_codec_enable_hphl_pa()
860 if (!wcd938x->comp1_enable) in wcd938x_codec_enable_hphl_pa()
866 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF); in wcd938x_codec_enable_hphl_pa()
867 set_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphl_pa()
875 if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { in wcd938x_codec_enable_hphl_pa()
876 if (!wcd938x->comp1_enable) in wcd938x_codec_enable_hphl_pa()
880 clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); in wcd938x_codec_enable_hphl_pa()
882 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_codec_enable_hphl_pa()
888 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, in wcd938x_codec_enable_hphl_pa()
890 if (wcd938x->ldoh) in wcd938x_codec_enable_hphl_pa()
902 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_aux_pa()
904 int hph_mode = wcd938x->hph_mode; in wcd938x_codec_enable_aux_pa()
919 enable_irq(wcd938x->aux_pdm_wd_int); in wcd938x_codec_enable_aux_pa()
922 disable_irq_nosync(wcd938x->aux_pdm_wd_int); in wcd938x_codec_enable_aux_pa()
929 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, in wcd938x_codec_enable_aux_pa()
934 wcd938x->flyback_cur_det_disable--; in wcd938x_codec_enable_aux_pa()
935 if (wcd938x->flyback_cur_det_disable == 0) in wcd938x_codec_enable_aux_pa()
946 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_ear_pa()
948 int hph_mode = wcd938x->hph_mode; in wcd938x_codec_enable_ear_pa()
956 wcd938x->ear_rx_path = snd_soc_component_read(component, in wcd938x_codec_enable_ear_pa()
958 if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) in wcd938x_codec_enable_ear_pa()
965 if (!wcd938x->comp1_enable) in wcd938x_codec_enable_ear_pa()
979 if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) in wcd938x_codec_enable_ear_pa()
980 enable_irq(wcd938x->aux_pdm_wd_int); in wcd938x_codec_enable_ear_pa()
982 enable_irq(wcd938x->hphl_pdm_wd_int); in wcd938x_codec_enable_ear_pa()
985 if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) in wcd938x_codec_enable_ear_pa()
986 disable_irq_nosync(wcd938x->aux_pdm_wd_int); in wcd938x_codec_enable_ear_pa()
988 disable_irq_nosync(wcd938x->hphl_pdm_wd_int); in wcd938x_codec_enable_ear_pa()
991 if (!wcd938x->comp1_enable) in wcd938x_codec_enable_ear_pa()
996 if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) in wcd938x_codec_enable_ear_pa()
1003 wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, in wcd938x_codec_enable_ear_pa()
1006 wcd938x->flyback_cur_det_disable--; in wcd938x_codec_enable_ear_pa()
1007 if (wcd938x->flyback_cur_det_disable == 0) in wcd938x_codec_enable_ear_pa()
1020 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_dmic()
1024 switch (w->shift) { in wcd938x_codec_enable_dmic()
1054 dev_err(component->dev, "%s: Invalid DMIC Selection\n", in wcd938x_codec_enable_dmic()
1056 return -EINVAL; in wcd938x_codec_enable_dmic()
1091 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_tx_swr_ctrl()
1096 bank = (wcd938x_swr_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev)) ? 0 : 1; in wcd938x_tx_swr_ctrl()
1101 if (strnstr(w->name, "ADC", sizeof("ADC"))) { in wcd938x_tx_swr_ctrl()
1104 if (test_bit(WCD_ADC1, &wcd938x->status_mask)) in wcd938x_tx_swr_ctrl()
1105 mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]]; in wcd938x_tx_swr_ctrl()
1106 if (test_bit(WCD_ADC2, &wcd938x->status_mask)) in wcd938x_tx_swr_ctrl()
1107 mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]]; in wcd938x_tx_swr_ctrl()
1108 if (test_bit(WCD_ADC3, &wcd938x->status_mask)) in wcd938x_tx_swr_ctrl()
1109 mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]]; in wcd938x_tx_swr_ctrl()
1110 if (test_bit(WCD_ADC4, &wcd938x->status_mask)) in wcd938x_tx_swr_ctrl()
1111 mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]]; in wcd938x_tx_swr_ctrl()
1128 if (strnstr(w->name, "ADC", sizeof("ADC"))) { in wcd938x_tx_swr_ctrl()
1166 ret = -EINVAL; in wcd938x_get_adc_mode()
1175 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_adc()
1186 set_bit(w->shift, &wcd938x->status_mask); in wcd938x_codec_enable_adc()
1191 clear_bit(w->shift, &wcd938x->status_mask); in wcd938x_codec_enable_adc()
1230 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_adc_enable_req()
1242 wcd938x_tx_channel_config(component, w->shift, 1); in wcd938x_adc_enable_req()
1243 mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]); in wcd938x_adc_enable_req()
1245 dev_info(component->dev, "Invalid ADC mode\n"); in wcd938x_adc_enable_req()
1246 return -EINVAL; in wcd938x_adc_enable_req()
1248 switch (w->shift) { in wcd938x_adc_enable_req()
1285 wcd938x_tx_channel_config(component, w->shift, 0); in wcd938x_adc_enable_req()
1288 switch (w->shift) { in wcd938x_adc_enable_req()
1337 int micb_index = micb_num - 1; in wcd938x_micbias_control()
1354 dev_err(component->dev, "%s: Invalid micbias number: %d\n", in wcd938x_micbias_control()
1356 return -EINVAL; in wcd938x_micbias_control()
1361 wcd938x->pullup_ref[micb_index]++; in wcd938x_micbias_control()
1362 if ((wcd938x->pullup_ref[micb_index] == 1) && in wcd938x_micbias_control()
1363 (wcd938x->micb_ref[micb_index] == 0)) in wcd938x_micbias_control()
1369 if (wcd938x->pullup_ref[micb_index] > 0) in wcd938x_micbias_control()
1370 wcd938x->pullup_ref[micb_index]--; in wcd938x_micbias_control()
1372 if ((wcd938x->pullup_ref[micb_index] == 0) && in wcd938x_micbias_control()
1373 (wcd938x->micb_ref[micb_index] == 0)) in wcd938x_micbias_control()
1378 wcd938x->micb_ref[micb_index]++; in wcd938x_micbias_control()
1379 if (wcd938x->micb_ref[micb_index] == 1) { in wcd938x_micbias_control()
1394 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_micbias_control()
1398 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_micbias_control()
1404 if (wcd938x->micb_ref[micb_index] > 0) in wcd938x_micbias_control()
1405 wcd938x->micb_ref[micb_index]--; in wcd938x_micbias_control()
1407 if ((wcd938x->micb_ref[micb_index] == 0) && in wcd938x_micbias_control()
1408 (wcd938x->pullup_ref[micb_index] > 0)) in wcd938x_micbias_control()
1412 else if ((wcd938x->micb_ref[micb_index] == 0) && in wcd938x_micbias_control()
1413 (wcd938x->pullup_ref[micb_index] == 0)) { in wcd938x_micbias_control()
1415 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_micbias_control()
1421 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_micbias_control()
1425 wcd_mbhc_event_notify(wcd938x->wcd_mbhc, in wcd938x_micbias_control()
1437 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_micbias()
1438 int micb_num = w->shift; in wcd938x_codec_enable_micbias()
1460 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wcd938x_codec_enable_micbias_pullup()
1461 int micb_num = w->shift; in wcd938x_codec_enable_micbias_pullup()
1486 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in wcd938x_tx_mode_get()
1487 int path = e->shift_l; in wcd938x_tx_mode_get()
1489 ucontrol->value.enumerated.item[0] = wcd938x->tx_mode[path]; in wcd938x_tx_mode_get()
1499 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in wcd938x_tx_mode_put()
1500 int path = e->shift_l; in wcd938x_tx_mode_put()
1502 if (wcd938x->tx_mode[path] == ucontrol->value.enumerated.item[0]) in wcd938x_tx_mode_put()
1505 wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0]; in wcd938x_tx_mode_put()
1516 ucontrol->value.enumerated.item[0] = wcd938x->hph_mode; in wcd938x_rx_hph_mode_get()
1527 if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0]) in wcd938x_rx_hph_mode_put()
1530 wcd938x->hph_mode = ucontrol->value.enumerated.item[0]; in wcd938x_rx_hph_mode_put()
1541 if (wcd938x->comp1_enable) { in wcd938x_ear_pa_put_gain()
1542 dev_err(component->dev, "Can not set EAR PA Gain, compander1 is enabled\n"); in wcd938x_ear_pa_put_gain()
1543 return -EINVAL; in wcd938x_ear_pa_put_gain()
1548 ucontrol->value.integer.value[0]); in wcd938x_ear_pa_put_gain()
1562 mc = (struct soc_mixer_control *)(kcontrol->private_value); in wcd938x_get_compander()
1563 hphr = mc->shift; in wcd938x_get_compander()
1566 ucontrol->value.integer.value[0] = wcd938x->comp2_enable; in wcd938x_get_compander()
1568 ucontrol->value.integer.value[0] = wcd938x->comp1_enable; in wcd938x_get_compander()
1579 int value = ucontrol->value.integer.value[0]; in wcd938x_set_compander()
1584 mc = (struct soc_mixer_control *)(kcontrol->private_value); in wcd938x_set_compander()
1585 hphr = mc->shift; in wcd938x_set_compander()
1587 wcd = wcd938x->sdw_priv[AIF1_PB]; in wcd938x_set_compander()
1590 wcd938x->comp2_enable = value; in wcd938x_set_compander()
1592 wcd938x->comp1_enable = value; in wcd938x_set_compander()
1594 portidx = wcd->ch_info[mc->reg].port_num; in wcd938x_set_compander()
1597 wcd938x_connect_port(wcd, portidx, mc->reg, true); in wcd938x_set_compander()
1599 wcd938x_connect_port(wcd, portidx, mc->reg, false); in wcd938x_set_compander()
1610 ucontrol->value.integer.value[0] = wcd938x->ldoh; in wcd938x_ldoh_get()
1621 if (wcd938x->ldoh == ucontrol->value.integer.value[0]) in wcd938x_ldoh_put()
1624 wcd938x->ldoh = ucontrol->value.integer.value[0]; in wcd938x_ldoh_put()
1851 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; in wcd938x_get_swr_port()
1852 int dai_id = mixer->shift; in wcd938x_get_swr_port()
1853 int portidx, ch_idx = mixer->reg; in wcd938x_get_swr_port()
1856 wcd = wcd938x->sdw_priv[dai_id]; in wcd938x_get_swr_port()
1857 portidx = wcd->ch_info[ch_idx].port_num; in wcd938x_get_swr_port()
1859 ucontrol->value.integer.value[0] = wcd->port_enable[portidx]; in wcd938x_get_swr_port()
1871 (struct soc_mixer_control *)kcontrol->private_value; in wcd938x_set_swr_port()
1872 int ch_idx = mixer->reg; in wcd938x_set_swr_port()
1874 int dai_id = mixer->shift; in wcd938x_set_swr_port()
1877 wcd = wcd938x->sdw_priv[dai_id]; in wcd938x_set_swr_port()
1879 portidx = wcd->ch_info[ch_idx].port_num; in wcd938x_set_swr_port()
1880 if (ucontrol->value.integer.value[0]) in wcd938x_set_swr_port()
1885 wcd->port_enable[portidx] = enable; in wcd938x_set_swr_port()
1915 dev_err(component->dev, "%s: invalid number of buttons: %d\n", in wcd938x_mbhc_program_btn_thr()
1924 dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", in wcd938x_mbhc_program_btn_thr()
1981 return -EINVAL; in wcd938x_get_micb_vout_ctl_val()
1983 return (micb_mv - 1000) / 50; in wcd938x_get_micb_vout_ctl_val()
2006 return -EINVAL; in wcd938x_mbhc_micb_adjust_voltage()
2008 mutex_lock(&wcd938x->micb_lock); in wcd938x_mbhc_micb_adjust_voltage()
2013 * to avoid slow micbias ramp-up or down enable pull-up in wcd938x_mbhc_micb_adjust_voltage()
2014 * momentarily, change the micbias value and then re-enable in wcd938x_mbhc_micb_adjust_voltage()
2024 ret = -EINVAL; in wcd938x_mbhc_micb_adjust_voltage()
2053 mutex_unlock(&wcd938x->micb_lock); in wcd938x_mbhc_micb_adjust_voltage()
2064 return -EINVAL; in wcd938x_mbhc_micb_ctrl_threshold_mic()
2070 if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) in wcd938x_mbhc_micb_ctrl_threshold_mic()
2073 micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv; in wcd938x_mbhc_micb_ctrl_threshold_mic()
2092 regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x20); in wcd938x_mbhc_get_result_params()
2094 regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_2, &val); in wcd938x_mbhc_get_result_params()
2099 regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_1, &val1); in wcd938x_mbhc_get_result_params()
2101 regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x00); in wcd938x_mbhc_get_result_params()
2109 dev_err(component->dev, "Impedance detect ramp error, c1=%d, x1=0x%x\n", in wcd938x_mbhc_get_result_params()
2114 denom = (x1 * d1) - (1 << (14 - noff)); in wcd938x_mbhc_get_result_params()
2120 dev_dbg(component->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n", in wcd938x_mbhc_get_result_params()
2125 regmap_read(wcd938x->regmap, in wcd938x_mbhc_get_result_params()
2127 regmap_read(wcd938x->regmap, in wcd938x_mbhc_get_result_params()
2146 WCD938X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl); in wcd938x_mbhc_zdet_ramp()
2148 WCD938X_VTH_MASK, zdet_param->btn5); in wcd938x_mbhc_zdet_ramp()
2150 WCD938X_VTH_MASK, zdet_param->btn6); in wcd938x_mbhc_zdet_ramp()
2152 WCD938X_VTH_MASK, zdet_param->btn7); in wcd938x_mbhc_zdet_ramp()
2154 WCD938X_ZDET_RANGE_CTL_MASK, zdet_param->noff); in wcd938x_mbhc_zdet_ramp()
2156 0x0F, zdet_param->nshift); in wcd938x_mbhc_zdet_ramp()
2161 regmap_update_bits(wcd938x->regmap, in wcd938x_mbhc_zdet_ramp()
2163 dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n", in wcd938x_mbhc_zdet_ramp()
2164 __func__, zdet_param->noff); in wcd938x_mbhc_zdet_ramp()
2165 wcd938x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet); in wcd938x_mbhc_zdet_ramp()
2166 regmap_update_bits(wcd938x->regmap, in wcd938x_mbhc_zdet_ramp()
2175 regmap_update_bits(wcd938x->regmap, in wcd938x_mbhc_zdet_ramp()
2177 dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n", in wcd938x_mbhc_zdet_ramp()
2178 __func__, zdet_param->noff); in wcd938x_mbhc_zdet_ramp()
2179 wcd938x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet); in wcd938x_mbhc_zdet_ramp()
2180 regmap_update_bits(wcd938x->regmap, in wcd938x_mbhc_zdet_ramp()
2199 q1_cal = (10000 - ((q1 & 0x7F) * 25)); in wcd938x_wcd_mbhc_qfuse_cal()
2237 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2241 /* For NO-jack, disable L_DET_EN before Z-det measurements */ in wcd938x_wcd_mbhc_calc_impedance()
2242 if (wcd938x->mbhc_cfg.hphl_swh) in wcd938x_wcd_mbhc_calc_impedance()
2243 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2247 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2253 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2290 dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", in wcd938x_wcd_mbhc_calc_impedance()
2297 (zdet_param_ptr->noff == 0x6)) || in wcd938x_wcd_mbhc_calc_impedance()
2322 dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", in wcd938x_wcd_mbhc_calc_impedance()
2328 dev_dbg(component->dev, in wcd938x_wcd_mbhc_calc_impedance()
2337 dev_dbg(component->dev, in wcd938x_wcd_mbhc_calc_impedance()
2340 wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO); in wcd938x_wcd_mbhc_calc_impedance()
2359 z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); in wcd938x_wcd_mbhc_calc_impedance()
2360 z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); in wcd938x_wcd_mbhc_calc_impedance()
2362 dev_dbg(component->dev, "%s: stereo plug type detected\n", in wcd938x_wcd_mbhc_calc_impedance()
2364 wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_STEREO); in wcd938x_wcd_mbhc_calc_impedance()
2366 dev_dbg(component->dev, "%s: MONO plug type detected\n", in wcd938x_wcd_mbhc_calc_impedance()
2368 wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO); in wcd938x_wcd_mbhc_calc_impedance()
2372 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2379 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2382 /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ in wcd938x_wcd_mbhc_calc_impedance()
2383 if (wcd938x->mbhc_cfg.hphl_swh) in wcd938x_wcd_mbhc_calc_impedance()
2384 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2390 regmap_update_bits(wcd938x->regmap, in wcd938x_wcd_mbhc_calc_impedance()
2423 if (wcd938x->mbhc_cfg.moist_rref == R_OFF) { in wcd938x_mbhc_moisture_config()
2430 if (!wcd938x->mbhc_cfg.hphl_swh) { in wcd938x_mbhc_moisture_config()
2431 dev_dbg(component->dev, "%s: disable moisture detection for NC\n", in wcd938x_mbhc_moisture_config()
2439 WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref); in wcd938x_mbhc_moisture_config()
2448 WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref); in wcd938x_mbhc_moisture_detect_en()
2459 if (wcd938x->mbhc_cfg.moist_rref == R_OFF) { in wcd938x_mbhc_get_moisture_status()
2466 if (!wcd938x->mbhc_cfg.hphl_swh) { in wcd938x_mbhc_get_moisture_status()
2467 dev_dbg(component->dev, "%s: disable moisture detection for NC\n", in wcd938x_mbhc_get_moisture_status()
2523 ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd938x->wcd_mbhc); in wcd938x_get_hph_type()
2538 mc = (struct soc_mixer_control *)(kcontrol->private_value); in wcd938x_hph_impedance_get()
2539 hphr = mc->shift; in wcd938x_hph_impedance_get()
2540 wcd_mbhc_get_impedance(wcd938x->wcd_mbhc, &zl, &zr); in wcd938x_hph_impedance_get()
2541 dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); in wcd938x_hph_impedance_get()
2542 ucontrol->value.integer.value[0] = hphr ? zr : zl; in wcd938x_hph_impedance_get()
2562 struct wcd_mbhc_intr *intr_ids = &wcd938x->intr_ids; in wcd938x_mbhc_init()
2564 intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2566 intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2568 intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2570 intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2572 intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2574 intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2576 intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_mbhc_init()
2579 wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true); in wcd938x_mbhc_init()
2580 if (IS_ERR(wcd938x->wcd_mbhc)) in wcd938x_mbhc_init()
2581 return PTR_ERR(wcd938x->wcd_mbhc); in wcd938x_mbhc_init()
2595 wcd_mbhc_deinit(wcd938x->wcd_mbhc); in wcd938x_mbhc_deinit()
2983 vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv); in wcd938x_set_micbias_data()
2984 vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv); in wcd938x_set_micbias_data()
2985 vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv); in wcd938x_set_micbias_data()
2986 vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv); in wcd938x_set_micbias_data()
2988 return -EINVAL; in wcd938x_set_micbias_data()
2990 regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1, in wcd938x_set_micbias_data()
2992 regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2, in wcd938x_set_micbias_data()
2994 regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3, in wcd938x_set_micbias_data()
2996 regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4, in wcd938x_set_micbias_data()
3028 wcd->virq = irq_domain_create_linear(NULL, 1, &wcd_domain_ops, NULL); in wcd938x_irq_init()
3029 if (!(wcd->virq)) { in wcd938x_irq_init()
3031 return -EINVAL; in wcd938x_irq_init()
3034 return devm_regmap_add_irq_chip(dev, wcd->regmap, in wcd938x_irq_init()
3035 irq_create_mapping(wcd->virq, 0), in wcd938x_irq_init()
3037 &wcd->irq_chip); in wcd938x_irq_init()
3043 struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev; in wcd938x_soc_codec_probe()
3044 struct device *dev = component->dev; in wcd938x_soc_codec_probe()
3048 time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete, in wcd938x_soc_codec_probe()
3052 return -ETIMEDOUT; in wcd938x_soc_codec_probe()
3055 snd_soc_component_init_regmap(component, wcd938x->regmap); in wcd938x_soc_codec_probe()
3061 wcd938x->variant = snd_soc_component_read_field(component, in wcd938x_soc_codec_probe()
3065 wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X); in wcd938x_soc_codec_probe()
3066 if (IS_ERR(wcd938x->clsh_info)) { in wcd938x_soc_codec_probe()
3068 return PTR_ERR(wcd938x->clsh_info); in wcd938x_soc_codec_probe()
3074 regmap_write(wcd938x->regmap, in wcd938x_soc_codec_probe()
3080 wcd938x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_soc_codec_probe()
3082 wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_soc_codec_probe()
3084 wcd938x->aux_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip, in wcd938x_soc_codec_probe()
3088 ret = request_threaded_irq(wcd938x->hphr_pdm_wd_int, NULL, wcd938x_wd_handle_irq, in wcd938x_soc_codec_probe()
3096 ret = request_threaded_irq(wcd938x->hphl_pdm_wd_int, NULL, wcd938x_wd_handle_irq, in wcd938x_soc_codec_probe()
3104 ret = request_threaded_irq(wcd938x->aux_pdm_wd_int, NULL, wcd938x_wd_handle_irq, in wcd938x_soc_codec_probe()
3113 disable_irq_nosync(wcd938x->hphr_pdm_wd_int); in wcd938x_soc_codec_probe()
3114 disable_irq_nosync(wcd938x->hphl_pdm_wd_int); in wcd938x_soc_codec_probe()
3115 disable_irq_nosync(wcd938x->aux_pdm_wd_int); in wcd938x_soc_codec_probe()
3117 switch (wcd938x->variant) { in wcd938x_soc_codec_probe()
3118 case WCD9380: in wcd938x_soc_codec_probe()
3122 dev_err(component->dev, in wcd938x_soc_codec_probe()
3124 __func__, wcd938x->variant); in wcd938x_soc_codec_probe()
3132 dev_err(component->dev, in wcd938x_soc_codec_probe()
3134 __func__, wcd938x->variant); in wcd938x_soc_codec_probe()
3144 dev_err(component->dev, "mbhc initialization failed\n"); in wcd938x_soc_codec_probe()
3151 free_irq(wcd938x->aux_pdm_wd_int, wcd938x); in wcd938x_soc_codec_probe()
3153 free_irq(wcd938x->hphl_pdm_wd_int, wcd938x); in wcd938x_soc_codec_probe()
3155 free_irq(wcd938x->hphr_pdm_wd_int, wcd938x); in wcd938x_soc_codec_probe()
3157 wcd_clsh_ctrl_free(wcd938x->clsh_info); in wcd938x_soc_codec_probe()
3168 free_irq(wcd938x->aux_pdm_wd_int, wcd938x); in wcd938x_soc_codec_remove()
3169 free_irq(wcd938x->hphl_pdm_wd_int, wcd938x); in wcd938x_soc_codec_remove()
3170 free_irq(wcd938x->hphr_pdm_wd_int, wcd938x); in wcd938x_soc_codec_remove()
3172 wcd_clsh_ctrl_free(wcd938x->clsh_info); in wcd938x_soc_codec_remove()
3178 struct wcd938x_priv *wcd = dev_get_drvdata(comp->dev); in wcd938x_codec_set_jack()
3181 return wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack); in wcd938x_codec_set_jack()
3183 wcd_mbhc_stop(wcd->wcd_mbhc); in wcd938x_codec_set_jack()
3204 struct device_node *np = dev->of_node; in wcd938x_dt_parse_micbias_info()
3208 rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val); in wcd938x_dt_parse_micbias_info()
3210 wcd->micb1_mv = prop_val/1000; in wcd938x_dt_parse_micbias_info()
3214 rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val); in wcd938x_dt_parse_micbias_info()
3216 wcd->micb2_mv = prop_val/1000; in wcd938x_dt_parse_micbias_info()
3220 rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val); in wcd938x_dt_parse_micbias_info()
3222 wcd->micb3_mv = prop_val/1000; in wcd938x_dt_parse_micbias_info()
3226 rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val); in wcd938x_dt_parse_micbias_info()
3228 wcd->micb4_mv = prop_val/1000; in wcd938x_dt_parse_micbias_info()
3241 value = gpiod_get_value(wcd938x->us_euro_gpio); in wcd938x_swap_gnd_mic()
3243 gpiod_set_value(wcd938x->us_euro_gpio, !value); in wcd938x_swap_gnd_mic()
3251 struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg; in wcd938x_populate_dt_data()
3254 wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0); in wcd938x_populate_dt_data()
3255 if (wcd938x->reset_gpio < 0) in wcd938x_populate_dt_data()
3256 return dev_err_probe(dev, wcd938x->reset_gpio, in wcd938x_populate_dt_data()
3259 wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", in wcd938x_populate_dt_data()
3261 if (IS_ERR(wcd938x->us_euro_gpio)) in wcd938x_populate_dt_data()
3262 return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio), in wcd938x_populate_dt_data()
3263 "us-euro swap Control GPIO not found\n"); in wcd938x_populate_dt_data()
3265 cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; in wcd938x_populate_dt_data()
3267 wcd938x->supplies[0].supply = "vdd-rxtx"; in wcd938x_populate_dt_data()
3268 wcd938x->supplies[1].supply = "vdd-io"; in wcd938x_populate_dt_data()
3269 wcd938x->supplies[2].supply = "vdd-buck"; in wcd938x_populate_dt_data()
3270 wcd938x->supplies[3].supply = "vdd-mic-bias"; in wcd938x_populate_dt_data()
3272 ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_populate_dt_data()
3276 ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_populate_dt_data()
3278 regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_populate_dt_data()
3284 cfg->mbhc_micbias = MIC_BIAS_2; in wcd938x_populate_dt_data()
3285 cfg->anc_micbias = MIC_BIAS_2; in wcd938x_populate_dt_data()
3286 cfg->v_hs_max = WCD_MBHC_HS_V_MAX; in wcd938x_populate_dt_data()
3287 cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS; in wcd938x_populate_dt_data()
3288 cfg->micb_mv = wcd938x->micb2_mv; in wcd938x_populate_dt_data()
3289 cfg->linein_th = 5000; in wcd938x_populate_dt_data()
3290 cfg->hs_thr = 1700; in wcd938x_populate_dt_data()
3291 cfg->hph_thr = 50; in wcd938x_populate_dt_data()
3300 gpio_direction_output(wcd938x->reset_gpio, 0); in wcd938x_reset()
3303 gpio_set_value(wcd938x->reset_gpio, 1); in wcd938x_reset()
3314 struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev); in wcd938x_codec_hw_params()
3315 struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id]; in wcd938x_codec_hw_params()
3323 struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev); in wcd938x_codec_free()
3324 struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id]; in wcd938x_codec_free()
3332 struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev); in wcd938x_codec_set_sdw_stream()
3333 struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id]; in wcd938x_codec_set_sdw_stream()
3347 .name = "wcd938x-sdw-rx",
3360 .name = "wcd938x-sdw-tx",
3386 wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode); in wcd938x_bind()
3387 if (!wcd938x->rxdev) { in wcd938x_bind()
3389 ret = -EINVAL; in wcd938x_bind()
3392 wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev); in wcd938x_bind()
3393 wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x; in wcd938x_bind()
3395 wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode); in wcd938x_bind()
3396 if (!wcd938x->txdev) { in wcd938x_bind()
3398 ret = -EINVAL; in wcd938x_bind()
3401 wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev); in wcd938x_bind()
3402 wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x; in wcd938x_bind()
3403 wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev); in wcd938x_bind()
3407 if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS | in wcd938x_bind()
3410 ret = -EINVAL; in wcd938x_bind()
3414 if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS | in wcd938x_bind()
3417 ret = -EINVAL; in wcd938x_bind()
3421 if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS | in wcd938x_bind()
3424 ret = -EINVAL; in wcd938x_bind()
3428 wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL); in wcd938x_bind()
3429 if (!wcd938x->regmap) { in wcd938x_bind()
3431 ret = -EINVAL; in wcd938x_bind()
3441 wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq; in wcd938x_bind()
3442 wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq; in wcd938x_bind()
3453 dev_err(dev, "%s: Codec registration failed\n", in wcd938x_bind()
3461 device_link_remove(dev, wcd938x->rxdev); in wcd938x_bind()
3463 device_link_remove(dev, wcd938x->txdev); in wcd938x_bind()
3465 device_link_remove(wcd938x->rxdev, wcd938x->txdev); in wcd938x_bind()
3467 put_device(wcd938x->txdev); in wcd938x_bind()
3469 put_device(wcd938x->rxdev); in wcd938x_bind()
3481 device_link_remove(dev, wcd938x->txdev); in wcd938x_unbind()
3482 device_link_remove(dev, wcd938x->rxdev); in wcd938x_unbind()
3483 device_link_remove(wcd938x->rxdev, wcd938x->txdev); in wcd938x_unbind()
3484 put_device(wcd938x->txdev); in wcd938x_unbind()
3485 put_device(wcd938x->rxdev); in wcd938x_unbind()
3500 np = dev->of_node; in wcd938x_add_slave_components()
3502 wcd938x->rxnode = of_parse_phandle(np, "qcom,rx-device", 0); in wcd938x_add_slave_components()
3503 if (!wcd938x->rxnode) { in wcd938x_add_slave_components()
3504 dev_err(dev, "%s: Rx-device node not defined\n", __func__); in wcd938x_add_slave_components()
3505 return -ENODEV; in wcd938x_add_slave_components()
3508 of_node_get(wcd938x->rxnode); in wcd938x_add_slave_components()
3510 component_compare_of, wcd938x->rxnode); in wcd938x_add_slave_components()
3512 wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0); in wcd938x_add_slave_components()
3513 if (!wcd938x->txnode) { in wcd938x_add_slave_components()
3514 dev_err(dev, "%s: Tx-device node not defined\n", __func__); in wcd938x_add_slave_components()
3515 return -ENODEV; in wcd938x_add_slave_components()
3517 of_node_get(wcd938x->txnode); in wcd938x_add_slave_components()
3519 component_compare_of, wcd938x->txnode); in wcd938x_add_slave_components()
3527 struct device *dev = &pdev->dev; in wcd938x_probe()
3533 return -ENOMEM; in wcd938x_probe()
3536 mutex_init(&wcd938x->micb_lock); in wcd938x_probe()
3562 regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_probe()
3563 regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_probe()
3570 struct device *dev = &pdev->dev; in wcd938x_remove()
3579 regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_remove()
3580 regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); in wcd938x_remove()
3585 { .compatible = "qcom,wcd9380-codec" },
3586 { .compatible = "qcom,wcd9385-codec" },
3603 MODULE_DESCRIPTION("WCD938X Codec driver");