]> www.infradead.org Git - users/hch/misc.git/commitdiff
ASoC: codecs: wcd: add common helper for wcd codecs
authorSrinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Tue, 9 Sep 2025 12:19:48 +0000 (13:19 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 18 Sep 2025 21:24:30 +0000 (22:24 +0100)
All the Qualcomm WCD codecs have most of its code duplicated across all
these 3/4 drivers. This is an attempt to remove those duplicate
parts by adding a common helper library for these codecs.

To start with move all the micbias parsing and voltage settings these
are identical in WCD934x, WCD937x, WCD938x and WCD939x codec driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20250909121954.225833-8-srinivas.kandagatla@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/wcd-common.c [new file with mode: 0644]
sound/soc/codecs/wcd-common.h [new file with mode: 0644]
sound/soc/codecs/wcd934x.c
sound/soc/codecs/wcd937x.c
sound/soc/codecs/wcd938x.c
sound/soc/codecs/wcd939x.c

index 6d7e4725d89cd33647770e4f2c4e81445b8335ce..3f11b2c9cce880bb0f410efa3eede87096e709f3 100644 (file)
@@ -2233,6 +2233,9 @@ config SND_SOC_UDA1380
 config SND_SOC_WCD_CLASSH
        tristate
 
+config SND_SOC_WCD_COMMON
+       tristate
+
 config SND_SOC_WCD9335
        tristate "WCD9335 Codec"
        depends on SLIMBUS
@@ -2254,6 +2257,7 @@ config SND_SOC_WCD934X
        select REGMAP_IRQ
        select REGMAP_SLIMBUS
        select SND_SOC_WCD_CLASSH
+       select SND_SOC_WCD_COMMON
        select SND_SOC_WCD_MBHC
        depends on MFD_WCD934X || COMPILE_TEST
        help
@@ -2265,6 +2269,7 @@ config SND_SOC_WCD937X
        tristate
        depends on SOUNDWIRE || !SOUNDWIRE
        select SND_SOC_WCD_CLASSH
+       select SND_SOC_WCD_COMMON
 
 config SND_SOC_WCD937X_SDW
        tristate "WCD9370/WCD9375 Codec - SDW"
@@ -2284,6 +2289,7 @@ config SND_SOC_WCD938X
        tristate
        depends on SOUNDWIRE || !SOUNDWIRE
        select SND_SOC_WCD_CLASSH
+       select SND_SOC_WCD_COMMON
        select MULTIPLEXER
 
 config SND_SOC_WCD938X_SDW
@@ -2303,6 +2309,7 @@ config SND_SOC_WCD939X
        depends on SOUNDWIRE || !SOUNDWIRE
        depends on TYPEC || !TYPEC
        select SND_SOC_WCD_CLASSH
+       select SND_SOC_WCD_COMMON
 
 config SND_SOC_WCD939X_SDW
        tristate "WCD9390/WCD9395 Codec - SDW"
index a68c3d192a1b6ccec513c6bc447c29be532ea70c..79e32f319cabcaaf43b49afc9778451241d7c09a 100644 (file)
@@ -339,6 +339,7 @@ snd-soc-uda1334-y := uda1334.o
 snd-soc-uda1342-y := uda1342.o
 snd-soc-uda1380-y := uda1380.o
 snd-soc-wcd-classh-y := wcd-clsh-v2.o
+snd-soc-wcd-common-y := wcd-common.o
 snd-soc-wcd-mbhc-y := wcd-mbhc-v2.o
 snd-soc-wcd9335-y := wcd9335.o
 snd-soc-wcd934x-y := wcd934x.o
@@ -761,6 +762,7 @@ obj-$(CONFIG_SND_SOC_UDA1334)       += snd-soc-uda1334.o
 obj-$(CONFIG_SND_SOC_UDA1342)  += snd-soc-uda1342.o
 obj-$(CONFIG_SND_SOC_UDA1380)  += snd-soc-uda1380.o
 obj-$(CONFIG_SND_SOC_WCD_CLASSH)       += snd-soc-wcd-classh.o
+obj-$(CONFIG_SND_SOC_WCD_COMMON)       += snd-soc-wcd-common.o
 obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o
 obj-$(CONFIG_SND_SOC_WCD9335)  += snd-soc-wcd9335.o
 obj-$(CONFIG_SND_SOC_WCD934X)  += snd-soc-wcd934x.o
diff --git a/sound/soc/codecs/wcd-common.c b/sound/soc/codecs/wcd-common.c
new file mode 100644 (file)
index 0000000..8f3c080
--- /dev/null
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries.
+
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+
+#include "wcd-common.h"
+
+#define WCD_MIN_MICBIAS_MV     1000
+#define WCD_DEF_MICBIAS_MV     1800
+#define WCD_MAX_MICBIAS_MV     2850
+
+int wcd_get_micb_vout_ctl_val(struct device *dev, u32 micb_mv)
+{
+       /* min micbias voltage is 1V and maximum is 2.85V */
+       if (micb_mv < WCD_MIN_MICBIAS_MV || micb_mv > WCD_MAX_MICBIAS_MV) {
+               dev_err(dev, "Unsupported micbias voltage (%u mV)\n", micb_mv);
+               return -EINVAL;
+       }
+
+       return (micb_mv - WCD_MIN_MICBIAS_MV) / 50;
+}
+EXPORT_SYMBOL_GPL(wcd_get_micb_vout_ctl_val);
+
+static int wcd_get_micbias_val(struct device *dev, int micb_num, u32 *micb_mv)
+{
+       char micbias[64];
+       int mv;
+
+       sprintf(micbias, "qcom,micbias%d-microvolt", micb_num);
+
+       if (of_property_read_u32(dev->of_node, micbias, &mv)) {
+               dev_err(dev, "%s value not found, using default\n", micbias);
+               mv = WCD_DEF_MICBIAS_MV;
+       } else {
+               /* convert it to milli volts */
+               mv = mv/1000;
+       }
+       if (micb_mv)
+               *micb_mv = mv;
+
+       mv = wcd_get_micb_vout_ctl_val(dev, mv);
+       if (mv < 0) {
+               dev_err(dev, "Unsupported %s voltage (%d mV), falling back to default (%d mV)\n",
+                               micbias, mv, WCD_DEF_MICBIAS_MV);
+               return wcd_get_micb_vout_ctl_val(dev, WCD_DEF_MICBIAS_MV);
+       }
+
+       return mv;
+}
+
+int wcd_dt_parse_micbias_info(struct wcd_common *common)
+{
+       int i;
+
+       for (i = 0; i < common->max_bias; i++) {
+               common->micb_vout[i] = wcd_get_micbias_val(common->dev, i + 1, &common->micb_mv[i]);
+               if (common->micb_vout[i] < 0)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(wcd_dt_parse_micbias_info);
+MODULE_DESCRIPTION("Common Qualcomm WCD Codec helpers driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wcd-common.h b/sound/soc/codecs/wcd-common.h
new file mode 100644 (file)
index 0000000..611f06c
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef __WCD_COMMON_H__
+#define __WCD_COMMON_H__
+
+struct device;
+struct sdw_slave;
+struct sdw_bus_params;
+struct irq_domain;
+enum sdw_slave_status;
+
+#define WCD_MAX_MICBIAS                4
+
+struct wcd_common {
+       struct device *dev;
+       int max_bias;
+       u32 micb_mv[WCD_MAX_MICBIAS];
+       u32 micb_vout[WCD_MAX_MICBIAS];
+};
+
+int wcd_get_micb_vout_ctl_val(struct device *dev, u32 micb_mv);
+int wcd_dt_parse_micbias_info(struct wcd_common *common);
+
+#endif /* __WCD_COMMON_H__  */
index 1bb7e1dc7e6b0a5528cbdb7ada943a7d417fb684..d10b457e6c9ac4ee972b6402b8d13423cd5c387f 100644 (file)
@@ -21,6 +21,7 @@
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
 #include "wcd-clsh-v2.h"
+#include "wcd-common.h"
 #include "wcd-mbhc-v2.h"
 
 #include <dt-bindings/sound/qcom,wcd934x.h>
 #define WCD934X_DEC_PWR_LVL_DF         0x00
 #define WCD934X_DEC_PWR_LVL_HYBRID WCD934X_DEC_PWR_LVL_DF
 
-#define WCD934X_DEF_MICBIAS_MV 1800
-#define WCD934X_MAX_MICBIAS_MV 2850
-
 #define WCD_IIR_FILTER_SIZE    (sizeof(u32) * BAND_MAX)
 
 #define WCD_IIR_FILTER_CTL(xname, iidx, bidx) \
@@ -530,6 +528,7 @@ struct wcd934x_codec {
        struct slim_device *sdev;
        struct slim_device *sidev;
        struct wcd_clsh_ctrl *clsh_ctrl;
+       struct wcd_common common;
        struct snd_soc_component *component;
        struct wcd934x_slim_ch rx_chs[WCD934X_RX_MAX];
        struct wcd934x_slim_ch tx_chs[WCD934X_TX_MAX];
@@ -555,7 +554,6 @@ struct wcd934x_codec {
        struct mutex micb_lock;
        u32 micb_ref[WCD934X_MAX_MICBIAS];
        u32 pullup_ref[WCD934X_MAX_MICBIAS];
-       u32 micb2_mv;
 };
 
 #define to_wcd934x_codec(_hw) container_of(_hw, struct wcd934x_codec, hw)
@@ -2168,55 +2166,24 @@ static struct clk *wcd934x_register_mclk_output(struct wcd934x_codec *wcd)
        return NULL;
 }
 
-static int wcd934x_get_micbias_val(struct device *dev, const char *micbias,
-                                  u32 *micb_mv)
-{
-       int mv;
-
-       if (of_property_read_u32(dev->parent->of_node, micbias, &mv)) {
-               dev_err(dev, "%s value not found, using default\n", micbias);
-               mv = WCD934X_DEF_MICBIAS_MV;
-       } else {
-               /* convert it to milli volts */
-               mv = mv/1000;
-       }
-
-       if (mv < 1000 || mv > 2850) {
-               dev_err(dev, "%s value not in valid range, using default\n",
-                       micbias);
-               mv = WCD934X_DEF_MICBIAS_MV;
-       }
-
-       if (micb_mv)
-               *micb_mv = mv;
-
-       return (mv - 1000) / 50;
-}
-
 static int wcd934x_init_dmic(struct snd_soc_component *comp)
 {
-       int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
        struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
        u32 def_dmic_rate, dmic_clk_drv;
+       int ret;
 
-       vout_ctl_1 = wcd934x_get_micbias_val(comp->dev,
-                                            "qcom,micbias1-microvolt", NULL);
-       vout_ctl_2 = wcd934x_get_micbias_val(comp->dev,
-                                            "qcom,micbias2-microvolt",
-                                            &wcd->micb2_mv);
-       vout_ctl_3 = wcd934x_get_micbias_val(comp->dev,
-                                            "qcom,micbias3-microvolt", NULL);
-       vout_ctl_4 = wcd934x_get_micbias_val(comp->dev,
-                                            "qcom,micbias4-microvolt", NULL);
+       ret = wcd_dt_parse_mbhc_data(comp->dev, &wcd->mbhc_cfg);
+       if (ret)
+               return ret;
 
        snd_soc_component_update_bits(comp, WCD934X_ANA_MICB1,
-                                     WCD934X_MICB_VAL_MASK, vout_ctl_1);
+                                     WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[0]);
        snd_soc_component_update_bits(comp, WCD934X_ANA_MICB2,
-                                     WCD934X_MICB_VAL_MASK, vout_ctl_2);
+                                     WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[1]);
        snd_soc_component_update_bits(comp, WCD934X_ANA_MICB3,
-                                     WCD934X_MICB_VAL_MASK, vout_ctl_3);
+                                     WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[2]);
        snd_soc_component_update_bits(comp, WCD934X_ANA_MICB4,
-                                     WCD934X_MICB_VAL_MASK, vout_ctl_4);
+                                     WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[3]);
 
        if (wcd->rate == WCD934X_MCLK_CLK_9P6MHZ)
                def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
@@ -2517,15 +2484,6 @@ static void wcd934x_mbhc_micb_ramp_control(struct snd_soc_component *component,
        }
 }
 
