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. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmUv6LwACgkQJNaLcl1U h9ARKQf+NeyoX/Hu9p0nL5LOzgRaV2QDvWL6k4O06/jHs0TRS6csce1XqrZaZI8Q 1JFFC++oop8AIEbnQPX8Iv6Zmaf3IxbxBx1/b8mMeE9SxW2tJjxN2JHft2W3GcD9 /cdTnAzkfTlS1WEFhMjCq0rCkmWcsREI6RKFI1g7z7X9WDF3sPYLxnoQrfmVeud6 1Rv784J+flQSfpDrjn2peSFno9XEOZKTjaUuCpJpy1pOq0kiR0lVx/6yM/D9wMJg e1mEeq9HcuvMqjQsTh3qbfNklY2xEthxnRrvqZXBrDcvh24utFa2YRGCXHZoKtQF dHVsiQ8XIztnBOpLZJSpnzpXdcnJMA== =rQYT -----END PGP SIGNATURE----- Merge tag 'asoc-fix-v6.6-rc6' of https://git.kernel.org/pub/scm/linux/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.
This commit is contained in:
commit
8e13caa215
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
@ -1186,6 +1186,12 @@ post_soft_reset:
|
|||
/* 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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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[] = {
|
||||
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -3435,7 +3437,8 @@ 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;
|
||||
|
@ -3443,46 +3446,47 @@ static int wcd938x_bind(struct device *dev)
|
|||
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;
|
||||
|
@ -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 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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue