diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 700bb909e3..3a02debee8 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef WSA883X_INTERNAL_H @@ -125,6 +126,7 @@ struct wsa883x_priv { unsigned long status_mask; struct snd_soc_dai_driver *dai_driver; struct snd_soc_component_driver *driver; + unsigned long port_status_mask; }; #endif /* WSA883X_INTERNAL_H */ diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 5cd0055c6b..51abab7bdd 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -166,6 +167,11 @@ enum { WSA883X_NUM_IRQS, }; +enum { + COMP_PORT_EN_STATUS_BIT = 0, + VISENSE_EN_STATUS_BIT, +}; + static const struct regmap_irq wsa883x_irqs[WSA883X_NUM_IRQS] = { REGMAP_IRQ_REG(WSA883X_IRQ_INT_SAF2WAR, 0, 0x01), REGMAP_IRQ_REG(WSA883X_IRQ_INT_WAR2SAF, 0, 0x02), @@ -1081,6 +1087,7 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + set_bit(COMP_PORT_EN_STATUS_BIT, &wsa883x->port_status_mask); } if (wsa883x->visense_enable) { wsa883x_set_port(component, SWR_VISENSE_PORT, @@ -1088,6 +1095,7 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + set_bit(VISENSE_EN_STATUS_BIT, &wsa883x->port_status_mask); } swr_connect_port(wsa883x->swr_slave, &port_id[0], num_port, &ch_mask[0], &ch_rate[0], &num_ch[0], @@ -1103,19 +1111,23 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &port_type[num_port]); ++num_port; - if (wsa883x->comp_enable) { + if (wsa883x->comp_enable && + test_bit(COMP_PORT_EN_STATUS_BIT, &wsa883x->port_status_mask)) { wsa883x_set_port(component, SWR_COMP_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + clear_bit(COMP_PORT_EN_STATUS_BIT, &wsa883x->port_status_mask); } - if (wsa883x->visense_enable) { + if (wsa883x->visense_enable && + test_bit(VISENSE_EN_STATUS_BIT, &wsa883x->port_status_mask)) { wsa883x_set_port(component, SWR_VISENSE_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + clear_bit(VISENSE_EN_STATUS_BIT, &wsa883x->port_status_mask); } swr_disconnect_port(wsa883x->swr_slave, &port_id[0], num_port, &ch_mask[0], &port_type[0]); @@ -1180,7 +1192,8 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); - if (wsa883x->comp_enable) + if (wsa883x->comp_enable && + test_bit(COMP_PORT_EN_STATUS_BIT, &wsa883x->port_status_mask)) snd_soc_component_update_bits(component, WSA883X_DRE_CTL_0, 0x07, @@ -1612,7 +1625,8 @@ static int wsa883x_event_notify(struct notifier_block *nb, WSA883X_IRQ_INT_PDM_WD); /* Added delay as per HW sequence */ usleep_range(3000, 3100); - if (wsa883x->comp_enable) { + if (wsa883x->comp_enable && + test_bit(COMP_PORT_EN_STATUS_BIT, &wsa883x->port_status_mask)) { snd_soc_component_update_bits(wsa883x->component, WSA883X_DRE_CTL_1, 0x01, 0x00); diff --git a/asoc/codecs/wsa884x/internal.h b/asoc/codecs/wsa884x/internal.h index 26c776a295..d24130f3bf 100644 --- a/asoc/codecs/wsa884x/internal.h +++ b/asoc/codecs/wsa884x/internal.h @@ -397,6 +397,7 @@ struct wsa884x_priv { int num_supplies; struct regulator_bulk_data *supplies; unsigned long status_mask; + unsigned long port_status_mask; struct snd_soc_dai_driver *dai_driver; struct snd_soc_component_driver *driver; int noise_gate_mode; diff --git a/asoc/codecs/wsa884x/wsa884x.c b/asoc/codecs/wsa884x/wsa884x.c index beae1588b1..247903976b 100644 --- a/asoc/codecs/wsa884x/wsa884x.c +++ b/asoc/codecs/wsa884x/wsa884x.c @@ -166,6 +166,12 @@ enum { SPKR_ADIE_LB, }; +enum { + COMP_PORT_EN_STATUS_BIT = 0, + VI_PORT_EN_STATUS_BIT, + PBR_PORT_EN_STATUS_BIT, + CPS_PORT_EN_STATUS_BIT, +}; enum { WSA884X_IRQ_INT_SAF2WAR = 0, WSA884X_IRQ_INT_WAR2SAF, @@ -1307,6 +1313,7 @@ static int wsa884x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + set_bit(COMP_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } if (wsa884x->pbr_enable) { wsa884x_set_port(component, SWR_PBR_PORT, @@ -1314,6 +1321,7 @@ static int wsa884x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + set_bit(PBR_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } if (wsa884x->visense_enable) { wsa884x_set_port(component, SWR_VISENSE_PORT, @@ -1321,6 +1329,7 @@ static int wsa884x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + set_bit(VI_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } if (wsa884x->cps_enable) { wsa884x_set_port(component, SWR_CPS_PORT, @@ -1328,6 +1337,7 @@ static int wsa884x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + set_bit(CPS_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } swr_connect_port(wsa884x->swr_slave, &port_id[0], num_port, &ch_mask[0], &ch_rate[0], &num_ch[0], @@ -1343,33 +1353,41 @@ static int wsa884x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &port_type[num_port]); ++num_port; - if (wsa884x->comp_enable) { + if (wsa884x->comp_enable && + test_bit(COMP_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask)) { wsa884x_set_port(component, SWR_COMP_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + clear_bit(COMP_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } - if (wsa884x->pbr_enable) { + if (wsa884x->pbr_enable && + test_bit(PBR_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask)) { wsa884x_set_port(component, SWR_PBR_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + clear_bit(PBR_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } - if (wsa884x->visense_enable) { + if (wsa884x->visense_enable && + test_bit(VI_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask)) { wsa884x_set_port(component, SWR_VISENSE_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + clear_bit(VI_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } - if (wsa884x->cps_enable) { + if (wsa884x->cps_enable && + test_bit(CPS_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask)) { wsa884x_set_port(component, SWR_CPS_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; + clear_bit(CPS_PORT_EN_STATUS_BIT, &wsa884x->port_status_mask); } swr_disconnect_port(wsa884x->swr_slave, &port_id[0], num_port, &ch_mask[0], &port_type[0]);