-static int wcd934x_get_micb_vout_ctl_val(u32 micb_mv)
-{
-       /* min micbias voltage is 1V and maximum is 2.85V */
-       if (micb_mv < 1000 || micb_mv > 2850)
-               return -EINVAL;
-
-       return (micb_mv - 1000) / 50;
-}
-
 static int wcd934x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
                                            int req_volt, int micb_num)
 {
@@ -2562,7 +2520,7 @@ static int wcd934x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
        cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
                                                    WCD934X_MICB_VAL_MASK);
 
-       req_vout_ctl = wcd934x_get_micb_vout_ctl_val(req_volt);
+       req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
        if (req_vout_ctl < 0) {
                ret = -EINVAL;
                goto exit;
@@ -2610,10 +2568,10 @@ static int wcd934x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
         * voltage needed to detect threshold microphone, then do
         * not change the micbias, just return.
         */
-       if (wcd934x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+       if (wcd934x->common.micb_mv[1] >= WCD_MBHC_THR_HS_MICB_MV)
                return 0;
 
-       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd934x->micb2_mv;
+       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd934x->common.micb_mv[1];
 
        rc = wcd934x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
 
@@ -3036,7 +2994,7 @@ static void wcd934x_mbhc_deinit(struct snd_soc_component *component)
 static int wcd934x_comp_probe(struct snd_soc_component *component)
 {
        struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
-       int i;
+       int i, ret;
 
        snd_soc_component_init_regmap(component, wcd->regmap);
        wcd->component = component;
@@ -3054,7 +3012,12 @@ static int wcd934x_comp_probe(struct snd_soc_component *component)
        for (i = 0; i < NUM_CODEC_DAIS; i++)
                INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
 
-       wcd934x_init_dmic(component);
+
+       ret = wcd934x_init_dmic(component);
+       if (ret) {
+               dev_err(component->dev, "Failed to Initialize micbias\n");
+               return ret;
+       }
 
        if (wcd934x_mbhc_init(component))
                dev_err(component->dev, "Failed to Initialize MBHC\n");
@@ -5860,14 +5823,13 @@ static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
        cfg->anc_micbias = MIC_BIAS_2;
        cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
        cfg->num_btn = WCD934X_MBHC_MAX_BUTTONS;
-       cfg->micb_mv = wcd->micb2_mv;
+       cfg->micb_mv = wcd->common.micb_mv[1];
        cfg->linein_th = 5000;
        cfg->hs_thr = 1700;
        cfg->hph_thr = 50;
 
        wcd_dt_parse_mbhc_data(dev, cfg);
 
-
        return 0;
 }
 
@@ -5888,6 +5850,8 @@ static int wcd934x_codec_probe(struct platform_device *pdev)
        wcd->sdev = to_slim_device(data->dev);
        mutex_init(&wcd->sysclk_mutex);
        mutex_init(&wcd->micb_lock);
+       wcd->common.dev = dev->parent;
+       wcd->common.max_bias = 4;
 
        ret = wcd934x_codec_parse_data(wcd);
        if (ret)
index b78f37c582cadee0474703f475e257d5f4ce05c3..ffe6508fd84c45c15abc06604d5bafefb880035b 100644 (file)
@@ -21,6 +21,7 @@
 #include <sound/tlv.h>
 
 #include "wcd-clsh-v2.h"
+#include "wcd-common.h"
 #include "wcd-mbhc-v2.h"
 #include "wcd937x.h"
 
@@ -85,6 +86,7 @@ struct wcd937x_priv {
        struct wcd_mbhc_config mbhc_cfg;
        struct wcd_mbhc_intr intr_ids;
        struct wcd_clsh_ctrl *clsh_info;
+       struct wcd_common common;
        struct irq_domain *virq;
        struct regmap_irq_chip_data *irq_chip;
        struct snd_soc_jack *jack;
@@ -93,9 +95,6 @@ struct wcd937x_priv {
        s32 pullup_ref[WCD937X_MAX_MICBIAS];
        u32 hph_mode;
        int ear_rx_path;
-       u32 micb1_mv;
-       u32 micb2_mv;
-       u32 micb3_mv;
        int hphr_pdm_wd_int;
        int hphl_pdm_wd_int;
        int aux_pdm_wd_int;
@@ -872,15 +871,6 @@ static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
-static int wcd937x_get_micb_vout_ctl_val(u32 micb_mv)
-{
-       if (micb_mv < 1000 || micb_mv > 2850) {
-               pr_err("Unsupported micbias voltage (%u mV)\n", micb_mv);
-               return -EINVAL;
-       }
-
-       return (micb_mv - 1000) / 50;
-}
 
 static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
@@ -1481,7 +1471,7 @@ static int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
        cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
                                                    WCD937X_MICB_VOUT_MASK);
 
-       req_vout_ctl = wcd937x_get_micb_vout_ctl_val(req_volt);
+       req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
        if (req_vout_ctl < 0) {
                ret = -EINVAL;
                goto exit;
@@ -1529,10 +1519,10 @@ static int wcd937x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
         * voltage needed to detect threshold microphone, then do
         * not change the micbias, just return.
         */
-       if (wcd937x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+       if (wcd937x->common.micb_mv[2] >= WCD_MBHC_THR_HS_MICB_MV)
                return 0;
 
-       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd937x->micb2_mv;
+       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd937x->common.micb_mv[2];
 
        return wcd937x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
 }
@@ -2436,22 +2426,14 @@ static const struct snd_soc_dapm_route wcd9375_audio_map[] = {
        { "DMIC6_MIXER", "Switch", "DMIC6" },
 };
 
-static int wcd937x_set_micbias_data(struct wcd937x_priv *wcd937x)
+static void wcd937x_set_micbias_data(struct device *dev, struct wcd937x_priv *wcd937x)
 {
-       int vout_ctl[3];
-
-       /* Set micbias voltage */
-       vout_ctl[0] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb1_mv);
-       vout_ctl[1] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb2_mv);
-       vout_ctl[2] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb3_mv);
-       if ((vout_ctl[0] | vout_ctl[1] | vout_ctl[2]) < 0)
-               return -EINVAL;
-
-       regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB1, WCD937X_ANA_MICB_VOUT, vout_ctl[0]);
-       regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB2, WCD937X_ANA_MICB_VOUT, vout_ctl[1]);
-       regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB3, WCD937X_ANA_MICB_VOUT, vout_ctl[2]);
-
-       return 0;
+       regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB1, WCD937X_ANA_MICB_VOUT,
+                       wcd937x->common.micb_vout[0]);
+       regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB2, WCD937X_ANA_MICB_VOUT,
+                       wcd937x->common.micb_vout[1]);
+       regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB3, WCD937X_ANA_MICB_VOUT,
+                       wcd937x->common.micb_vout[2]);
 }
 
 static irqreturn_t wcd937x_wd_handle_irq(int irq, void *data)
