Lines Matching +full:int +full:- +full:comp +full:- +full:resistor
1 // SPDX-License-Identifier: GPL-2.0
6 #include <linux/clk-provider.h>
21 #include <sound/soc-dapm.h>
23 #include "wcd-clsh-v2.h"
24 #include "wcd-mbhc-v2.h"
26 #include <dt-bindings/sound/qcom,wcd934x.h>
156 {"RX INT" #id "_1 MIX1 INP0", "RX0", "SLIM RX0"}, \
157 {"RX INT" #id "_1 MIX1 INP0", "RX1", "SLIM RX1"}, \
158 {"RX INT" #id "_1 MIX1 INP0", "RX2", "SLIM RX2"}, \
159 {"RX INT" #id "_1 MIX1 INP0", "RX3", "SLIM RX3"}, \
160 {"RX INT" #id "_1 MIX1 INP0", "RX4", "SLIM RX4"}, \
161 {"RX INT" #id "_1 MIX1 INP0", "RX5", "SLIM RX5"}, \
162 {"RX INT" #id "_1 MIX1 INP0", "RX6", "SLIM RX6"}, \
163 {"RX INT" #id "_1 MIX1 INP0", "RX7", "SLIM RX7"}, \
164 {"RX INT" #id "_1 MIX1 INP0", "IIR0", "IIR0"}, \
165 {"RX INT" #id "_1 MIX1 INP0", "IIR1", "IIR1"}, \
166 {"RX INT" #id "_1 MIX1 INP1", "RX0", "SLIM RX0"}, \
167 {"RX INT" #id "_1 MIX1 INP1", "RX1", "SLIM RX1"}, \
168 {"RX INT" #id "_1 MIX1 INP1", "RX2", "SLIM RX2"}, \
169 {"RX INT" #id "_1 MIX1 INP1", "RX3", "SLIM RX3"}, \
170 {"RX INT" #id "_1 MIX1 INP1", "RX4", "SLIM RX4"}, \
171 {"RX INT" #id "_1 MIX1 INP1", "RX5", "SLIM RX5"}, \
172 {"RX INT" #id "_1 MIX1 INP1", "RX6", "SLIM RX6"}, \
173 {"RX INT" #id "_1 MIX1 INP1", "RX7", "SLIM RX7"}, \
174 {"RX INT" #id "_1 MIX1 INP1", "IIR0", "IIR0"}, \
175 {"RX INT" #id "_1 MIX1 INP1", "IIR1", "IIR1"}, \
176 {"RX INT" #id "_1 MIX1 INP2", "RX0", "SLIM RX0"}, \
177 {"RX INT" #id "_1 MIX1 INP2", "RX1", "SLIM RX1"}, \
178 {"RX INT" #id "_1 MIX1 INP2", "RX2", "SLIM RX2"}, \
179 {"RX INT" #id "_1 MIX1 INP2", "RX3", "SLIM RX3"}, \
180 {"RX INT" #id "_1 MIX1 INP2", "RX4", "SLIM RX4"}, \
181 {"RX INT" #id "_1 MIX1 INP2", "RX5", "SLIM RX5"}, \
182 {"RX INT" #id "_1 MIX1 INP2", "RX6", "SLIM RX6"}, \
183 {"RX INT" #id "_1 MIX1 INP2", "RX7", "SLIM RX7"}, \
184 {"RX INT" #id "_1 MIX1 INP2", "IIR0", "IIR0"}, \
185 {"RX INT" #id "_1 MIX1 INP2", "IIR1", "IIR1"}, \
186 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP0"}, \
187 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP1"}, \
188 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP2"}, \
189 {"RX INT" #id "_2 MUX", "RX0", "SLIM RX0"}, \
190 {"RX INT" #id "_2 MUX", "RX1", "SLIM RX1"}, \
191 {"RX INT" #id "_2 MUX", "RX2", "SLIM RX2"}, \
192 {"RX INT" #id "_2 MUX", "RX3", "SLIM RX3"}, \
193 {"RX INT" #id "_2 MUX", "RX4", "SLIM RX4"}, \
194 {"RX INT" #id "_2 MUX", "RX5", "SLIM RX5"}, \
195 {"RX INT" #id "_2 MUX", "RX6", "SLIM RX6"}, \
196 {"RX INT" #id "_2 MUX", "RX7", "SLIM RX7"}, \
197 {"RX INT" #id "_2 MUX", NULL, "INT" #id "_CLK"}, \
198 {"RX INT" #id "_2 MUX", NULL, "DSMDEM" #id "_CLK"}, \
199 {"RX INT" #id "_2 INTERP", NULL, "RX INT" #id "_2 MUX"}, \
200 {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_2 INTERP"}, \
201 {"RX INT" #id "_1 INTERP", NULL, "RX INT" #id "_1 MIX1"}, \
202 {"RX INT" #id "_1 INTERP", NULL, "INT" #id "_CLK"}, \
203 {"RX INT" #id "_1 INTERP", NULL, "DSMDEM" #id "_CLK"}, \
204 {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_1 INTERP"}
207 {"RX INT" #id " MIX2", NULL, "RX INT" #id " SEC MIX"}, \
208 {"RX INT" #id " MIX2", NULL, "RX INT" #id " MIX2 INP"}
433 COMPANDER_5, /* LO3_SE - not used in Tavil */
434 COMPANDER_6, /* LO4_SE - not used in Tavil */
470 int sample_rate;
471 int rate_val;
505 .name = "WCD9335-IFC-DEV",
537 int rate;
540 int num_rx_port;
541 int num_tx_port;
544 int sido_input_src;
545 int dmic_0_1_clk_cnt;
546 int dmic_2_3_clk_cnt;
547 int dmic_4_5_clk_cnt;
548 int dmic_sample_rate;
549 int comp_enabled[COMPANDER_MAX];
550 int sysclk_users;
566 unsigned int iir_idx;
567 unsigned int band_idx;
571 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
587 "Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB",
588 "Class-H Hi-Fi Low Power"
1254 static int wcd934x_set_sido_input_src(struct wcd934x_codec *wcd, int sido_src)
1256 if (sido_src == wcd->sido_input_src)
1260 regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO,
1265 wcd->sido_input_src = sido_src;
1270 static int wcd934x_enable_ana_bias_and_sysclk(struct wcd934x_codec *wcd)
1272 mutex_lock(&wcd->sysclk_mutex);
1274 if (++wcd->sysclk_users != 1) {
1275 mutex_unlock(&wcd->sysclk_mutex);
1278 mutex_unlock(&wcd->sysclk_mutex);
1280 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
1283 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
1287 * 1ms delay is required after pre-charge is enabled
1291 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
1293 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
1301 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
1304 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
1307 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
1310 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
1312 regmap_update_bits(wcd->regmap,
1316 regmap_update_bits(wcd->regmap,
1320 regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_GATE,
1333 static int wcd934x_disable_ana_bias_and_syclk(struct wcd934x_codec *wcd)
1335 mutex_lock(&wcd->sysclk_mutex);
1336 if (--wcd->sysclk_users != 0) {
1337 mutex_unlock(&wcd->sysclk_mutex);
1340 mutex_unlock(&wcd->sysclk_mutex);
1342 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
1345 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
1347 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
1353 static int __wcd934x_cdc_mclk_enable(struct wcd934x_codec *wcd, bool enable)
1355 int ret = 0;
1358 ret = clk_prepare_enable(wcd->extclk);
1361 dev_err(wcd->dev, "%s: ext clk enable failed\n",
1367 int val;
1369 regmap_read(wcd->regmap, WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL,
1377 clk_disable_unprepare(wcd->extclk);
1383 static int wcd934x_codec_enable_mclk(struct snd_soc_dapm_widget *w,
1384 struct snd_kcontrol *kc, int event)
1386 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
1387 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
1399 static int wcd934x_get_version(struct wcd934x_codec *wcd)
1401 int val1, val2, ver, ret;
1406 regmap = wcd->regmap;
1436 wcd->version = ver;
1437 dev_info(wcd->dev, "WCD934X Minor:0x%x Version:0x%x\n", id_minor, ver);
1444 int rc, val;
1448 regmap_update_bits(wcd->regmap,
1452 regmap_update_bits(wcd->regmap,
1463 rc = regmap_read(wcd->regmap,
1472 static int wcd934x_swrm_clock(struct wcd934x_codec *wcd, bool enable)
1476 regmap_update_bits(wcd->regmap,
1481 regmap_update_bits(wcd->regmap,
1490 static int wcd934x_set_prim_interpolator_rate(struct snd_soc_dai *dai,
1493 struct snd_soc_component *comp = dai->component;
1494 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
1497 int inp, j;
1499 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
1500 inp = ch->shift + INTn_1_INP_SEL_RX0;
1511 cfg0 = snd_soc_component_read(comp,
1513 cfg1 = snd_soc_component_read(comp,
1532 dev_err(wcd->dev,
1533 "Cannot set 44.1KHz on INT%d\n",
1536 snd_soc_component_update_bits(comp,
1547 static int wcd934x_set_mix_interpolator_rate(struct snd_soc_dai *dai,
1548 int rate_val, u32 rate)
1550 struct snd_soc_component *component = dai->component;
1551 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
1553 int val, j;
1555 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
1564 if (val == (ch->shift + INTn_2_INP_SEL_RX0)) {
1572 dev_err(component->dev,
1574 dai->id);
1575 return -EINVAL;
1589 static int wcd934x_set_interpolator_rate(struct snd_soc_dai *dai,
1592 int rate_val = 0;
1593 int i, ret;
1602 dev_err(dai->dev, "Unsupported sample rate: %d\n", sample_rate);
1603 return -EINVAL;
1616 static int wcd934x_set_decimator_rate(struct snd_soc_dai *dai,
1619 struct snd_soc_component *comp = dai->component;
1620 struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp);
1623 int tx_port, tx_port_reg;
1624 int decimator = -1;
1626 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
1627 tx_port = ch->port;
1628 /* Find the SB TX MUX input - which decimator is connected */
1637 shift = ((tx_port - 4) << 1);
1642 shift = ((tx_port - 8) << 1);
1656 dev_err(wcd->dev, "Invalid SLIM TX%u port DAI ID:%d\n",
1657 tx_port, dai->id);
1658 return -EINVAL;
1661 tx_mux_sel = snd_soc_component_read(comp, tx_port_reg) &
1676 decimator = tx_mux_sel - 1;
1683 dev_err(wcd->dev, "ERROR: Invalid tx_port: %d\n",
1685 return -EINVAL;
1688 snd_soc_component_update_bits(comp,
1697 static int wcd934x_slim_set_hw_params(struct wcd934x_codec *wcd,
1699 int direction)
1701 struct list_head *slim_ch_list = &dai_data->slim_ch_list;
1702 struct slim_stream_config *cfg = &dai_data->sconfig;
1705 int ret, i;
1707 cfg->ch_count = 0;
1708 cfg->direction = direction;
1709 cfg->port_mask = 0;
1713 cfg->ch_count++;
1714 payload |= 1 << ch->shift;
1715 cfg->port_mask |= BIT(ch->port);
1718 cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL);
1719 if (!cfg->chs)
1720 return -ENOMEM;
1724 cfg->chs[i++] = ch->ch_num;
1727 ret = regmap_write(wcd->if_regmap,
1728 WCD934X_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port),
1735 ret = regmap_write(wcd->if_regmap,
1736 WCD934X_SLIM_PGD_RX_PORT_CFG(ch->port),
1741 ret = regmap_write(wcd->if_regmap,
1742 WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_0(ch->port),
1748 ret = regmap_write(wcd->if_regmap,
1749 WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_1(ch->port),
1755 ret = regmap_write(wcd->if_regmap,
1756 WCD934X_SLIM_PGD_TX_PORT_CFG(ch->port),
1764 dai_data->sruntime = slim_stream_allocate(wcd->sdev, "WCD934x-SLIM");
1769 dev_err(wcd->dev, "Error Setting slim hw params\n");
1770 kfree(cfg->chs);
1771 cfg->chs = NULL;
1776 static int wcd934x_hw_params(struct snd_pcm_substream *substream,
1781 int ret, tx_fs_rate = 0;
1783 wcd = snd_soc_component_get_drvdata(dai->component);
1785 switch (substream->stream) {
1789 dev_err(wcd->dev, "cannot set sample rate: %u\n",
1795 wcd->dai[dai->id].sconfig.bps = params_width(params);
1798 dev_err(wcd->dev, "Invalid format 0x%x\n",
1800 return -EINVAL;
1828 dev_err(wcd->dev, "Invalid TX sample rate: %d\n",
1830 return -EINVAL;
1837 dev_err(wcd->dev, "Cannot set TX Decimator rate\n");
1842 wcd->dai[dai->id].sconfig.bps = params_width(params);
1845 dev_err(wcd->dev, "Invalid format 0x%x\n",
1847 return -EINVAL;
1851 dev_err(wcd->dev, "Invalid stream type %d\n",
1852 substream->stream);
1853 return -EINVAL;
1856 wcd->dai[dai->id].sconfig.rate = params_rate(params);
1858 return wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
1861 static int wcd934x_hw_free(struct snd_pcm_substream *substream,
1867 wcd = snd_soc_component_get_drvdata(dai->component);
1869 dai_data = &wcd->dai[dai->id];
1871 kfree(dai_data->sconfig.chs);
1876 static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd,
1883 wcd = snd_soc_component_get_drvdata(dai->component);
1885 dai_data = &wcd->dai[dai->id];
1891 cfg = &dai_data->sconfig;
1892 slim_stream_prepare(dai_data->sruntime, cfg);
1893 slim_stream_enable(dai_data->sruntime);
1898 slim_stream_disable(dai_data->sruntime);
1899 slim_stream_unprepare(dai_data->sruntime);
1908 static int wcd934x_set_channel_map(struct snd_soc_dai *dai,
1909 unsigned int tx_num,
1910 const unsigned int *tx_slot,
1911 unsigned int rx_num,
1912 const unsigned int *rx_slot)
1915 int i;
1917 wcd = snd_soc_component_get_drvdata(dai->component);
1920 dev_err(wcd->dev, "Invalid tx %d or rx %d channel count\n",
1922 return -EINVAL;
1926 dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n",
1928 return -EINVAL;
1931 wcd->num_rx_port = rx_num;
1933 wcd->rx_chs[i].ch_num = rx_slot[i];
1934 INIT_LIST_HEAD(&wcd->rx_chs[i].list);
1937 wcd->num_tx_port = tx_num;
1939 wcd->tx_chs[i].ch_num = tx_slot[i];
1940 INIT_LIST_HEAD(&wcd->tx_chs[i].list);
1946 static int wcd934x_get_channel_map(const struct snd_soc_dai *dai,
1947 unsigned int *tx_num, unsigned int *tx_slot,
1948 unsigned int *rx_num, unsigned int *rx_slot)
1952 int i = 0;
1954 wcd = snd_soc_component_get_drvdata(dai->component);
1956 switch (dai->id) {
1962 dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n",
1964 return -EINVAL;
1967 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
1968 rx_slot[i++] = ch->ch_num;
1976 dev_err(wcd->dev, "Invalid tx_slot %p or tx_num %p\n",
1978 return -EINVAL;
1981 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
1982 tx_slot[i++] = ch->ch_num;
1987 dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id);
2103 static int swclk_gate_enable(struct clk_hw *hw)
2113 static int swclk_gate_is_enabled(struct clk_hw *hw)
2116 int ret, val;
2118 regmap_read(wcd->regmap, WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, &val);
2140 struct clk *parent = wcd->extclk;
2141 struct device *dev = wcd->dev;
2142 struct device_node *np = dev->parent->of_node;
2147 int ret;
2149 if (of_property_read_u32(np, "clock-frequency", &wcd->rate))
2154 of_property_read_string(np, "clock-output-names", &clk_name);
2161 wcd->hw.init = &init;
2163 hw = &wcd->hw;
2164 ret = devm_clk_hw_register(wcd->dev->parent, hw);
2175 static int wcd934x_get_micbias_val(struct device *dev, const char *micbias,
2178 int mv;
2180 if (of_property_read_u32(dev->parent->of_node, micbias, &mv)) {
2197 return (mv - 1000) / 50;
2200 static int wcd934x_init_dmic(struct snd_soc_component *comp)
2202 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
2203 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
2206 vout_ctl_1 = wcd934x_get_micbias_val(comp->dev,
2207 "qcom,micbias1-microvolt", NULL);
2208 vout_ctl_2 = wcd934x_get_micbias_val(comp->dev,
2209 "qcom,micbias2-microvolt",
2210 &wcd->micb2_mv);
2211 vout_ctl_3 = wcd934x_get_micbias_val(comp->dev,
2212 "qcom,micbias3-microvolt", NULL);
2213 vout_ctl_4 = wcd934x_get_micbias_val(comp->dev,
2214 "qcom,micbias4-microvolt", NULL);
2216 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB1,
2218 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB2,
2220 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB3,
2222 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB4,
2225 if (wcd->rate == WCD934X_MCLK_CLK_9P6MHZ)
2230 wcd->dmic_sample_rate = def_dmic_rate;
2233 snd_soc_component_update_bits(comp, WCD934X_TEST_DEBUG_PAD_DRVCTL_0,
2241 struct regmap *rm = wcd->regmap;
2251 static int wcd934x_comp_init(struct snd_soc_component *component)
2253 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
2262 static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
2266 unsigned int i, j, port_id;
2267 unsigned int val, int_val = 0;
2274 regmap_read(wcd->if_regmap, i, &val);
2284 port_id = j - 16;
2287 regmap_read(wcd->if_regmap,
2296 regmap_read(wcd->if_regmap, reg, &int_val);
2300 dev_err_ratelimited(wcd->dev,
2305 dev_err_ratelimited(wcd->dev,
2318 wcd->if_regmap, reg, &int_val);
2321 regmap_write(wcd->if_regmap,
2327 dev_err_ratelimited(wcd->dev,
2331 regmap_write(wcd->if_regmap,
2355 int *btn_low, int *btn_high,
2356 int num_btn, bool is_micbias)
2358 int i, vth;
2361 dev_err(component->dev, "%s: invalid number of buttons: %d\n",
2373 static bool wcd934x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num)
2399 static int wcd934x_micbias_control(struct snd_soc_component *component,
2400 int micb_num, int req, bool is_dapm)
2403 int micb_index = micb_num - 1;
2420 dev_err(component->dev, "%s: Invalid micbias number: %d\n",
2422 return -EINVAL;
2424 mutex_lock(&wcd934x->micb_lock);
2428 wcd934x->pullup_ref[micb_index]++;
2429 if ((wcd934x->pullup_ref[micb_index] == 1) &&
2430 (wcd934x->micb_ref[micb_index] == 0))
2436 if (wcd934x->pullup_ref[micb_index] > 0)
2437 wcd934x->pullup_ref[micb_index]--;
2439 if ((wcd934x->pullup_ref[micb_index] == 0) &&
2440 (wcd934x->micb_ref[micb_index] == 0))
2445 wcd934x->micb_ref[micb_index]++;
2446 if (wcd934x->micb_ref[micb_index] == 1) {
2451 wcd_mbhc_event_notify(wcd934x->mbhc,
2456 wcd_mbhc_event_notify(wcd934x->mbhc,
2460 if (wcd934x->micb_ref[micb_index] > 0)
2461 wcd934x->micb_ref[micb_index]--;
2463 if ((wcd934x->micb_ref[micb_index] == 0) &&
2464 (wcd934x->pullup_ref[micb_index] > 0))
2468 else if ((wcd934x->micb_ref[micb_index] == 0) &&
2469 (wcd934x->pullup_ref[micb_index] == 0)) {
2471 wcd_mbhc_event_notify(wcd934x->mbhc,
2477 wcd_mbhc_event_notify(wcd934x->mbhc,
2481 wcd_mbhc_event_notify(wcd934x->mbhc,
2486 mutex_unlock(&wcd934x->micb_lock);
2491 static int wcd934x_mbhc_request_micbias(struct snd_soc_component *component,
2492 int micb_num, int req)
2494 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
2495 int ret;
2524 static int wcd934x_get_micb_vout_ctl_val(u32 micb_mv)
2528 return -EINVAL;
2530 return (micb_mv - 1000) / 50;
2533 static int wcd934x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
2534 int req_volt, int micb_num)
2537 int cur_vout_ctl, req_vout_ctl, micb_reg, micb_en, ret = 0;
2553 return -EINVAL;
2555 mutex_lock(&wcd934x->micb_lock);
2560 * to avoid slow micbias ramp-up or down enable pull-up
2561 * momentarily, change the micbias value and then re-enable
2571 ret = -EINVAL;
2600 mutex_unlock(&wcd934x->micb_lock);
2604 static int wcd934x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component,
2605 int micb_num, bool req_en)
2608 int rc, micb_mv;
2611 return -EINVAL;
2617 if (wcd934x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
2620 micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd934x->micb2_mv;
2631 int i;
2632 int val, val1;
2636 static const int minCode_param[] = {
2640 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ZDET, 0x20, 0x20);
2642 regmap_read(wcd934x->regmap, WCD934X_ANA_MBHC_RESULT_2, &val);
2647 regmap_read(wcd934x->regmap, WCD934X_ANA_MBHC_RESULT_1, &val1);
2649 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ZDET, 0x20, 0x00);
2657 dev_err(wcd934x->dev, "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
2662 denom = (x1 * d1) - (1 << (14 - noff));
2668 dev_dbg(wcd934x->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%di (milliohm)\n",
2674 regmap_read(wcd934x->regmap, WCD934X_ANA_MBHC_RESULT_1, &val);
2675 regmap_read(wcd934x->regmap, WCD934X_ANA_MBHC_RESULT_2, &val1);
2689 struct wcd934x_codec *wcd934x = dev_get_drvdata(component->dev);
2693 WCD934X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl);
2695 WCD934X_VTH_MASK, zdet_param->btn5);
2697 WCD934X_VTH_MASK, zdet_param->btn6);
2699 WCD934X_VTH_MASK, zdet_param->btn7);
2701 WCD934X_ZDET_RANGE_CTL_MASK, zdet_param->noff);
2703 0x0F, zdet_param->nshift);
2708 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ZDET, 0x80, 0x80);
2709 wcd934x_mbhc_get_result_params(wcd934x, d1_a, zdet_param->noff, &zdet);
2710 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ZDET, 0x80, 0x00);
2718 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ZDET, 0x40, 0x40);
2719 wcd934x_mbhc_get_result_params(wcd934x, d1_a, zdet_param->noff, &zdet);
2720 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ZDET, 0x40, 0x00);
2726 int32_t *z_val, int flag_l_r)
2729 int q1_cal;
2738 q1_cal = (10000 - ((q1 & 0x7F) * 25));
2748 struct wcd934x_codec *wcd934x = dev_get_drvdata(component->dev);
2751 int zMono, z_diff1, z_diff2;
2776 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ELECT, 0x80, 0x00);
2779 /* For NO-jack, disable L_DET_EN before Z-det measurements */
2780 if (wcd934x->mbhc_cfg.hphl_swh)
2781 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_MECH, 0x80, 0x00);
2784 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_MECH, 0x01, 0x00);
2818 dev_info(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
2825 (zdet_param_ptr->noff == 0x6)) ||
2850 dev_err(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
2856 dev_dbg(component->dev,
2865 dev_dbg(component->dev,
2868 wcd_mbhc_set_hph_type(wcd934x->mbhc, WCD_MBHC_HPH_MONO);
2885 /* Parallel of left Z and 9 ohm pull down resistor */
2887 z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
2888 z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
2890 dev_err(component->dev, "%s: stereo plug type detected\n",
2892 wcd_mbhc_set_hph_type(wcd934x->mbhc, WCD_MBHC_HPH_STEREO);
2894 dev_err(component->dev, "%s: MONO plug type detected\n",
2896 wcd_mbhc_set_hph_type(wcd934x->mbhc, WCD_MBHC_HPH_MONO);
2904 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_MECH, 0x01, 0x01);
2906 /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
2907 if (wcd934x->mbhc_cfg.hphl_swh)
2908 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_MECH, 0x80, 0x80);
2913 regmap_update_bits(wcd934x->regmap, WCD934X_ANA_MBHC_ELECT, 0x80, 0x80);
2955 static int wcd934x_get_hph_type(struct snd_kcontrol *kcontrol,
2961 ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd->mbhc);
2966 static int wcd934x_hph_impedance_get(struct snd_kcontrol *kcontrol,
2975 mc = (struct soc_mixer_control *)(kcontrol->private_value);
2976 hphr = mc->shift;
2977 wcd_mbhc_get_impedance(wcd->mbhc, &zl, &zr);
2978 dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
2979 ucontrol->value.integer.value[0] = hphr ? zr : zl;
2995 static int wcd934x_mbhc_init(struct snd_soc_component *component)
2997 struct wcd934x_ddata *data = dev_get_drvdata(component->dev->parent);
2999 struct wcd_mbhc_intr *intr_ids = &wcd->intr_ids;
3001 intr_ids->mbhc_sw_intr = regmap_irq_get_virq(data->irq_data,
3003 intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(data->irq_data,
3005 intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(data->irq_data,
3007 intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(data->irq_data,
3009 intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(data->irq_data,
3011 intr_ids->hph_left_ocp = regmap_irq_get_virq(data->irq_data,
3013 intr_ids->hph_right_ocp = regmap_irq_get_virq(data->irq_data,
3016 wcd->mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
3017 if (IS_ERR(wcd->mbhc)) {
3018 wcd->mbhc = NULL;
3019 return -EINVAL;
3034 if (!wcd->mbhc)
3037 wcd_mbhc_deinit(wcd->mbhc);
3040 static int wcd934x_comp_probe(struct snd_soc_component *component)
3042 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
3043 int i;
3045 snd_soc_component_init_regmap(component, wcd->regmap);
3046 wcd->component = component;
3048 /* Class-H Init*/
3049 wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, wcd->version);
3050 if (IS_ERR(wcd->clsh_ctrl))
3051 return PTR_ERR(wcd->clsh_ctrl);
3053 /* Default HPH Mode to Class-H Low HiFi */
3054 wcd->hph_mode = CLS_H_LOHIFI;
3059 INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
3064 dev_err(component->dev, "Failed to Initialize MBHC\n");
3069 static void wcd934x_comp_remove(struct snd_soc_component *comp)
3071 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
3073 wcd934x_mbhc_deinit(comp);
3074 wcd_clsh_ctrl_free(wcd->clsh_ctrl);
3077 static int wcd934x_comp_set_sysclk(struct snd_soc_component *comp,
3078 int clk_id, int source,
3079 unsigned int freq, int dir)
3081 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
3082 int val = WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ;
3084 wcd->rate = freq;
3086 if (wcd->rate == WCD934X_MCLK_CLK_12P288MHZ)
3089 snd_soc_component_update_bits(comp, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
3093 return clk_set_rate(wcd->extclk, freq);
3097 int iir_idx, int band_idx, int coeff_idx)
3100 int reg, b2_reg;
3131 int iir_idx, int band_idx, uint32_t value)
3133 int reg = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
3138 /* Mask top 2 bits, 7-8 are reserved */
3142 static int wcd934x_put_iir_band_audio_mixer(
3149 (struct wcd_iir_filter_ctl *)kcontrol->private_value;
3150 struct soc_bytes_ext *params = &ctl->bytes_ext;
3151 int iir_idx = ctl->iir_idx;
3152 int band_idx = ctl->band_idx;
3154 int reg = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx;
3156 memcpy(&coeff[0], ucontrol->value.bytes.data, params->max);
3172 static int wcd934x_get_iir_band_audio_mixer(struct snd_kcontrol *kcontrol,
3178 (struct wcd_iir_filter_ctl *)kcontrol->private_value;
3179 struct soc_bytes_ext *params = &ctl->bytes_ext;
3180 int iir_idx = ctl->iir_idx;
3181 int band_idx = ctl->band_idx;
3190 memcpy(ucontrol->value.bytes.data, &coeff[0], params->max);
3195 static int wcd934x_iir_filter_info(struct snd_kcontrol *kcontrol,
3199 (struct wcd_iir_filter_ctl *)kcontrol->private_value;
3200 struct soc_bytes_ext *params = &ctl->bytes_ext;
3202 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES;
3203 ucontrol->count = params->max;
3208 static int wcd934x_compander_get(struct snd_kcontrol *kc,
3212 int comp = ((struct soc_mixer_control *)kc->private_value)->shift;
3213 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
3215 ucontrol->value.integer.value[0] = wcd->comp_enabled[comp];
3220 static int wcd934x_compander_set(struct snd_kcontrol *kc,
3224 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
3225 int comp = ((struct soc_mixer_control *)kc->private_value)->shift;
3226 int value = ucontrol->value.integer.value[0];
3227 int sel;
3229 if (wcd->comp_enabled[comp] == value)
3232 wcd->comp_enabled[comp] = value;
3237 switch (comp) {
3261 static int wcd934x_rx_hph_mode_get(struct snd_kcontrol *kc,
3265 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
3267 ucontrol->value.enumerated.item[0] = wcd->hph_mode;
3272 static int wcd934x_rx_hph_mode_put(struct snd_kcontrol *kc,
3276 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
3279 mode_val = ucontrol->value.enumerated.item[0];
3281 if (mode_val == wcd->hph_mode)
3285 dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n");
3288 wcd->hph_mode = mode_val;
3293 static int slim_rx_mux_get(struct snd_kcontrol *kc,
3298 struct wcd934x_codec *wcd = dev_get_drvdata(dapm->dev);
3300 ucontrol->value.enumerated.item[0] = wcd->rx_port_value[w->shift];
3305 static int slim_rx_mux_to_dai_id(int mux)
3307 int aif_id;
3323 aif_id = -1;
3330 static int slim_rx_mux_put(struct snd_kcontrol *kc,
3334 struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev);
3335 struct soc_enum *e = (struct soc_enum *)kc->private_value;
3338 u32 port_id = w->shift;
3340 int mux_idx;
3341 int prev_mux_idx = wcd->rx_port_value[port_id];
3342 int aif_id;
3344 mux_idx = ucontrol->value.enumerated.item[0];
3355 list_for_each_entry_safe(ch, c, &wcd->dai[aif_id].slim_ch_list, list) {
3356 if (ch->port == port_id + WCD934X_RX_START) {
3358 list_del_init(&ch->list);
3371 if (list_empty(&wcd->rx_chs[port_id].list)) {
3372 list_add_tail(&wcd->rx_chs[port_id].list,
3373 &wcd->dai[aif_id].slim_ch_list);
3375 dev_err(wcd->dev ,"SLIM_RX%d PORT is busy\n", port_id);
3381 dev_err(wcd->dev, "Unknown AIF %d\n", mux_idx);
3385 wcd->rx_port_value[port_id] = mux_idx;
3386 snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id],
3391 return -EINVAL;
3394 static int wcd934x_int_dem_inp_mux_put(struct snd_kcontrol *kc,
3397 struct soc_enum *e = (struct soc_enum *)kc->private_value;
3399 int reg, val;
3402 val = ucontrol->value.enumerated.item[0];
3403 if (e->reg == WCD934X_CDC_RX0_RX_PATH_SEC0)
3405 else if (e->reg == WCD934X_CDC_RX1_RX_PATH_SEC0)
3407 else if (e->reg == WCD934X_CDC_RX2_RX_PATH_SEC0)
3410 return -EINVAL;
3425 static int wcd934x_dec_enum_put(struct snd_kcontrol *kcontrol,
3428 struct snd_soc_component *comp;
3429 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3430 unsigned int val;
3434 comp = snd_soc_dapm_kcontrol_component(kcontrol);
3436 val = ucontrol->value.enumerated.item[0];
3437 if (val > e->items - 1)
3438 return -EINVAL;
3440 switch (e->reg) {
3442 if (e->shift_l == 0)
3444 else if (e->shift_l == 2)
3446 else if (e->shift_l == 4)
3450 if (e->shift_l == 0)
3452 else if (e->shift_l == 2)
3456 if (e->shift_l == 0)
3458 else if (e->shift_l == 2)
3462 if (e->shift_l == 0)
3464 else if (e->shift_l == 2)
3468 dev_err(comp->dev, "%s: e->reg: 0x%x not expected\n",
3469 __func__, e->reg);
3470 return -EINVAL;
3476 snd_soc_component_update_bits(comp, mic_sel_reg, BIT(7),
3810 static int slim_tx_mixer_get(struct snd_kcontrol *kc,
3814 struct wcd934x_codec *wcd = dev_get_drvdata(dapm->dev);
3816 (struct soc_mixer_control *)kc->private_value;
3817 int port_id = mixer->shift;
3819 ucontrol->value.integer.value[0] = wcd->tx_port_value[port_id];
3824 static int slim_tx_mixer_put(struct snd_kcontrol *kc,
3828 struct wcd934x_codec *wcd = dev_get_drvdata(widget->dapm->dev);
3831 (struct soc_mixer_control *)kc->private_value;
3832 int enable = ucontrol->value.integer.value[0];
3834 int dai_id = widget->shift;
3835 int port_id = mixer->shift;
3838 if (enable == wcd->tx_port_value[port_id])
3842 if (list_empty(&wcd->tx_chs[port_id].list)) {
3843 list_add_tail(&wcd->tx_chs[port_id].list,
3844 &wcd->dai[dai_id].slim_ch_list);
3846 dev_err(wcd->dev ,"SLIM_TX%d PORT is busy\n", port_id);
3852 list_for_each_entry_safe(ch, c, &wcd->dai[dai_id].slim_ch_list, list) {
3853 if (ch->port == port_id) {
3855 list_del_init(&wcd->tx_chs[port_id].list);
3863 wcd->tx_port_value[port_id] = enable;
3864 snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update);
3972 -84, 40, digital_gain), /* -84dB min - 40dB max */
3974 -84, 40, digital_gain),
3976 -84, 40, digital_gain),
3978 -84, 40, digital_gain),
3980 -84, 40, digital_gain),
3982 -84, 40, digital_gain),
3984 -84, 40, digital_gain),
3987 -84, 40, digital_gain),
3990 -84, 40, digital_gain),
3993 -84, 40, digital_gain),
3996 -84, 40, digital_gain),
3999 -84, 40, digital_gain),
4002 -84, 40, digital_gain),
4005 -84, 40, digital_gain),
4008 -84, 40, digital_gain),
4010 -84, 40, digital_gain),
4012 -84, 40, digital_gain),
4014 -84, 40, digital_gain),
4016 -84, 40, digital_gain),
4018 -84, 40, digital_gain),
4020 -84, 40, digital_gain),
4022 -84, 40, digital_gain),
4024 -84, 40, digital_gain),
4027 WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40,
4030 WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40,
4033 WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40,
4036 WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40,
4039 WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40,
4042 WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40,
4045 WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40,
4048 WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40,
4128 int port_num = 0;
4130 unsigned int val = 0;
4131 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
4134 list_for_each_entry(ch, &dai->slim_ch_list, list) {
4135 if (ch->port >= WCD934X_RX_START) {
4136 port_num = ch->port - WCD934X_RX_START;
4139 port_num = ch->port;
4143 regmap_read(wcd->if_regmap, reg, &val);
4145 regmap_write(wcd->if_regmap, reg,
4150 static int wcd934x_codec_enable_slim(struct snd_soc_dapm_widget *w,
4151 struct snd_kcontrol *kc, int event)
4153 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4154 struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp);
4155 struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift];
4159 wcd934x_codec_enable_int_port(dai, comp);
4167 u16 interp_idx, int event)
4204 static void wcd934x_codec_hphdelay_lutbypass(struct snd_soc_component *comp,
4205 u16 interp_idx, int event)
4224 snd_soc_component_update_bits(comp, WCD934X_CDC_CLSH_TEST0,
4226 snd_soc_component_update_bits(comp, hph_lut_bypass_reg,
4232 snd_soc_component_update_bits(comp, WCD934X_CDC_CLSH_TEST0,
4234 snd_soc_component_update_bits(comp, hph_lut_bypass_reg,
4240 static int wcd934x_config_compander(struct snd_soc_component *comp,
4241 int interp_n, int event)
4243 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
4244 int compander;
4251 compander = interp_n - 1;
4252 if (!wcd->comp_enabled[compander])
4261 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4264 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4267 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4270 snd_soc_component_update_bits(comp, rx_path_cfg0_reg,
4275 snd_soc_component_update_bits(comp, rx_path_cfg0_reg,
4278 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4281 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4284 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4287 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4289 snd_soc_component_update_bits(comp, comp_ctl0_reg,
4297 static int wcd934x_codec_enable_interp_clk(struct snd_soc_dapm_widget *w,
4298 struct snd_kcontrol *kc, int event)
4300 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4301 int interp_idx = w->shift;
4307 snd_soc_component_update_bits(comp, main_reg,
4310 wcd934x_codec_hd2_control(comp, interp_idx, event);
4311 wcd934x_codec_hphdelay_lutbypass(comp, interp_idx, event);
4312 wcd934x_config_compander(comp, interp_idx, event);
4315 wcd934x_config_compander(comp, interp_idx, event);
4316 wcd934x_codec_hphdelay_lutbypass(comp, interp_idx, event);
4317 wcd934x_codec_hd2_control(comp, interp_idx, event);
4319 snd_soc_component_update_bits(comp, main_reg,
4322 snd_soc_component_update_bits(comp, main_reg,
4325 snd_soc_component_update_bits(comp, main_reg,
4329 snd_soc_component_update_bits(comp, main_reg,
4338 static int wcd934x_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
4339 struct snd_kcontrol *kc, int event)
4341 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4342 int offset_val = 0;
4344 int val = 0;
4347 (w->shift * WCD934X_RX_PATH_CTL_OFFSET);
4349 (w->shift * WCD934X_RX_PATH_CTL_OFFSET);
4354 snd_soc_component_update_bits(comp, mix_reg,
4360 val = snd_soc_component_read(comp, gain_reg);
4362 snd_soc_component_write(comp, gain_reg, val);
4369 static int wcd934x_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
4370 struct snd_kcontrol *kcontrol, int event)
4372 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4373 int reg = w->reg;
4378 snd_soc_component_write(comp, reg,
4379 snd_soc_component_read(comp, reg));
4382 snd_soc_component_write(comp, reg,
4383 snd_soc_component_read(comp, reg));
4386 snd_soc_component_write(comp, reg,
4387 snd_soc_component_read(comp, reg));
4390 snd_soc_component_write(comp, reg,
4391 snd_soc_component_read(comp, reg));
4394 snd_soc_component_write(comp, reg,
4395 snd_soc_component_read(comp, reg));
4403 static int wcd934x_codec_enable_main_path(struct snd_soc_dapm_widget *w,
4405 int event)
4407 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4410 gain_reg = WCD934X_CDC_RX0_RX_VOL_CTL + (w->shift *
4415 snd_soc_component_write(comp, gain_reg,
4416 snd_soc_component_read(comp, gain_reg));
4423 static int wcd934x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4424 struct snd_kcontrol *kc, int event)
4426 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4427 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
4432 snd_soc_component_update_bits(comp,
4435 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
4440 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
4448 static int wcd934x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
4450 int event)
4452 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4453 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
4454 int hph_mode = wcd->hph_mode;
4460 dem_inp = snd_soc_component_read(comp,
4465 return -EINVAL;
4469 snd_soc_component_update_bits(comp,
4474 snd_soc_component_update_bits(comp,
4477 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
4484 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
4488 snd_soc_component_update_bits(comp,
4500 static int wcd934x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
4502 int event)
4504 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4505 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
4506 int hph_mode = wcd->hph_mode;
4511 dem_inp = snd_soc_component_read(comp,
4515 return -EINVAL;
4519 snd_soc_component_update_bits(comp,
4524 snd_soc_component_update_bits(comp,
4527 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
4535 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
4539 snd_soc_component_update_bits(comp,
4550 static int wcd934x_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
4551 struct snd_kcontrol *kc, int event)
4553 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4554 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
4558 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
4562 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
4570 static int wcd934x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
4572 int event)
4574 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4575 struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp);
4586 snd_soc_component_update_bits(comp, WCD934X_HPH_L_TEST,
4590 snd_soc_component_update_bits(comp, WCD934X_CDC_RX1_RX_PATH_CTL,
4594 snd_soc_component_update_bits(comp, WCD934X_HPH_CNP_WG_CTL,
4598 snd_soc_component_update_bits(comp,
4603 snd_soc_component_update_bits(comp,
4608 wcd_mbhc_event_notify(wcd->mbhc, WCD_EVENT_POST_HPHL_PA_OFF);
4610 snd_soc_component_update_bits(comp, WCD934X_HPH_L_TEST,
4613 snd_soc_component_update_bits(comp, WCD934X_CDC_RX1_RX_PATH_CTL,
4616 snd_soc_component_update_bits(comp,
4627 wcd_mbhc_event_notify(wcd->mbhc, WCD_EVENT_POST_HPHL_PA_OFF);
4634 static int wcd934x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
4636 int event)
4638 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4639 struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp);
4649 snd_soc_component_update_bits(comp, WCD934X_HPH_R_TEST,
4653 snd_soc_component_update_bits(comp, WCD934X_CDC_RX2_RX_PATH_CTL,
4657 snd_soc_component_update_bits(comp, WCD934X_HPH_CNP_WG_CTL,
4661 snd_soc_component_update_bits(comp,
4666 if ((snd_soc_component_read(comp,
4668 snd_soc_component_update_bits(comp,
4674 wcd_mbhc_event_notify(wcd->mbhc, WCD_EVENT_PRE_HPHR_PA_OFF);
4675 snd_soc_component_update_bits(comp, WCD934X_HPH_R_TEST,
4678 snd_soc_component_update_bits(comp, WCD934X_CDC_RX2_RX_PATH_CTL,
4681 snd_soc_component_update_bits(comp,
4692 wcd_mbhc_event_notify(wcd->mbhc, WCD_EVENT_POST_HPHR_PA_OFF);
4699 static u32 wcd934x_get_dmic_sample_rate(struct snd_soc_component *comp,
4700 unsigned int dmic,
4715 adc_mux_index - 4;
4720 adc_mux_sel = ((snd_soc_component_read(comp, adc_mux_ctl_reg)
4721 & 0xF8) >> 3) - 1;
4733 tx_stream_fs = snd_soc_component_read(comp, tx_fs_reg) & 0x0F;
4735 dmic_fs = min(wcd->dmic_sample_rate, WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ);
4739 dmic_fs = wcd->dmic_sample_rate;
4745 static u8 wcd934x_get_dmic_clk_val(struct snd_soc_component *comp,
4758 dev_err(comp->dev,
4785 dev_err(comp->dev,
4795 static int wcd934x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
4796 struct snd_kcontrol *kcontrol, int event)
4798 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4799 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
4804 unsigned int dmic;
4806 int ret;
4809 wname = strpbrk(w->name, "012345");
4811 dev_err(comp->dev, "%s: widget not found\n", __func__);
4812 return -EINVAL;
4817 dev_err(comp->dev, "%s: Invalid DMIC line on the codec\n",
4819 return -EINVAL;
4825 dmic_clk_cnt = &wcd->dmic_0_1_clk_cnt;
4830 dmic_clk_cnt = &wcd->dmic_2_3_clk_cnt;
4835 dmic_clk_cnt = &wcd->dmic_4_5_clk_cnt;
4839 dev_err(comp->dev, "%s: Invalid DMIC Selection\n",
4841 return -EINVAL;
4846 dmic_sample_rate = wcd934x_get_dmic_sample_rate(comp, dmic,
4848 dmic_rate_val = wcd934x_get_dmic_clk_val(comp, wcd->rate,
4853 snd_soc_component_update_bits(comp, dmic_clk_reg,
4856 snd_soc_component_update_bits(comp, dmic_clk_reg,
4862 (*dmic_clk_cnt)--;
4864 snd_soc_component_update_bits(comp, dmic_clk_reg,
4872 static int wcd934x_codec_find_amic_input(struct snd_soc_component *comp,
4873 int adc_mux_n)
4898 (adc_mux_n - 4);
4902 adc_mux_n - 4;
4908 adc_mux_n - 4;
4911 ((adc_mux_n == 8) ? (adc_mux_n - 8) :
4912 (adc_mux_n - 9));
4916 adc_mux_n - 4;
4922 adc_mux_n - 4;
4928 adc_mux_n - 4;
4931 is_amic = (((snd_soc_component_read(comp, adc_mux_in_reg)
4936 return snd_soc_component_read(comp, amic_mux_sel_reg) & 0x07;
4939 static u16 wcd934x_codec_get_amic_pwlvl_reg(struct snd_soc_component *comp,
4940 int amic)
4961 static int wcd934x_codec_enable_dec(struct snd_soc_dapm_widget *w,
4962 struct snd_kcontrol *kcontrol, int event)
4964 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4965 unsigned int decimator;
4968 int ret = 0, amic_n;
4974 char *wname __free(kfree) = kstrndup(w->name, 15, GFP_KERNEL);
4976 return -ENOMEM;
4981 dev_err(comp->dev, "%s: Invalid decimator = %s\n",
4982 __func__, w->name);
4983 return -EINVAL;
4989 dev_err(comp->dev, "%s: decimator index not found\n",
4991 return -EINVAL;
4996 dev_err(comp->dev, "%s: Invalid decimator = %s\n",
4998 return -EINVAL;
5008 amic_n = wcd934x_codec_find_amic_input(comp, decimator);
5010 pwr_level_reg = wcd934x_codec_get_amic_pwlvl_reg(comp,
5016 switch ((snd_soc_component_read(comp, pwr_level_reg) &
5020 snd_soc_component_update_bits(comp, dec_cfg_reg,
5025 snd_soc_component_update_bits(comp, dec_cfg_reg,
5032 snd_soc_component_update_bits(comp, dec_cfg_reg,
5039 hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
5042 snd_soc_component_update_bits(comp, dec_cfg_reg,
5045 snd_soc_component_update_bits(comp, hpf_gate_reg,
5053 snd_soc_component_update_bits(comp, hpf_gate_reg,
5058 snd_soc_component_write(comp, tx_gain_ctl_reg,
5059 snd_soc_component_read(comp,
5063 hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
5067 snd_soc_component_update_bits(comp, dec_cfg_reg,
5070 snd_soc_component_update_bits(comp, hpf_gate_reg,
5078 snd_soc_component_update_bits(comp, hpf_gate_reg,
5084 snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
5086 snd_soc_component_update_bits(comp, dec_cfg_reg,
5095 static void wcd934x_codec_set_tx_hold(struct snd_soc_component *comp,
5110 snd_soc_component_update_bits(comp, WCD934X_ANA_AMIC2,
5115 snd_soc_component_update_bits(comp, WCD934X_ANA_AMIC4,
5123 static int wcd934x_codec_enable_adc(struct snd_soc_dapm_widget *w,
5124 struct snd_kcontrol *kcontrol, int event)
5126 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
5130 wcd934x_codec_set_tx_hold(comp, w->reg, true);
5139 static int wcd934x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
5141 int event)
5143 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
5144 int micb_num = w->shift;
5673 /* RX0-RX7 */
5804 static int wcd934x_codec_set_jack(struct snd_soc_component *comp,
5807 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
5808 int ret = 0;
5810 if (!wcd->mbhc)
5811 return -ENOTSUPP;
5813 if (jack && !wcd->mbhc_started) {
5814 ret = wcd_mbhc_start(wcd->mbhc, &wcd->mbhc_cfg, jack);
5815 wcd->mbhc_started = true;
5816 } else if (wcd->mbhc_started) {
5817 wcd_mbhc_stop(wcd->mbhc);
5818 wcd->mbhc_started = false;
5838 static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
5840 struct device *dev = &wcd->sdev->dev;
5841 struct wcd_mbhc_config *cfg = &wcd->mbhc_cfg;
5844 ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0);
5846 return dev_err_probe(dev, -EINVAL, "No Interface device found\n");
5848 wcd->sidev = of_slim_get_device(wcd->sdev->ctrl, ifc_dev_np);
5850 if (!wcd->sidev)
5851 return dev_err_probe(dev, -EINVAL, "Unable to get SLIM Interface device\n");
5853 slim_get_logical_addr(wcd->sidev);
5854 wcd->if_regmap = regmap_init_slimbus(wcd->sidev,
5856 if (IS_ERR(wcd->if_regmap))
5857 return dev_err_probe(dev, PTR_ERR(wcd->if_regmap),
5860 of_property_read_u32(dev->parent->of_node, "qcom,dmic-sample-rate",
5861 &wcd->dmic_sample_rate);
5863 cfg->mbhc_micbias = MIC_BIAS_2;
5864 cfg->anc_micbias = MIC_BIAS_2;
5865 cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
5866 cfg->num_btn = WCD934X_MBHC_MAX_BUTTONS;
5867 cfg->micb_mv = wcd->micb2_mv;
5868 cfg->linein_th = 5000;
5869 cfg->hs_thr = 1700;
5870 cfg->hph_thr = 50;
5878 static int wcd934x_codec_probe(struct platform_device *pdev)
5880 struct device *dev = &pdev->dev;
5881 struct wcd934x_ddata *data = dev_get_drvdata(dev->parent);
5883 int ret, irq;
5887 return -ENOMEM;
5889 wcd->dev = dev;
5890 wcd->regmap = data->regmap;
5891 wcd->extclk = data->extclk;
5892 wcd->sdev = to_slim_device(data->dev);
5893 mutex_init(&wcd->sysclk_mutex);
5894 mutex_init(&wcd->micb_lock);
5901 regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
5904 memcpy(wcd->rx_chs, wcd934x_rx_chs, sizeof(wcd934x_rx_chs));
5905 memcpy(wcd->tx_chs, wcd934x_tx_chs, sizeof(wcd934x_tx_chs));
5907 irq = regmap_irq_get_virq(data->irq_data, WCD934X_IRQ_SLIMBUS);
5909 return dev_err_probe(wcd->dev, irq, "Failed to get SLIM IRQ\n");
5928 .name = "wcd934x-codec",
5938 .name = "wcd934x-codec",