summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/pm4125.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2025-12-02 07:12:56 +0100
committerTakashi Iwai <tiwai@suse.de>2025-12-02 07:12:56 +0100
commit9747b22a417d2a7c478678143863b9777de104e4 (patch)
tree2690242ac1e95570c3e56a3106752af4cc2b5472 /sound/soc/codecs/pm4125.c
parentef5e0a02d842b2c6dfcfd9b80feb185769b892ef (diff)
parentc5fae31f60a91dbe884ef2789fb3440bb4cddf05 (diff)
Merge tag 'asoc-v6.19' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v6.19 This is a very large set of updates, as well as some more extensive cleanup work from Morimto-san we've also added a generic SCDA class driver for SoundWire devices enabling us to support many chips with no custom code. There's also a batch of new drivers added for both SoCs and CODECs. - Added a SoundWire SCDA generic class driver, pulling in a little regmap work to support it. - A *lot* of cleaup and API improvement work from Morimoto-san. - Lots of work on the existing Cirrus, Intel, Maxim and Qualcomm drivers. - Support for Allwinner A523, Mediatek MT8189, Qualcomm QCM2290, QRB2210 and SM6115, SpacemiT K1, and TI TAS2568, TAS5802, TAS5806, TAS5815, TAS5828 and TAS5830. This also pulls in some gpiolib changes supporting shared GPIOs in the core there so we can convert some of the ASoC drivers open coding handling of that to the core functionality.
Diffstat (limited to 'sound/soc/codecs/pm4125.c')
-rw-r--r--sound/soc/codecs/pm4125.c104
1 files changed, 35 insertions, 69 deletions
diff --git a/sound/soc/codecs/pm4125.c b/sound/soc/codecs/pm4125.c
index f9bcae6d1d79..8bc3b9994019 100644
--- a/sound/soc/codecs/pm4125.c
+++ b/sound/soc/codecs/pm4125.c
@@ -69,16 +69,14 @@ struct pm4125_priv {
struct wcd_mbhc *wcd_mbhc;
struct wcd_mbhc_config mbhc_cfg;
struct wcd_mbhc_intr intr_ids;
+ struct wcd_common common;
struct irq_domain *virq;
- const struct regmap_irq_chip *pm4125_regmap_irq_chip;
+ const struct regmap_irq_chip *chip_desc;
struct regmap_irq_chip_data *irq_chip;
struct snd_soc_jack *jack;
unsigned long status_mask;
s32 micb_ref[PM4125_MAX_MICBIAS];
s32 pullup_ref[PM4125_MAX_MICBIAS];
- u32 micb1_mv;
- u32 micb2_mv;
- u32 micb3_mv;
int hphr_pdm_wd_int;
int hphl_pdm_wd_int;
@@ -179,7 +177,7 @@ static const u32 pm4125_config_regs[] = {
PM4125_DIG_SWR_INTR_LEVEL_0,
};
-static struct regmap_irq_chip pm4125_regmap_irq_chip = {
+static const struct regmap_irq_chip pm4125_regmap_irq_chip = {
.name = "pm4125",
.irqs = pm4125_irqs,
.num_irqs = ARRAY_SIZE(pm4125_irqs),
@@ -644,16 +642,6 @@ static int pm4125_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
return 0;
}
-static int pm4125_get_micb_vout_ctl_val(struct device *dev, u32 micb_mv)
-{
- if (micb_mv < 1600 || micb_mv > 2850) {
- dev_err(dev, "%s: unsupported micbias voltage (%u mV)\n", __func__, micb_mv);
- return -EINVAL;
- }
-
- return (micb_mv - 1600) / 50;
-}
-
static int pm4125_codec_enable_adc(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -691,7 +679,7 @@ static int pm4125_codec_enable_adc(struct snd_soc_dapm_widget *w,
0x00);
pm4125_global_mbias_disable(component);
break;
- };
+ }
return 0;
}
@@ -756,7 +744,7 @@ static int pm4125_micbias_control(struct snd_soc_component *component, int micb_
dev_err(component->dev, "%s: Invalid micbias number: %d\n",
__func__, micb_num);
return -EINVAL;
- };
+ }
switch (req) {
case MICB_PULLUP_ENABLE:
@@ -799,7 +787,7 @@ static int pm4125_micbias_control(struct snd_soc_component *component, int micb_
pm4125_global_mbias_disable(component);
}
break;
- };
+ }
return 0;
}
@@ -855,7 +843,7 @@ static int pm4125_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
static int pm4125_connect_port(struct pm4125_sdw_priv *sdw_priv, u8 port_idx, u8 ch_id, bool enable)
{
struct sdw_port_config *port_config = &sdw_priv->port_config[port_idx - 1];
- const struct pm4125_sdw_ch_info *ch_info = &sdw_priv->ch_info[ch_id];
+ const struct wcd_sdw_ch_info *ch_info = &sdw_priv->ch_info[ch_id];
struct sdw_slave *sdev = sdw_priv->sdev;
u8 port_num = ch_info->port_num;
u8 ch_mask = ch_info->ch_mask;
@@ -879,7 +867,7 @@ static int pm4125_connect_port(struct pm4125_sdw_priv *sdw_priv, u8 port_idx, u8
static int pm4125_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
struct soc_mixer_control *mc;
bool hphr;
@@ -893,7 +881,7 @@ static int pm4125_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_el
static int pm4125_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[AIF1_PB];
int value = ucontrol->value.integer.value[0];
@@ -926,7 +914,7 @@ static int pm4125_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_el
static int pm4125_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(comp);
struct pm4125_sdw_priv *sdw_priv;
int dai_id = mixer->shift;
@@ -944,7 +932,7 @@ static int pm4125_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
static int pm4125_set_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(comp);
struct pm4125_sdw_priv *sdw_priv;
int dai_id = mixer->shift;
@@ -1266,15 +1254,8 @@ static const struct snd_soc_dapm_route pm4125_audio_map[] = {
static int pm4125_set_micbias_data(struct device *dev, struct pm4125_priv *pm4125)
{
- int vout_ctl;
-
- /* Set micbias voltage */
- vout_ctl = pm4125_get_micb_vout_ctl_val(dev, pm4125->micb1_mv);
- if (vout_ctl < 0)
- return -EINVAL;
-
regmap_update_bits(pm4125->regmap, PM4125_ANA_MICBIAS_LDO_1_SETTING,
- PM4125_ANA_MICBIAS_MICB_OUT_VAL_MASK, vout_ctl << 3);
+ PM4125_ANA_MICBIAS_MICB_OUT_VAL_MASK, pm4125->common.micb_vout[0]);
return 0;
}
@@ -1320,10 +1301,8 @@ static int pm4125_irq_init(struct pm4125_priv *pm4125, struct device *dev)
return -EINVAL;
}
- pm4125_regmap_irq_chip.irq_drv_data = pm4125;
-
return devm_regmap_add_irq_chip(dev, pm4125->regmap, irq_create_mapping(pm4125->virq, 0),
- IRQF_ONESHOT, 0, &pm4125_regmap_irq_chip,
+ IRQF_ONESHOT, 0, pm4125->chip_desc,
&pm4125->irq_chip);
}
@@ -1418,31 +1397,6 @@ static const struct snd_soc_component_driver soc_codec_dev_pm4125 = {
.endianness = 1,
};
-static void pm4125_dt_parse_micbias_info(struct device *dev, struct pm4125_priv *priv)
-{
- struct device_node *np = dev->of_node;
- u32 prop_val = 0;
- int ret;
-
- ret = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
- if (!ret)
- priv->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)
- priv->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)
- priv->micb3_mv = prop_val / 1000;
- else
- dev_warn(dev, "Micbias3 DT property not found\n");
-}
-
static int pm4125_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -1564,7 +1518,7 @@ static int pm4125_bind(struct device *dev)
return ret;
}
- pm4125->rxdev = pm4125_sdw_device_get(pm4125->rxnode);
+ pm4125->rxdev = of_sdw_find_device_by_node(pm4125->rxnode);
if (!pm4125->rxdev) {
dev_err(dev, "could not find rxslave with matching of node\n");
ret = -EINVAL;
@@ -1574,7 +1528,7 @@ static int pm4125_bind(struct device *dev)
pm4125->sdw_priv[AIF1_PB] = dev_get_drvdata(pm4125->rxdev);
pm4125->sdw_priv[AIF1_PB]->pm4125 = pm4125;
- pm4125->txdev = pm4125_sdw_device_get(pm4125->txnode);
+ pm4125->txdev = of_sdw_find_device_by_node(pm4125->txnode);
if (!pm4125->txdev) {
dev_err(dev, "could not find txslave with matching of node\n");
ret = -EINVAL;
@@ -1619,7 +1573,7 @@ static int pm4125_bind(struct device *dev)
goto link_remove_dev_tx;
}
- pm4125->regmap = dev_get_regmap(&pm4125->tx_sdw_dev->dev, NULL);
+ pm4125->regmap = pm4125->sdw_priv[AIF1_CAP]->regmap;
if (!pm4125->regmap) {
dev_err(dev, "could not get TX device regmap\n");
ret = -EINVAL;
@@ -1635,11 +1589,7 @@ static int pm4125_bind(struct device *dev)
pm4125->sdw_priv[AIF1_PB]->slave_irq = pm4125->virq;
pm4125->sdw_priv[AIF1_CAP]->slave_irq = pm4125->virq;
- ret = pm4125_set_micbias_data(dev, pm4125);
- if (ret < 0) {
- dev_err(dev, "Bad micbias pdata\n");
- goto link_remove_dev_rx;
- }
+ pm4125_set_micbias_data(dev, pm4125);
ret = snd_soc_register_component(dev, &soc_codec_dev_pm4125,
pm4125_dais, ARRAY_SIZE(pm4125_dais));
@@ -1668,6 +1618,8 @@ static void pm4125_unbind(struct device *dev)
struct pm4125_priv *pm4125 = dev_get_drvdata(dev);
snd_soc_unregister_component(dev);
+ devm_regmap_del_irq_chip(dev, irq_find_mapping(pm4125->virq, 0),
+ pm4125->irq_chip);
device_link_remove(dev, pm4125->txdev);
device_link_remove(dev, pm4125->rxdev);
device_link_remove(pm4125->rxdev, pm4125->txdev);
@@ -1710,6 +1662,7 @@ static int pm4125_probe(struct platform_device *pdev)
{
struct component_match *match = NULL;
struct device *dev = &pdev->dev;
+ struct regmap_irq_chip *chip_desc;
struct pm4125_priv *pm4125;
struct wcd_mbhc_config *cfg;
int ret;
@@ -1720,6 +1673,14 @@ static int pm4125_probe(struct platform_device *pdev)
dev_set_drvdata(dev, pm4125);
+ chip_desc = devm_kmemdup(dev, &pm4125_regmap_irq_chip,
+ sizeof(pm4125_regmap_irq_chip),
+ GFP_KERNEL);
+ if (!chip_desc)
+ return -ENOMEM;
+ chip_desc->irq_drv_data = pm4125;
+ pm4125->chip_desc = chip_desc;
+
ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(pm4125_power_supplies),
pm4125_power_supplies);
if (ret)
@@ -1731,7 +1692,12 @@ static int pm4125_probe(struct platform_device *pdev)
pm4125_reset(pm4125);
- pm4125_dt_parse_micbias_info(dev, pm4125);
+ pm4125->common.dev = dev;
+ pm4125->common.max_bias = 3;
+ ret = wcd_dt_parse_micbias_info(&pm4125->common);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get micbias\n");
+
atomic_set(&pm4125->gloal_mbias_cnt, 0);
cfg = &pm4125->mbhc_cfg;
@@ -1739,7 +1705,7 @@ static int pm4125_probe(struct platform_device *pdev)
cfg->anc_micbias = MIC_BIAS_2;
cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
cfg->num_btn = PM4125_MBHC_MAX_BUTTONS;
- cfg->micb_mv = pm4125->micb2_mv;
+ cfg->micb_mv = pm4125->common.micb_mv[1];
cfg->linein_th = 5000;
cfg->hs_thr = 1700;
cfg->hph_thr = 50;