@@ -2630,31 +2612,6 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd937x = {
        .endianness = 1,
 };
 
-static void wcd937x_dt_parse_micbias_info(struct device *dev, struct wcd937x_priv *wcd)
-{
-       struct device_node *np = dev->of_node;
-       u32 prop_val = 0;
-       int ret = 0;
-
-       ret = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
-       if (!ret)
-               wcd->micb1_mv = prop_val / 1000;
-       else
-               dev_warn(dev, "Micbias1 DT property not found\n");
-
-       ret = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
-       if (!ret)
-               wcd->micb2_mv = prop_val / 1000;
-       else
-               dev_warn(dev, "Micbias2 DT property not found\n");
-
-       ret = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
-       if (!ret)
-               wcd->micb3_mv = prop_val / 1000;
-       else
-               dev_warn(dev, "Micbias3 DT property not found\n");
-}
-
 static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component)
 {
        int value;
@@ -2848,11 +2805,7 @@ static int wcd937x_bind(struct device *dev)
        wcd937x->sdw_priv[AIF1_PB]->slave_irq = wcd937x->virq;
        wcd937x->sdw_priv[AIF1_CAP]->slave_irq = wcd937x->virq;
 
-       ret = wcd937x_set_micbias_data(wcd937x);
-       if (ret < 0) {
-               dev_err(dev, "Bad micbias pdata\n");
-               return ret;
-       }
+       wcd937x_set_micbias_data(dev, wcd937x);
 
        ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x,
                                         wcd937x_dais, ARRAY_SIZE(wcd937x_dais));
