Skip to content

Commit

Permalink
Merge tag 'asoc-fix-v6.6-rc6' of https://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v6.6

A fairly large set of fixes here but all driver specific, the biggest
block is Johan's work shaking out issues with device setup and teardown
for the wcd938x driver which is a relatively large but clearly broken
down set of changes.

There is one core helper function added as part of a fix for wsa-macro.
  • Loading branch information
Takashi Iwai committed Oct 18, 2023
2 parents c8c0a03 + e8ecffd commit 8e13caa
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ properties:
description:
Current at which the headset micbias sense clamp will engage, 0 to
disable.
enum: [ 0, 14, 23, 41, 50, 60, 68, 86, 95 ]
enum: [ 0, 14, 24, 43, 52, 61, 71, 90, 99 ]
default: 0

cirrus,bias-ramp-ms:
Expand Down
1 change: 1 addition & 0 deletions include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);

int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai);
int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s);

/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
Expand Down
8 changes: 7 additions & 1 deletion sound/soc/codecs/cs35l56.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56)

mutex_lock(&cs35l56->base.irq_lock);

init_completion(&cs35l56->init_completion);
reinit_completion(&cs35l56->init_completion);

cs35l56->soft_resetting = true;
cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral);
Expand Down Expand Up @@ -1186,6 +1186,12 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
/* Registers could be dirty after soft reset or SoundWire enumeration */
regcache_sync(cs35l56->base.regmap);

/* Set ASP1 DOUT to high-impedance when it is not transmitting audio data. */
ret = regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3,
CS35L56_ASP1_DOUT_HIZ_CTRL_MASK);
if (ret)
return dev_err_probe(cs35l56->base.dev, ret, "Failed to write ASP1_CONTROL3\n");

cs35l56->base.init_done = true;
complete(&cs35l56->init_completion);

Expand Down
1 change: 1 addition & 0 deletions sound/soc/codecs/cs42l42-sdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/codecs/cs42l43-jack.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static const unsigned int cs42l43_accdet_db_ms[] = {
static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 };

static const unsigned int cs42l43_accdet_bias_sense[] = {
14, 23, 41, 50, 60, 68, 86, 95, 0,
14, 24, 43, 52, 61, 71, 90, 99, 0,
};

static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const prop,
Expand Down
11 changes: 5 additions & 6 deletions sound/soc/codecs/da7219-aad.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
bool micbias_up = false;
int retries = 0;

/* Disable ground switch */
snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);

/* Drive headphones/lineout */
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_OE_MASK,
Expand Down Expand Up @@ -155,9 +152,6 @@ static void da7219_aad_hptest_work(struct work_struct *work)
tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
}

/* Disable ground switch */
snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);

/* Ensure gain ramping at fastest rate */
gain_ramp_ctrl = snd_soc_component_read(component, DA7219_GAIN_RAMP_CTRL);
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
Expand Down Expand Up @@ -421,6 +415,11 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
* handle a removal, and we can check at the end of
* hptest if we have a valid result or not.
*/

cancel_delayed_work_sync(&da7219_aad->jack_det_work);
/* Disable ground switch */
snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);

if (statusa & DA7219_JACK_TYPE_STS_MASK) {
report |= SND_JACK_HEADSET;
mask |= SND_JACK_HEADSET | SND_JACK_LINEOUT;
Expand Down
4 changes: 2 additions & 2 deletions sound/soc/codecs/lpass-wsa-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1675,12 +1675,12 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
u16 boost_path_ctl, boost_path_cfg1;
u16 reg, reg_mix;

if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT0 CHAIN")) {
boost_path_ctl = CDC_WSA_BOOST0_BOOST_PATH_CTL;
boost_path_cfg1 = CDC_WSA_RX0_RX_PATH_CFG1;
reg = CDC_WSA_RX0_RX_PATH_CTL;
reg_mix = CDC_WSA_RX0_RX_PATH_MIX_CTL;
} else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
} else if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT1 CHAIN")) {
boost_path_ctl = CDC_WSA_BOOST1_BOOST_PATH_CTL;
boost_path_cfg1 = CDC_WSA_RX1_RX_PATH_CFG1;
reg = CDC_WSA_RX1_RX_PATH_CTL;
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/codecs/rt5645.c
Original file line number Diff line number Diff line change
Expand Up @@ -3257,6 +3257,8 @@ int rt5645_set_jack_detect(struct snd_soc_component *component,
RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ);
regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL1,
RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
regmap_update_bits(rt5645->regmap, RT5645_DEPOP_M1,
RT5645_HP_CB_MASK, RT5645_HP_CB_PU);
}
rt5645_irq(0, rt5645);

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/codecs/tas2780.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static void tas2780_reset(struct tas2780_priv *tas2780)
usleep_range(2000, 2050);
}