@@ -2920,6 +2873,8 @@ static int wcd937x_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, wcd937x);
        mutex_init(&wcd937x->micb_lock);
+       wcd937x->common.dev = dev;
+       wcd937x->common.max_bias = 3;
 
        wcd937x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
        if (IS_ERR(wcd937x->reset_gpio))
@@ -2939,13 +2894,15 @@ static int wcd937x_probe(struct platform_device *pdev)
        if (ret)
                return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
 
-       wcd937x_dt_parse_micbias_info(dev, wcd937x);
+       ret = wcd_dt_parse_micbias_info(&wcd937x->common);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to get micbias\n");
 
        cfg->mbhc_micbias = MIC_BIAS_2;
        cfg->anc_micbias = MIC_BIAS_2;
        cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
        cfg->num_btn = WCD937X_MBHC_MAX_BUTTONS;
-       cfg->micb_mv = wcd937x->micb2_mv;
+       cfg->micb_mv = wcd937x->common.micb_mv[2];
        cfg->linein_th = 5000;
        cfg->hs_thr = 1700;
        cfg->hph_thr = 50;
index f8d7bf27a6edbcad5e6d19c8d01eeb36151e7d5d..c8b6e543986d333a36eb9f5dcc95149442954bc2 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/regulator/consumer.h>
 
 #include "wcd-clsh-v2.h"
+#include "wcd-common.h"
 #include "wcd-mbhc-v2.h"
 #include "wcd938x.h"
 
@@ -155,6 +156,7 @@ struct wcd938x_priv {
        struct wcd_mbhc_config mbhc_cfg;
        struct wcd_mbhc_intr intr_ids;
        struct wcd_clsh_ctrl *clsh_info;
+       struct wcd_common common;
        struct irq_domain *virq;
        struct regmap_irq_chip_data *irq_chip;
        struct snd_soc_jack *jack;
@@ -169,10 +171,6 @@ struct wcd938x_priv {
        struct gpio_desc *us_euro_gpio;
        struct mux_control *us_euro_mux;
        unsigned int mux_state;
-       u32 micb1_mv;
-       u32 micb2_mv;
-       u32 micb3_mv;
-       u32 micb4_mv;
        int hphr_pdm_wd_int;
        int hphl_pdm_wd_int;
        int aux_pdm_wd_int;
@@ -1974,15 +1972,6 @@ static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component,
        }
 }
 
-static int wcd938x_get_micb_vout_ctl_val(u32 micb_mv)
-{
-       /* min micbias voltage is 1V and maximum is 2.85V */
-       if (micb_mv < 1000 || micb_mv > 2850)
-               return -EINVAL;
-
-       return (micb_mv - 1000) / 50;
-}
-
 static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
                                            int req_volt, int micb_num)
 {
@@ -2019,7 +2008,7 @@ static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
        cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
                                                    WCD938X_MICB_VOUT_MASK);
 