snd_soc_component_write(tas2780->component, TAS2780_SW_RST,
ret = snd_soc_component_write(tas2780->component, TAS2780_SW_RST,
TAS2780_RST);
if (ret)
dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n",
Expand Down
27 changes: 26 additions & 1 deletion sound/soc/codecs/wcd938x-sdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,31 @@ static int wcd9380_probe(struct sdw_slave *pdev,
pm_runtime_set_active(dev);
pm_runtime_enable(dev);

return component_add(dev, &wcd938x_sdw_component_ops);
ret = component_add(dev, &wcd938x_sdw_component_ops);
if (ret)
goto err_disable_rpm;

return 0;

err_disable_rpm:
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_dont_use_autosuspend(dev);

return ret;
}

static int wcd9380_remove(struct sdw_slave *pdev)
{
struct device *dev = &pdev->dev;

component_del(dev, &wcd938x_sdw_component_ops);

pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_dont_use_autosuspend(dev);

return 0;
}

static const struct sdw_device_id wcd9380_slave_id[] = {
Expand Down Expand Up @@ -1320,6 +1344,7 @@ static const struct dev_pm_ops wcd938x_sdw_pm_ops = {

static struct sdw_driver wcd9380_codec_driver = {
.probe = wcd9380_probe,
.remove = wcd9380_remove,
.ops = &wcd9380_slave_ops,
.id_table = wcd9380_slave_id,
.driver = {
Expand Down
76 changes: 57 additions & 19 deletions sound/soc/codecs/wcd938x.c
Original file line number Diff line number Diff line change
Expand Up @@ -3325,8 +3325,10 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device
return dev_err_probe(dev, ret, "Failed to get supplies\n");

ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
if (ret)
if (ret) {
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
return dev_err_probe(dev, ret, "Failed to enable supplies\n");
}

wcd938x_dt_parse_micbias_info(dev, wcd938x);

Expand Down Expand Up @@ -3435,54 +3437,56 @@ static int wcd938x_bind(struct device *dev)
wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode);
if (!wcd938x->rxdev) {
dev_err(dev, "could not find slave with matching of node\n");
return -EINVAL;
ret = -EINVAL;
goto err_unbind;
}
wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev);
wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x;

wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode);
if (!wcd938x->txdev) {
dev_err(dev, "could not find txslave with matching of node\n");
return -EINVAL;
ret = -EINVAL;
goto err_put_rxdev;
}
wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev);
wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x;
wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev);
if (!wcd938x->tx_sdw_dev) {
dev_err(dev, "could not get txslave with matching of dev\n");
return -EINVAL;
}

/* As TX is main CSR reg interface, which should not be suspended first.
* expicilty add the dependency link */
if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS |
DL_FLAG_PM_RUNTIME)) {
dev_err(dev, "could not devlink tx and rx\n");
return -EINVAL;
ret = -EINVAL;
goto err_put_txdev;
}

if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS |
DL_FLAG_PM_RUNTIME)) {
dev_err(dev, "could not devlink wcd and tx\n");
return -EINVAL;
ret = -EINVAL;
goto err_remove_rxtx_link;
}

if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS |
DL_FLAG_PM_RUNTIME)) {
dev_err(dev, "could not devlink wcd and rx\n");
return -EINVAL;
ret = -EINVAL;
goto err_remove_tx_link;
}

wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL);
if (!wcd938x->regmap) {
dev_err(dev, "could not get TX device regmap\n");
return -EINVAL;
ret = -EINVAL;
goto err_remove_rx_link;
}