-       req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt);
+       req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
        if (req_vout_ctl < 0) {
                ret = -EINVAL;
                goto exit;
@@ -2067,10 +2056,10 @@ static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
         * voltage needed to detect threshold microphone, then do
         * not change the micbias, just return.
         */
-       if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+       if (wcd938x->common.micb_mv[2] >= WCD_MBHC_THR_HS_MICB_MV)
                return 0;
 
-       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv;
+       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->common.micb_mv[2];
 
        return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
 }
@@ -2975,28 +2964,16 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
        {"EAR", NULL, "EAR PGA"},
 };
 
-static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x)
+static void wcd938x_set_micbias_data(struct device *dev, struct wcd938x_priv *wcd938x)
 {
-       int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
-
-       /* set micbias voltage */
-       vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv);
-       vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv);
-       vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv);
-       vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv);
-       if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
-               return -EINVAL;
-
        regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1,
-                          WCD938X_MICB_VOUT_MASK, vout_ctl_1);
+                          WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[0]);
        regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2,
-                          WCD938X_MICB_VOUT_MASK, vout_ctl_2);
+                          WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[1]);
        regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3,
-                          WCD938X_MICB_VOUT_MASK, vout_ctl_3);
+                          WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[2]);
        regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4,
-                          WCD938X_MICB_VOUT_MASK, vout_ctl_4);
-
-       return 0;
+                          WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[3]);
 }
 
 static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data)
@@ -3200,37 +3177,6 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
        .endianness = 1,
 };
 
-static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd)
-{
-       struct device_node *np = dev->of_node;
-       u32 prop_val = 0;
-       int rc = 0;
-
-       rc = of_property_read_u32(np, "qcom,micbias1-microvolt",  &prop_val);
-       if (!rc)
-               wcd->micb1_mv = prop_val/1000;
-       else
-               dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
-
-       rc = of_property_read_u32(np, "qcom,micbias2-microvolt",  &prop_val);
-       if (!rc)
-               wcd->micb2_mv = prop_val/1000;
-       else
-               dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
-
-       rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
-       if (!rc)
-               wcd->micb3_mv = prop_val/1000;
-       else
-               dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
-
-       rc = of_property_read_u32(np, "qcom,micbias4-microvolt",  &prop_val);
-       if (!rc)
-               wcd->micb4_mv = prop_val/1000;
-       else
-               dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
-}
-
 static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component)
 {
        struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
@@ -3295,13 +3241,15 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device
        if (ret)
                return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
 
-       wcd938x_dt_parse_micbias_info(dev, wcd938x);
+       ret = wcd_dt_parse_micbias_info(&wcd938x->common);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
 
        cfg->mbhc_micbias = MIC_BIAS_2;
        cfg->anc_micbias = MIC_BIAS_2;
        cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
        cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS;
-       cfg->micb_mv = wcd938x->micb2_mv;
+       cfg->micb_mv = wcd938x->common.micb_mv[2];
        cfg->linein_th = 5000;
        cfg->hs_thr = 1700;
        cfg->hph_thr = 50;
@@ -3457,11 +3405,7 @@ static int wcd938x_bind(struct device *dev)
        wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq;
        wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq;
 
-       ret = wcd938x_set_micbias_data(wcd938x);
-       if (ret < 0) {
-               dev_err(dev, "%s: bad micbias pdata\n", __func__);
-               goto err_remove_rx_link;
-       }
+       wcd938x_set_micbias_data(dev, wcd938x);
 
        ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
                                         wcd938x_dais, ARRAY_SIZE(wcd938x_dais));
@@ -3550,6 +3494,8 @@ static int wcd938x_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, wcd938x);
        mutex_init(&wcd938x->micb_lock);
+       wcd938x->common.dev = dev;
+       wcd938x->common.max_bias = 4;
 
        ret = wcd938x_populate_dt_data(wcd938x, dev);
        if (ret)
index 85730ae40c2c2424161adc52173594689d24f4f6..59c920c50c00f86266705a12bd92923ba64e6a92 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/usb/typec_altmode.h>
 
 #include "wcd-clsh-v2.h"
+#include "wcd-common.h"
 #include "wcd-mbhc-v2.h"
 #include "wcd939x.h"
 
@@ -191,6 +192,7 @@ struct wcd939x_priv {
        struct wcd_mbhc_config mbhc_cfg;
        struct wcd_mbhc_intr intr_ids;
        struct wcd_clsh_ctrl *clsh_info;
+       struct wcd_common common;
        struct irq_domain *virq;
        struct regmap_irq_chip_data *irq_chip;
        struct snd_soc_jack *jack;
@@ -201,10 +203,6 @@ struct wcd939x_priv {
        u32 tx_mode[TX_ADC_MAX];
        int variant;
        struct gpio_desc *reset_gpio;
-       u32 micb1_mv;
-       u32 micb2_mv;
-       u32 micb3_mv;
-       u32 micb4_mv;
        int hphr_pdm_wd_int;
        int hphl_pdm_wd_int;
        int ear_pdm_wd_int;
@@ -1919,17 +1917,6 @@ static void wcd939x_mbhc_micb_ramp_control(struct snd_soc_component *component,
        }
 }
 
-static int wcd939x_get_micb_vout_ctl_val(u32 micb_mv)
-{
-       /* min micbias voltage is 1V and maximum is 2.85V */
-       if (micb_mv < 1000 || micb_mv > 2850) {
-               pr_err("%s: unsupported micbias voltage\n", __func__);
-               return -EINVAL;
-       }
-
-       return (micb_mv - 1000) / 50;
-}
-
 static int wcd939x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
                                            int req_volt, int micb_num)
 {
@@ -1969,7 +1956,7 @@ static int wcd939x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
        cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
                                                    WCD939X_MICB_VOUT_CTL);
 
-       req_vout_ctl = wcd939x_get_micb_vout_ctl_val(req_volt);
+       req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
        if (req_vout_ctl < 0) {
                ret = req_vout_ctl;
                goto exit;
@@ -2021,10 +2008,10 @@ static int wcd939x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
         * voltage needed to detect threshold microphone, then do
         * not change the micbias, just return.
         */
-       if (wcd939x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+       if (wcd939x->common.micb_mv[1] >= WCD_MBHC_THR_HS_MICB_MV)
                return 0;
 
-       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd939x->micb2_mv;
+       micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd939x->common.micb_mv[1];
 
        return wcd939x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
 }
@@ -2895,28 +2882,16 @@ static const struct snd_soc_dapm_route wcd939x_audio_map[] = {
        {"EAR", NULL, "EAR PGA"},
 };
 
-static int wcd939x_set_micbias_data(struct wcd939x_priv *wcd939x)
+static void wcd939x_set_micbias_data(struct device *dev, struct wcd939x_priv *wcd939x)
 {
-       int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
-
-       /* set micbias voltage */
-       vout_ctl_1 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb1_mv);
-       vout_ctl_2 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb2_mv);
-       vout_ctl_3 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb3_mv);
-       vout_ctl_4 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb4_mv);
-       if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
-               return -EINVAL;
-
        regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB1,