ret = wcd938x_irq_init(wcd938x, dev);
if (ret) {
dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret);
return ret;
goto err_remove_rx_link;
}

wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq;
Expand All @@ -3491,27 +3495,45 @@ static int wcd938x_bind(struct device *dev)
ret = wcd938x_set_micbias_data(wcd938x);
if (ret < 0) {
dev_err(dev, "%s: bad micbias pdata\n", __func__);
return ret;
goto err_remove_rx_link;
}

ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
wcd938x_dais, ARRAY_SIZE(wcd938x_dais));
if (ret)
if (ret) {
dev_err(dev, "%s: Codec registration failed\n",
__func__);
goto err_remove_rx_link;
}

return ret;
return 0;

err_remove_rx_link:
device_link_remove(dev, wcd938x->rxdev);
err_remove_tx_link:
device_link_remove(dev, wcd938x->txdev);
err_remove_rxtx_link:
device_link_remove(wcd938x->rxdev, wcd938x->txdev);
err_put_txdev:
put_device(wcd938x->txdev);
err_put_rxdev:
put_device(wcd938x->rxdev);
err_unbind:
component_unbind_all(dev, wcd938x);

return ret;
}

static void wcd938x_unbind(struct device *dev)
{
struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);

snd_soc_unregister_component(dev);
device_link_remove(dev, wcd938x->txdev);
device_link_remove(dev, wcd938x->rxdev);
device_link_remove(wcd938x->rxdev, wcd938x->txdev);
snd_soc_unregister_component(dev);
put_device(wcd938x->txdev);
put_device(wcd938x->rxdev);
component_unbind_all(dev, wcd938x);
}

Expand Down Expand Up @@ -3572,13 +3594,13 @@ static int wcd938x_probe(struct platform_device *pdev)

ret = wcd938x_add_slave_components(wcd938x, dev, &match);
if (ret)
return ret;
goto err_disable_regulators;

wcd938x_reset(wcd938x);

ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match);
if (ret)
return ret;
goto err_disable_regulators;

pm_runtime_set_autosuspend_delay(dev, 1000);
pm_runtime_use_autosuspend(dev);
Expand All @@ -3588,11 +3610,27 @@ static int wcd938x_probe(struct platform_device *pdev)
pm_runtime_idle(dev);

return 0;

err_disable_regulators:
regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);

return ret;
}

static void wcd938x_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &wcd938x_comp_ops);
struct device *dev = &pdev->dev;
struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);

component_master_del(dev, &wcd938x_comp_ops);

pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_dont_use_autosuspend(dev);

regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
}

#if defined(CONFIG_OF)
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/dwc/dwc-i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ static int jh7110_i2stx0_clk_cfg(struct i2s_clk_config_data *config)

static int dw_i2s_probe(struct platform_device *pdev)
{
const struct i2s_platform_data *pdata = of_device_get_match_data(&pdev->dev);
const struct i2s_platform_data *pdata = pdev->dev.platform_data;
struct dw_i2s_dev *dev;
struct resource *res;
int ret, irq;
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/pxa/pxa-ssp.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai)
if (IS_ERR(priv->extclk)) {
ret = PTR_ERR(priv->extclk);
if (ret == -EPROBE_DEFER)
return ret;
goto err_priv;

priv->extclk = NULL;
}
Expand Down
1 change: 1 addition & 0 deletions sound/soc/soc-component.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ int snd_soc_component_notify_control(struct snd_soc_component *component,
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
struct snd_kcontrol *kctl;

/* When updating, change also snd_soc_dapm_widget_name_cmp() */
if (component->name_prefix)
snprintf(name, ARRAY_SIZE(name), "%s %s", component->name_prefix, ctl);
else
Expand Down
12 changes: 12 additions & 0 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2728,6 +2728,18 @@ int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_update_dai);

int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm);
const char *wname = widget->name;

if (component->name_prefix)
wname += strlen(component->name_prefix) + 1; /* plus space */

return strcmp(wname, s);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_widget_name_cmp);

/*
* dapm_update_widget_flags() - Re-compute widget sink and source flags
* @w: The widget for which to update the flags
Expand Down

0 comments on commit 8e13caa

Please sign in to comment.