-                          WCD939X_MICB_VOUT_CTL, vout_ctl_1);
+                          WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[0]);
        regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB2,
-                          WCD939X_MICB_VOUT_CTL, vout_ctl_2);
+                          WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[1]);
        regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB3,
-                          WCD939X_MICB_VOUT_CTL, vout_ctl_3);
+                          WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[2]);
        regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB4,
-                          WCD939X_MICB_VOUT_CTL, vout_ctl_4);
-
-       return 0;
+                          WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[3]);
 }
 
 static irqreturn_t wcd939x_wd_handle_irq(int irq, void *data)
@@ -3186,37 +3161,6 @@ static int wcd939x_typec_mux_set(struct typec_mux_dev *mux,
 }
 #endif /* CONFIG_TYPEC */
 
-static void wcd939x_dt_parse_micbias_info(struct device *dev, struct wcd939x_priv *wcd)
-{
-       struct device_node *np = dev->of_node;
-       u32 prop_val = 0;
-       int rc = 0;
-
-       rc = of_property_read_u32(np, "qcom,micbias1-microvolt",  &prop_val);
-       if (!rc)
-               wcd->micb1_mv = prop_val / 1000;
-       else
-               dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
-
-       rc = of_property_read_u32(np, "qcom,micbias2-microvolt",  &prop_val);
-       if (!rc)
-               wcd->micb2_mv = prop_val / 1000;
-       else
-               dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
-
-       rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
-       if (!rc)
-               wcd->micb3_mv = prop_val / 1000;
-       else
-               dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
-
-       rc = of_property_read_u32(np, "qcom,micbias4-microvolt",  &prop_val);
-       if (!rc)
-               wcd->micb4_mv = prop_val / 1000;
-       else
-               dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
-}
-
 #if IS_ENABLED(CONFIG_TYPEC)
 static bool wcd939x_swap_gnd_mic(struct snd_soc_component *component)
 {
@@ -3252,13 +3196,15 @@ static int wcd939x_populate_dt_data(struct wcd939x_priv *wcd939x, struct device
        if (ret)
                return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
 
-       wcd939x_dt_parse_micbias_info(dev, wcd939x);
+       ret = wcd_dt_parse_micbias_info(&wcd939x->common);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to get micbias\n");
 
        cfg->mbhc_micbias = MIC_BIAS_2;
        cfg->anc_micbias = MIC_BIAS_2;
        cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
        cfg->num_btn = WCD939X_MBHC_MAX_BUTTONS;
-       cfg->micb_mv = wcd939x->micb2_mv;
+       cfg->micb_mv = wcd939x->common.micb_mv[1];
        cfg->linein_th = 5000;
        cfg->hs_thr = 1700;
        cfg->hph_thr = 50;
@@ -3444,11 +3390,7 @@ static int wcd939x_bind(struct device *dev)
        wcd939x->sdw_priv[AIF1_PB]->slave_irq = wcd939x->virq;
        wcd939x->sdw_priv[AIF1_CAP]->slave_irq = wcd939x->virq;
 
-       ret = wcd939x_set_micbias_data(wcd939x);
-       if (ret < 0) {
-               dev_err(dev, "%s: bad micbias pdata\n", __func__);
-               goto err_remove_rx_link;
-       }
+       wcd939x_set_micbias_data(dev, wcd939x);
 
        /* Check WCD9395 version */
        regmap_read(wcd939x->regmap, WCD939X_DIGITAL_CHIP_ID1, &id1);
@@ -3613,6 +3555,8 @@ static int wcd939x_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, wcd939x);
        mutex_init(&wcd939x->micb_lock);
+       wcd939x->common.dev = dev;
+       wcd939x->common.max_bias = 4;
 
        ret = wcd939x_populate_dt_data(wcd939x, dev);
        if (ret) {