1041 lines
35 KiB
Diff
1041 lines
35 KiB
Diff
diff --git a/sound/hda/core/ext/controller.c b/sound/hda/core/ext/controller.c
|
|
--- a/sound/hda/core/ext/controller.c
|
|
+++ b/sound/hda/core/ext/controller.c
|
|
@@ -90,8 +90,10 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus)
|
|
|
|
for (idx = 0; idx < link_count; idx++) {
|
|
hlink = kzalloc_obj(*hlink);
|
|
- if (!hlink)
|
|
+ if (!hlink) {
|
|
+ snd_hdac_ext_link_free_all(bus);
|
|
return -ENOMEM;
|
|
+ }
|
|
hlink->index = idx;
|
|
hlink->bus = bus;
|
|
hlink->ml_addr = bus->mlcap + AZX_ML_BASE +
|
|
diff --git a/sound/hda/core/ext/stream.c b/sound/hda/core/ext/stream.c
|
|
--- a/sound/hda/core/ext/stream.c
|
|
+++ b/sound/hda/core/ext/stream.c
|
|
@@ -102,8 +102,10 @@ int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
|
|
|
|
for (i = 0; i < num_stream; i++) {
|
|
struct hdac_ext_stream *hext_stream = kzalloc_obj(*hext_stream);
|
|
- if (!hext_stream)
|
|
+ if (!hext_stream) {
|
|
+ snd_hdac_ext_stream_free_all(bus);
|
|
return -ENOMEM;
|
|
+ }
|
|
tag = ++stream_tag;
|
|
snd_hdac_ext_stream_init(bus, hext_stream, idx, dir, tag);
|
|
idx++;
|
|
@@ -111,7 +113,6 @@ int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
|
|
}
|
|
|
|
return 0;
|
|
-
|
|
}
|
|
EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all);
|
|
|
|
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
|
|
--- a/sound/soc/amd/yc/acp6x-mach.c
|
|
+++ b/sound/soc/amd/yc/acp6x-mach.c
|
|
@@ -388,6 +388,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|
DMI_MATCH(DMI_PRODUCT_NAME, "Nitro ANV15-41"),
|
|
}
|
|
},
|
|
+ {
|
|
+ .driver_data = &acp6x_card,
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN17-41"),
|
|
+ }
|
|
+ },
|
|
{
|
|
.driver_data = &acp6x_card,
|
|
.matches = {
|
|
@@ -899,6 +906,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|
DMI_MATCH(DMI_BOARD_NAME, "TM2423"),
|
|
}
|
|
},
|
|
+ {
|
|
+ .driver_data = &acp6x_card,
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP 255R 15.6 inch G10 Notebook PC"),
|
|
+ }
|
|
+ },
|
|
{}
|
|
};
|
|
|
|
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
|
|
--- a/sound/soc/codecs/ab8500-codec.c
|
|
+++ b/sound/soc/codecs/ab8500-codec.c
|
|
@@ -14,17 +14,14 @@
|
|
* for ST-Ericsson.
|
|
*/
|
|
|
|
-#include <linux/cleanup.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/device.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/moduleparam.h>
|
|
#include <linux/init.h>
|
|
-#include <linux/delay.h>
|
|
#include <linux/pm.h>
|
|
#include <linux/platform_device.h>
|
|
-#include <linux/mutex.h>
|
|
#include <linux/mfd/abx500/ab8500.h>
|
|
#include <linux/mfd/abx500.h>
|
|
#include <linux/mfd/abx500/ab8500-sysctrl.h>
|
|
@@ -54,32 +51,9 @@
|
|
/* Macrocell register definitions */
|
|
#define AB8500_GPIO_DIR4_REG 0x13 /* Bank AB8500_MISC */
|
|
|
|
-/* Nr of FIR/IIR-coeff banks in ANC-block */
|
|
-#define AB8500_NR_OF_ANC_COEFF_BANKS 2
|
|
-
|
|
-/* Minimum duration to keep ANC IIR Init bit high or
|
|
-low before proceeding with the configuration sequence */
|
|
-#define AB8500_ANC_SM_DELAY 2000
|
|
-
|
|
-/* Sidetone states */
|
|
-static const char * const enum_sid_state[] = {
|
|
- "Unconfigured",
|
|
- "Apply FIR",
|
|
- "FIR is configured",
|
|
-};
|
|
-enum sid_state {
|
|
- SID_UNCONFIGURED = 0,
|
|
- SID_APPLY_FIR = 1,
|
|
- SID_FIR_CONFIGURED = 2,
|
|
-};
|
|
-
|
|
/* Private data for AB8500 device-driver */
|
|
struct ab8500_codec_drvdata {
|
|
struct regmap *regmap;
|
|
- struct mutex ctrl_lock;
|
|
-
|
|
- /* Sidetone */
|
|
- enum sid_state sid_status;
|
|
};
|
|
|
|
static inline const char *amic_micbias_str(enum amic_micbias micbias)
|
|
@@ -642,9 +616,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
|
|
NULL, 0),
|
|
/* Acoustical Noise Cancellation path */
|
|
|
|
- SND_SOC_DAPM_INPUT("ANC Configure Input"),
|
|
- SND_SOC_DAPM_OUTPUT("ANC Configure Output"),
|
|
-
|
|
SND_SOC_DAPM_MUX("ANC Source",
|
|
SND_SOC_NOPM, 0, 0,
|
|
dapm_anc_in_select),
|
|
@@ -687,10 +658,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
|
|
{"Main Supply", NULL, "Audio Power"},
|
|
{"Main Supply", NULL, "Audio Analog Power"},
|
|
|
|
- /* ANC Configure */
|
|
- {"ANC Configure Input", NULL, "Main Supply"},
|
|
- {"ANC Configure Output", NULL, "ANC Configure Input"},
|
|
-
|
|
/* Powerup charge pump if DA1/2 is in use */
|
|
|
|
{"DA_IN1", NULL, "ab8500_0p"},
|
|
@@ -972,75 +939,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
|
|
{"MIC2 V-AMICx Enable", NULL, "V-AMIC2"},
|
|
};
|
|
|
|
-/*
|
|
- * Control-events
|
|
- */
|
|
-
|
|
-static int sid_status_control_get(struct snd_kcontrol *kcontrol,
|
|
- struct snd_ctl_elem_value *ucontrol)
|
|
-{
|
|
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
|
|
-
|
|
- guard(mutex)(&drvdata->ctrl_lock);
|
|
- ucontrol->value.enumerated.item[0] = drvdata->sid_status;
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* Write sidetone FIR-coefficients configuration sequence */
|
|
-static int sid_status_control_put(struct snd_kcontrol *kcontrol,
|
|
- struct snd_ctl_elem_value *ucontrol)
|
|
-{
|
|
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
|
|
- unsigned int param, sidconf;
|
|
- int status = 1;
|
|
-
|
|
- dev_dbg(component->dev, "%s: Enter\n", __func__);
|
|
-
|
|
- if (ucontrol->value.enumerated.item[0] != SID_APPLY_FIR) {
|
|
- dev_err(component->dev,
|
|
- "%s: ERROR: This control supports '%s' only!\n",
|
|
- __func__, enum_sid_state[SID_APPLY_FIR]);
|
|
- return -EIO;
|
|
- }
|
|
-
|
|
- guard(mutex)(&drvdata->ctrl_lock);
|
|
-
|
|
- sidconf = snd_soc_component_read(component, AB8500_SIDFIRCONF);
|
|
- if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
|
|
- if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) {
|
|
- dev_err(component->dev, "%s: Sidetone busy while off!\n",
|
|
- __func__);
|
|
- status = -EPERM;
|
|
- } else {
|
|
- status = -EBUSY;
|
|
- }
|
|
- dev_dbg(component->dev, "%s: Exit\n", __func__);
|
|
- return status;
|
|
- }
|
|
-
|
|
- snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
|
|
-
|
|
- for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
|
|
- snd_soc_component_write(component, AB8500_SIDFIRCOEF1, 0);
|
|
- snd_soc_component_write(component, AB8500_SIDFIRCOEF2, 0);
|
|
- }
|
|
-
|
|
- snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
|
|
- BIT(AB8500_SIDFIRADR_FIRSIDSET),
|
|
- BIT(AB8500_SIDFIRADR_FIRSIDSET));
|
|
- snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
|
|
- BIT(AB8500_SIDFIRADR_FIRSIDSET), 0);
|
|
-
|
|
- drvdata->sid_status = SID_FIR_CONFIGURED;
|
|
-
|
|
- dev_dbg(component->dev, "%s: Exit\n", __func__);
|
|
-
|
|
- return status;
|
|
-}
|
|
-
|
|
/*
|
|
* Controls - Non-DAPM ASoC
|
|
*/
|
|
@@ -1324,9 +1222,6 @@ static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast,
|
|
AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT,
|
|
enum_slavemaster);
|
|
|
|
-/* Sidetone */
|
|
-static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state);
|
|
-
|
|
/* ANC */
|
|
|
|
static struct snd_kcontrol_new ab8500_ctrls[] = {
|
|
@@ -1617,8 +1512,6 @@ static struct snd_kcontrol_new ab8500_ctrls[] = {
|
|
AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0),
|
|
|
|
/* Sidetone */
|
|
- SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate,
|
|
- sid_status_control_get, sid_status_control_put),
|
|
SOC_SINGLE_STROBE("Sidetone Reset",
|
|
AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0),
|
|
};
|
|
@@ -2148,10 +2041,8 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
|
|
|
|
static int ab8500_codec_probe(struct snd_soc_component *component)
|
|
{
|
|
- struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
|
struct device *dev = component->dev;
|
|
struct device_node *np = dev->of_node;
|
|
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
|
|
struct ab8500_codec_platform_data codec_pdata;
|
|
int status;
|
|
|
|
@@ -2184,10 +2075,6 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
|
|
snd_soc_component_write(component, AB8500_SHORTCIRCONF,
|
|
BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
|
|
|
|
- snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
|
|
-
|
|
- mutex_init(&drvdata->ctrl_lock);
|
|
-
|
|
return status;
|
|
}
|
|
|
|
@@ -2216,7 +2103,6 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
|
|
GFP_KERNEL);
|
|
if (!drvdata)
|
|
return -ENOMEM;
|
|
- drvdata->sid_status = SID_UNCONFIGURED;
|
|
dev_set_drvdata(&pdev->dev, drvdata);
|
|
|
|
drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev,
|
|
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
|
|
--- a/sound/soc/codecs/cs35l56-sdw.c
|
|
+++ b/sound/soc/codecs/cs35l56-sdw.c
|
|
@@ -386,11 +386,8 @@ static int __maybe_unused cs35l56_sdw_system_suspend(struct device *dev)
|
|
{
|
|
struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
|
|
|
|
- if (!cs35l56->base.init_done)
|
|
- return 0;
|
|
-
|
|
- /* runtime_resume unmasks the interrupt */
|
|
- cs35l56_mask_soundwire_interrupts(cs35l56);
|
|
+ if (cs35l56->sdw_attached)
|
|
+ cs35l56_mask_soundwire_interrupts(cs35l56);
|
|
|
|
return cs35l56_system_suspend(dev);
|
|
}
|
|
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
|
|
--- a/sound/soc/codecs/cs35l56.c
|
|
+++ b/sound/soc/codecs/cs35l56.c
|
|
@@ -18,9 +18,11 @@
|
|
#include <linux/interrupt.h>
|
|
#include <linux/math.h>
|
|
#include <linux/module.h>
|
|
+#include <linux/mutex.h>
|
|
#include <linux/pm.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/property.h>
|
|
+#include <linux/reboot.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/slab.h>
|
|
@@ -37,6 +39,13 @@
|
|
#include "wm_adsp.h"
|
|
#include "cs35l56.h"
|
|
|
|
+/*
|
|
+ * snd_soc_register_component() can call component_probe() on all instances
|
|
+ * in a card, so deferred registration must be protected across all instances.
|
|
+ */
|
|
+static DEFINE_MUTEX(cs35l56_component_register_lock);
|
|
+static bool cs35l56_shutting_down;
|
|
+
|
|
void cs35l56_mask_soundwire_interrupts(struct cs35l56_private *cs35l56)
|
|
{
|
|
/*
|
|
@@ -1957,6 +1966,11 @@ static void cs35l56_component_register_work(struct work_struct *work)
|
|
component_register_work);
|
|
int ret;
|
|
|
|
+ guard(mutex)(&cs35l56_component_register_lock);
|
|
+
|
|
+ if (cs35l56_shutting_down)
|
|
+ return;
|
|
+
|
|
PM_RUNTIME_ACQUIRE_AUTOSUSPEND(cs35l56->base.dev, pm_err);
|
|
ret = PM_RUNTIME_ACQUIRE_ERR(&pm_err);
|
|
if (ret) {
|
|
@@ -2217,6 +2231,37 @@ EXPORT_NS_GPL_DEV_PM_OPS(cs35l56_pm_ops_i2c_spi, SND_SOC_CS35L56_CORE) = {
|
|
};
|
|
#endif
|
|
|
|
+static int cs35l56_reboot_notify(struct notifier_block *nb,
|
|
+ unsigned long action, void *data)
|
|
+{
|
|
+ guard(mutex)(&cs35l56_component_register_lock);
|
|
+ cs35l56_shutting_down = true;
|
|
+
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+static struct notifier_block cs35l56_reboot_notifier = {
|
|
+ .notifier_call = cs35l56_reboot_notify,
|
|
+};
|
|
+
|
|
+static int __init cs35l56_modinit(void)
|
|
+{
|
|
+ /*
|
|
+ * Use reboot notifier to prevent race between shutdown and
|
|
+ * snd_soc_register_component(). Driver shutdown() callback would
|
|
+ * run too late, after device_shutdown() is already walking the
|
|
+ * device list that component registration can modify.
|
|
+ */
|
|
+ return register_reboot_notifier(&cs35l56_reboot_notifier);
|
|
+}
|
|
+module_init(cs35l56_modinit);
|
|
+
|
|
+static void __exit cs35l56_modexit(void)
|
|
+{
|
|
+ unregister_reboot_notifier(&cs35l56_reboot_notifier);
|
|
+}
|
|
+module_exit(cs35l56_modexit);
|
|
+
|
|
MODULE_DESCRIPTION("ASoC CS35L56 driver");
|
|
MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED");
|
|
MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB");
|
|
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
|
|
--- a/sound/soc/codecs/cs35l56.h
|
|
+++ b/sound/soc/codecs/cs35l56.h
|
|
@@ -32,6 +32,7 @@ struct sdw_slave;
|
|
struct cs35l56_private {
|
|
struct wm_adsp dsp; /* must be first member */
|
|
struct cs35l56_base base;
|
|
+ struct work_struct component_register_work;
|
|
struct work_struct dsp_work;
|
|
struct workqueue_struct *dsp_wq;
|
|
struct snd_soc_component *component;
|
|
@@ -41,6 +42,7 @@ struct cs35l56_private {
|
|
const char *fallback_fw_suffix;
|
|
bool soft_resetting;
|
|
bool sdw_attached;
|
|
+ bool component_registered;
|
|
struct completion init_completion;
|
|
|
|
int speaker_id;
|
|
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c
|
|
--- a/sound/soc/codecs/es8326.c
|
|
+++ b/sound/soc/codecs/es8326.c
|
|
@@ -26,6 +26,7 @@ struct es8326_priv {
|
|
struct snd_soc_component *component;
|
|
struct delayed_work jack_detect_work;
|
|
struct delayed_work button_press_work;
|
|
+ struct delayed_work capture_pop_work;
|
|
struct snd_soc_jack *jack;
|
|
int irq;
|
|
/* The lock protects the situation that an irq is generated
|
|
@@ -628,6 +629,7 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
|
|
regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF,
|
|
0x30, 0x00);
|
|
} else {
|
|
+ cancel_delayed_work_sync(&es8326->capture_pop_work);
|
|
regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE,
|
|
0x0F, 0x0F);
|
|
if (es8326->version > ES8326_VERSION_B) {
|
|
@@ -666,8 +668,9 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
|
|
regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x70);
|
|
regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x00);
|
|
}
|
|
- regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE,
|
|
- 0x0F, 0x00);
|
|
+
|
|
+ queue_delayed_work(system_dfl_wq, &es8326->capture_pop_work,
|
|
+ msecs_to_jiffies(40));
|
|
}
|
|
}
|
|
return 0;
|
|
@@ -773,6 +776,15 @@ static void es8326_disable_micbias(struct snd_soc_component *component)
|
|
snd_soc_dapm_mutex_unlock(dapm);
|
|
}
|
|
|
|
+static void es8326_capture_pop_handler(struct work_struct *work)
|
|
+{
|
|
+ struct es8326_priv *es8326 =
|
|
+ container_of(work, struct es8326_priv, capture_pop_work.work);
|
|
+
|
|
+ regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE,
|
|
+ 0x0F, 0x00);
|
|
+}
|
|
+
|
|
/*
|
|
* For button detection, set the following in soundcard
|
|
* snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
|
|
@@ -1140,6 +1152,7 @@ static int es8326_suspend(struct snd_soc_component *component)
|
|
struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
|
|
|
|
cancel_delayed_work_sync(&es8326->jack_detect_work);
|
|
+ cancel_delayed_work_sync(&es8326->capture_pop_work);
|
|
es8326_disable_micbias(component);
|
|
es8326->calibrated = false;
|
|
regmap_write(es8326->regmap, ES8326_CLK_MUX, 0x2d);
|
|
@@ -1291,6 +1304,8 @@ static int es8326_i2c_probe(struct i2c_client *i2c)
|
|
es8326_jack_detect_handler);
|
|
INIT_DELAYED_WORK(&es8326->button_press_work,
|
|
es8326_jack_button_handler);
|
|
+ INIT_DELAYED_WORK(&es8326->capture_pop_work,
|
|
+ es8326_capture_pop_handler);
|
|
/* ES8316 is level-based while ES8326 is edge-based */
|
|
ret = devm_request_threaded_irq(&i2c->dev, es8326->irq, NULL, es8326_irq,
|
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
|
diff --git a/sound/soc/codecs/es8389.c b/sound/soc/codecs/es8389.c
|
|
--- a/sound/soc/codecs/es8389.c
|
|
+++ b/sound/soc/codecs/es8389.c
|
|
@@ -812,6 +812,23 @@ static int es8389_pcm_hw_free(struct snd_pcm_substream *substream,
|
|
return 0;
|
|
}
|
|
|
|
+static void es8389_standby(struct snd_soc_component *component)
|
|
+{
|
|
+ struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
|
|
+
|
|
+ regmap_update_bits(es8389->regmap, ES8389_ADC_HPF1, 0x0f, 0x04);
|
|
+ regmap_update_bits(es8389->regmap, ES8389_ADC_HPF2, 0x0f, 0x04);
|
|
+ regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0xD4);
|
|
+ usleep_range(70000, 72000);
|
|
+ regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0x59);
|
|
+ regmap_write(es8389->regmap, ES8389_ADC_EN, 0x00);
|
|
+ regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0x00);
|
|
+ regmap_write(es8389->regmap, ES8389_RESET, 0x3E);
|
|
+ regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x80);
|
|
+ usleep_range(8000, 8500);
|
|
+ regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x00);
|
|
+}
|
|
+
|
|
static int es8389_set_bias_level(struct snd_soc_component *component,
|
|
enum snd_soc_bias_level level)
|
|
{
|
|
@@ -834,18 +851,7 @@ static int es8389_set_bias_level(struct snd_soc_component *component,
|
|
case SND_SOC_BIAS_PREPARE:
|
|
break;
|
|
case SND_SOC_BIAS_STANDBY:
|
|
- regmap_update_bits(es8389->regmap, ES8389_ADC_HPF1, 0x0f, 0x04);
|
|
- regmap_update_bits(es8389->regmap, ES8389_ADC_HPF2, 0x0f, 0x04);
|
|
- regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0xD4);
|
|
- usleep_range(70000, 72000);
|
|
- regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0x59);
|
|
- regmap_write(es8389->regmap, ES8389_ADC_EN, 0x00);
|
|
- regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0x00);
|
|
- regmap_write(es8389->regmap, ES8389_RESET, 0x3E);
|
|
- regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x80);
|
|
- usleep_range(8000, 8500);
|
|
- regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x00);
|
|
-
|
|
+ es8389_standby(component);
|
|
clk_disable_unprepare(es8389->mclk);
|
|
break;
|
|
case SND_SOC_BIAS_OFF:
|
|
@@ -1015,7 +1021,7 @@ static int es8389_suspend(struct snd_soc_component *component)
|
|
{
|
|
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
|
|
|
|
- es8389_set_bias_level(component, SND_SOC_BIAS_STANDBY);
|
|
+ es8389_standby(component);
|
|
regcache_cache_only(es8389->regmap, true);
|
|
regcache_mark_dirty(es8389->regmap);
|
|
|
|
@@ -1084,7 +1090,7 @@ static int es8389_probe(struct snd_soc_component *component)
|
|
|
|
es8389->hpf_freq = ES8389_HPF_DEFAULT;
|
|
es8389_init(component);
|
|
- es8389_set_bias_level(component, SND_SOC_BIAS_STANDBY);
|
|
+ es8389_standby(component);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/sound/soc/codecs/rt1318-sdw.c b/sound/soc/codecs/rt1318-sdw.c
|
|
--- a/sound/soc/codecs/rt1318-sdw.c
|
|
+++ b/sound/soc/codecs/rt1318-sdw.c
|
|
@@ -16,6 +16,7 @@
|
|
#include <sound/pcm.h>
|
|
#include <sound/pcm_params.h>
|
|
#include <sound/soc-dapm.h>
|
|
+#include <sound/sdw.h>
|
|
#include <sound/initval.h>
|
|
#include "rt1318-sdw.h"
|
|
|
|
@@ -564,11 +565,10 @@ static int rt1318_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
struct snd_soc_component *component = dai->component;
|
|
struct rt1318_sdw_priv *rt1318 =
|
|
snd_soc_component_get_drvdata(component);
|
|
- struct sdw_stream_config stream_config;
|
|
+ struct sdw_stream_config stream_config = {0};
|
|
struct sdw_port_config port_config;
|
|
- enum sdw_data_direction direction;
|
|
struct sdw_stream_runtime *sdw_stream;
|
|
- int retval, port, num_channels, ch_mask;
|
|
+ int retval, port;
|
|
unsigned int sampling_rate;
|
|
|
|
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
|
|
@@ -582,23 +582,13 @@ static int rt1318_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
|
|
/* SoundWire specific configuration */
|
|
/* port 1 for playback */
|
|
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
- direction = SDW_DATA_DIR_RX;
|
|
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
port = 1;
|
|
- } else {
|
|
- direction = SDW_DATA_DIR_TX;
|
|
+ else
|
|
port = 2;
|
|
- }
|
|
|
|
- num_channels = params_channels(params);
|
|
- ch_mask = (1 << num_channels) - 1;
|
|
-
|
|
- stream_config.frame_rate = params_rate(params);
|
|
- stream_config.ch_count = num_channels;
|
|
- stream_config.bps = snd_pcm_format_width(params_format(params));
|
|
- stream_config.direction = direction;
|
|
-
|
|
- port_config.ch_mask = ch_mask;
|
|
+ /* SoundWire specific configuration */
|
|
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
|
|
port_config.num = port;
|
|
|
|
retval = sdw_stream_add_slave(rt1318->sdw_slave, &stream_config,
|
|
diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c
|
|
--- a/sound/soc/codecs/rt1320-sdw.c
|
|
+++ b/sound/soc/codecs/rt1320-sdw.c
|
|
@@ -3246,7 +3246,7 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
struct snd_soc_component *component = dai->component;
|
|
struct rt1320_sdw_priv *rt1320 =
|
|
snd_soc_component_get_drvdata(component);
|
|
- struct sdw_stream_config stream_config;
|
|
+ struct sdw_stream_config stream_config = {0};
|
|
struct sdw_port_config port_config;
|
|
struct sdw_port_config dmic_port_config[2];
|
|
struct sdw_stream_runtime *sdw_stream;
|
|
diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c
|
|
--- a/sound/soc/codecs/rt712-sdca.c
|
|
+++ b/sound/soc/codecs/rt712-sdca.c
|
|
@@ -23,6 +23,7 @@
|
|
#include <linux/soundwire/sdw_registers.h>
|
|
#include <linux/slab.h>
|
|
#include <sound/soc-dapm.h>
|
|
+#include <sound/sdw.h>
|
|
#include <sound/tlv.h>
|
|
#include "rt712-sdca.h"
|
|
|
|
@@ -1449,11 +1450,10 @@ static int rt712_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
{
|
|
struct snd_soc_component *component = dai->component;
|
|
struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);
|
|
- struct sdw_stream_config stream_config;
|
|
+ struct sdw_stream_config stream_config = {0};
|
|
struct sdw_port_config port_config;
|
|
- enum sdw_data_direction direction;
|
|
struct sdw_stream_runtime *sdw_stream;
|
|
- int retval, port, num_channels;
|
|
+ int retval, port;
|
|
unsigned int sampling_rate;
|
|
|
|
dev_dbg(dai->dev, "%s %s id %d", __func__, dai->name, dai->id);
|
|
@@ -1471,7 +1471,6 @@ static int rt712_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
|
|
/* SoundWire specific configuration */
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
- direction = SDW_DATA_DIR_RX;
|
|
if (dai->id == RT712_AIF1)
|
|
port = 1;
|
|
else if (dai->id == RT712_AIF2)
|
|
@@ -1479,7 +1478,6 @@ static int rt712_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
else
|
|
return -EINVAL;
|
|
} else {
|
|
- direction = SDW_DATA_DIR_TX;
|
|
if (dai->id == RT712_AIF1)
|
|
port = 4;
|
|
else if (dai->id == RT712_AIF3)
|
|
@@ -1488,13 +1486,8 @@ static int rt712_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
return -EINVAL;
|
|
}
|
|
|
|
- stream_config.frame_rate = params_rate(params);
|
|
- stream_config.ch_count = params_channels(params);
|
|
- stream_config.bps = snd_pcm_format_width(params_format(params));
|
|
- stream_config.direction = direction;
|
|
-
|
|
- num_channels = params_channels(params);
|
|
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
|
|
+ /* SoundWire specific configuration */
|
|
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
|
|
port_config.num = port;
|
|
|
|
retval = sdw_stream_add_slave(rt712->slave, &stream_config,
|
|
diff --git a/sound/soc/codecs/rt721-sdca.c b/sound/soc/codecs/rt721-sdca.c
|
|
--- a/sound/soc/codecs/rt721-sdca.c
|
|
+++ b/sound/soc/codecs/rt721-sdca.c
|
|
@@ -21,6 +21,7 @@
|
|
#include <linux/soundwire/sdw_registers.h>
|
|
#include <linux/slab.h>
|
|
#include <sound/soc-dapm.h>
|
|
+#include <sound/sdw.h>
|
|
#include <sound/tlv.h>
|
|
|
|
#include "rt721-sdca.h"
|
|
@@ -206,6 +207,7 @@ static void rt721_sdca_amp_preset(struct rt721_sdca_priv *rt721)
|
|
regmap_write(rt721->regmap,
|
|
SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_FU55,
|
|
RT721_SDCA_CTL_FU_MUTE, CH_02), 0x00);
|
|
+ regmap_write(rt721->regmap, 0x2f5d, 0x1);
|
|
}
|
|
|
|
static void rt721_sdca_jack_preset(struct rt721_sdca_priv *rt721)
|
|
@@ -1268,11 +1270,10 @@ static int rt721_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
{
|
|
struct snd_soc_component *component = dai->component;
|
|
struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component);
|
|
- struct sdw_stream_config stream_config;
|
|
+ struct sdw_stream_config stream_config = {0};
|
|
struct sdw_port_config port_config;
|
|
- enum sdw_data_direction direction;
|
|
struct sdw_stream_runtime *sdw_stream;
|
|
- int retval, port, num_channels;
|
|
+ int retval, port;
|
|
unsigned int sampling_rate;
|
|
|
|
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
|
|
@@ -1291,7 +1292,6 @@ static int rt721_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
* RT721_AIF3 with port = 6 for digital-mic capture
|
|
*/
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
- direction = SDW_DATA_DIR_RX;
|
|
if (dai->id == RT721_AIF1)
|
|
port = 1;
|
|
else if (dai->id == RT721_AIF2)
|
|
@@ -1299,7 +1299,6 @@ static int rt721_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
else
|
|
return -EINVAL;
|
|
} else {
|
|
- direction = SDW_DATA_DIR_TX;
|
|
if (dai->id == RT721_AIF1)
|
|
port = 2;
|
|
else if (dai->id == RT721_AIF3)
|
|
@@ -1307,13 +1306,9 @@ static int rt721_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
else
|
|
return -EINVAL;
|
|
}
|
|
- stream_config.frame_rate = params_rate(params);
|
|
- stream_config.ch_count = params_channels(params);
|
|
- stream_config.bps = snd_pcm_format_width(params_format(params));
|
|
- stream_config.direction = direction;
|
|
|
|
- num_channels = params_channels(params);
|
|
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
|
|
+ /* SoundWire specific configuration */
|
|
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
|
|
port_config.num = port;
|
|
|
|
retval = sdw_stream_add_slave(rt721->slave, &stream_config,
|
|
diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c
|
|
--- a/sound/soc/codecs/rt722-sdca.c
|
|
+++ b/sound/soc/codecs/rt722-sdca.c
|
|
@@ -24,6 +24,7 @@
|
|
#include <sound/pcm.h>
|
|
#include <sound/pcm_params.h>
|
|
#include <sound/soc-dapm.h>
|
|
+#include <sound/sdw.h>
|
|
#include <sound/tlv.h>
|
|
|
|
#include "rt722-sdca.h"
|
|
@@ -1442,11 +1443,10 @@ static int rt722_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
{
|
|
struct snd_soc_component *component = dai->component;
|
|
struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);
|
|
- struct sdw_stream_config stream_config;
|
|
+ struct sdw_stream_config stream_config = {0};
|
|
struct sdw_port_config port_config;
|
|
- enum sdw_data_direction direction;
|
|
struct sdw_stream_runtime *sdw_stream;
|
|
- int retval, port, num_channels;
|
|
+ int retval, port;
|
|
unsigned int sampling_rate;
|
|
|
|
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
|
|
@@ -1465,7 +1465,6 @@ static int rt722_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
* RT722_AIF3 with port = 6 for digital-mic capture
|
|
*/
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
- direction = SDW_DATA_DIR_RX;
|
|
if (dai->id == RT722_AIF1)
|
|
port = 1;
|
|
else if (dai->id == RT722_AIF2)
|
|
@@ -1473,7 +1472,6 @@ static int rt722_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
else
|
|
return -EINVAL;
|
|
} else {
|
|
- direction = SDW_DATA_DIR_TX;
|
|
if (dai->id == RT722_AIF1)
|
|
port = 2;
|
|
else if (dai->id == RT722_AIF3)
|
|
@@ -1481,13 +1479,9 @@ static int rt722_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
else
|
|
return -EINVAL;
|
|
}
|
|
- stream_config.frame_rate = params_rate(params);
|
|
- stream_config.ch_count = params_channels(params);
|
|
- stream_config.bps = snd_pcm_format_width(params_format(params));
|
|
- stream_config.direction = direction;
|
|
|
|
- num_channels = params_channels(params);
|
|
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
|
|
+ /* SoundWire specific configuration */
|
|
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
|
|
port_config.num = port;
|
|
|
|
retval = sdw_stream_add_slave(rt722->slave, &stream_config,
|
|
diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c
|
|
--- a/sound/soc/codecs/tas2783-sdw.c
|
|
+++ b/sound/soc/codecs/tas2783-sdw.c
|
|
@@ -1001,6 +1001,31 @@ static s32 tas_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
/* SoundWire specific configuration */
|
|
snd_sdw_params_to_config(substream, params,
|
|
&stream_config, &port_config);
|
|
+
|
|
+ /*
|
|
+ * The two mono amps each render one channel of the stereo stream:
|
|
+ * snd_sdw_params_to_config() hands every codec the full mask for
|
|
+ * playback, which leaves the pair in mirror mode and one channel
|
|
+ * unreproduced. Claim a single channel instead, keyed off the
|
|
+ * machine-assigned component prefix rather than the SoundWire
|
|
+ * address, which is board-specific: soc_sdw_ti_amp.c names the amps
|
|
+ * tas2783-1..4.
|
|
+ *
|
|
+ * Which side an amp then renders does not follow from the bit that
|
|
+ * is set - sdw_compute_slave_ports() advances the payload offset by
|
|
+ * the popcount of ch_mask and never looks at which bit it is - but
|
|
+ * from the amp's position in the codec order of the DAI link, which
|
|
+ * on these boards matches the prefix numbering.
|
|
+ */
|
|
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
|
+ params_channels(params) == 2 && component->name_prefix) {
|
|
+ const char *idx_str = strrchr(component->name_prefix, '-');
|
|
+ unsigned long idx;
|
|
+
|
|
+ if (idx_str && !kstrtoul(idx_str + 1, 10, &idx) && idx)
|
|
+ port_config.ch_mask = (idx & 1) ? BIT(0) : BIT(1);
|
|
+ }
|
|
+
|
|
/* port 1 for playback */
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
port_config.num = 1;
|
|
diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c
|
|
--- a/sound/soc/intel/avs/boards/hdaudio.c
|
|
+++ b/sound/soc/intel/avs/boards/hdaudio.c
|
|
@@ -15,6 +15,22 @@
|
|
#include "../../../codecs/hda.h"
|
|
#include "../utils.h"
|
|
|
|
+static int avs_link_startup(struct snd_pcm_substream *substream)
|
|
+{
|
|
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
|
+ const struct snd_soc_pcm_stream *stream_info;
|
|
+ struct snd_soc_dai *codec_dai;
|
|
+
|
|
+ codec_dai = snd_soc_rtd_to_codec(rtd, 0);
|
|
+ stream_info = snd_soc_dai_get_pcm_stream(codec_dai, substream->stream);
|
|
+
|
|
+ return snd_pcm_hw_constraint_msbits(substream->runtime, 0, 0, stream_info->sig_bits);
|
|
+}
|
|
+
|
|
+static const struct snd_soc_ops avs_link_ops = {
|
|
+ .startup = avs_link_startup,
|
|
+};
|
|
+
|
|
static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int pcm_count,
|
|
struct snd_soc_dai_link **links)
|
|
{
|
|
@@ -43,6 +59,7 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int
|
|
dl[i].platforms = platform;
|
|
dl[i].num_platforms = 1;
|
|
dl[i].ignore_pmdown_time = 1;
|
|
+ dl[i].ops = &avs_link_ops;
|
|
|
|
dl[i].codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL);
|
|
dl[i].cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
|
|
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
|
|
--- a/sound/soc/intel/avs/core.c
|
|
+++ b/sound/soc/intel/avs/core.c
|
|
@@ -92,16 +92,28 @@ static int avs_hdac_bus_init_streams(struct hdac_bus *bus)
|
|
{
|
|
unsigned int cp_streams, pb_streams;
|
|
unsigned int gcap;
|
|
+ int ret;
|
|
|
|
gcap = snd_hdac_chip_readw(bus, GCAP);
|
|
cp_streams = (gcap >> 8) & 0x0F;
|
|
pb_streams = (gcap >> 12) & 0x0F;
|
|
bus->num_streams = cp_streams + pb_streams;
|
|
|
|
- snd_hdac_ext_stream_init_all(bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE);
|
|
- snd_hdac_ext_stream_init_all(bus, cp_streams, pb_streams, SNDRV_PCM_STREAM_PLAYBACK);
|
|
+ ret = snd_hdac_ext_stream_init_all(bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ ret = snd_hdac_ext_stream_init_all(bus, cp_streams, pb_streams, SNDRV_PCM_STREAM_PLAYBACK);
|
|
+ if (ret)
|
|
+ goto err;
|
|
|
|
- return snd_hdac_bus_alloc_stream_pages(bus);
|
|
+ ret = snd_hdac_bus_alloc_stream_pages(bus);
|
|
+ if (ret)
|
|
+ goto err;
|
|
+
|
|
+ return 0;
|
|
+err:
|
|
+ snd_hdac_ext_stream_free_all(bus);
|
|
+ return ret;
|
|
}
|
|
|
|
static bool avs_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
|
|
@@ -383,6 +395,18 @@ static int avs_bus_init(struct avs_dev *adev, struct pci_dev *pci, const struct
|
|
struct device *dev = &pci->dev;
|
|
int ret;
|
|
|
|
+ ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL);
|
|
+ if (!ipc)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ adev->modcfg_buf = devm_kzalloc(dev, AVS_MAILBOX_SIZE, GFP_KERNEL);
|
|
+ if (!adev->modcfg_buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ ret = avs_ipc_init(ipc, dev);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
ret = snd_hdac_ext_bus_init(&bus->core, dev, NULL, &soc_hda_ext_bus_ops);
|
|
if (ret < 0)
|
|
return ret;
|
|
@@ -394,17 +418,6 @@ static int avs_bus_init(struct avs_dev *adev, struct pci_dev *pci, const struct
|
|
bus->mixer_assigned = -1;
|
|
mutex_init(&bus->prepare_mutex);
|
|
|
|
- ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL);
|
|
- if (!ipc)
|
|
- return -ENOMEM;
|
|
- ret = avs_ipc_init(ipc, dev);
|
|
- if (ret < 0)
|
|
- return ret;
|
|
-
|
|
- adev->modcfg_buf = devm_kzalloc(dev, AVS_MAILBOX_SIZE, GFP_KERNEL);
|
|
- if (!adev->modcfg_buf)
|
|
- return -ENOMEM;
|
|
-
|
|
adev->dev = dev;
|
|
adev->spec = (const struct avs_spec *)id->driver_data;
|
|
adev->ipc = ipc;
|
|
@@ -456,13 +469,14 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
|
|
|
ret = pcim_request_all_regions(pci, "AVS HDAudio");
|
|
if (ret < 0)
|
|
- return ret;
|
|
+ goto err_request_regions;
|
|
|
|
bus->addr = pci_resource_start(pci, 0);
|
|
bus->remap_addr = pci_ioremap_bar(pci, 0);
|
|
if (!bus->remap_addr) {
|
|
dev_err(bus->dev, "ioremap error\n");
|
|
- return -ENXIO;
|
|
+ ret = -ENXIO;
|
|
+ goto err_request_regions;
|
|
}
|
|
|
|
adev->dsp_ba = pci_ioremap_bar(pci, 4);
|
|
@@ -526,6 +540,8 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
|
iounmap(adev->dsp_ba);
|
|
err_remap_bar4:
|
|
iounmap(bus->remap_addr);
|
|
+err_request_regions:
|
|
+ snd_hdac_ext_bus_exit(bus);
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
|
|
--- a/sound/soc/intel/avs/debugfs.c
|
|
+++ b/sound/soc/intel/avs/debugfs.c
|
|
@@ -9,6 +9,7 @@
|
|
#include <linux/cleanup.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/kfifo.h>
|
|
+#include <linux/module.h>
|
|
#include <linux/wait.h>
|
|
#include <linux/sched/signal.h>
|
|
#include <linux/string_helpers.h>
|
|
@@ -236,15 +237,20 @@ static int strace_open(struct inode *inode, struct file *file)
|
|
if (!try_module_get(adev->dev->driver->owner))
|
|
return -ENODEV;
|
|
|
|
- if (kfifo_initialized(&adev->trace_fifo))
|
|
- return -EBUSY;
|
|
+ if (kfifo_initialized(&adev->trace_fifo)) {
|
|
+ ret = -EBUSY;
|
|
+ goto err;
|
|
+ }
|
|
|
|
ret = kfifo_alloc(&adev->trace_fifo, PAGE_SIZE, GFP_KERNEL);
|
|
if (ret < 0)
|
|
- return ret;
|
|
+ goto err;
|
|
|
|
file->private_data = adev;
|
|
return 0;
|
|
+err:
|
|
+ module_put(adev->dev->driver->owner);
|
|
+ return ret;
|
|
}
|
|
|
|
static int strace_release(struct inode *inode, struct file *file)
|
|
diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
|
|
--- a/sound/soc/intel/avs/ipc.c
|
|
+++ b/sound/soc/intel/avs/ipc.c
|
|
@@ -172,7 +172,7 @@ static void avs_dsp_exception_caught(struct avs_dev *adev, union avs_notify_msg
|
|
|
|
/* Avoid deadlock as the exception may be the response to SET_D0IX. */
|
|
if (current_work() != &ipc->d0ix_work.work)
|
|
- cancel_delayed_work_sync(&ipc->d0ix_work);
|
|
+ cancel_delayed_work(&ipc->d0ix_work);
|
|
ipc->in_d0ix = false;
|
|
/* Re-enabled on recovery completion. */
|
|
pm_runtime_disable(adev->dev);
|
|
@@ -395,11 +395,11 @@ static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request
|
|
struct avs_ipc *ipc = adev->ipc;
|
|
int ret;
|
|
|
|
+ guard(mutex)(&ipc->msg_mutex);
|
|
+
|
|
if (!ipc->ready)
|
|
return -EPERM;
|
|
|
|
- guard(mutex)(&ipc->msg_mutex);
|
|
-
|
|
spin_lock(&ipc->rx_lock);
|
|
avs_ipc_msg_init(ipc, reply);
|
|
avs_dsp_send_tx(adev, request, true);
|
|
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
|
|
--- a/sound/soc/intel/boards/Kconfig
|
|
+++ b/sound/soc/intel/boards/Kconfig
|
|
@@ -533,12 +533,14 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
|
|
select SND_SOC_CS35L56_SPI
|
|
select SND_SOC_CS35L56_SDW
|
|
select SND_SOC_ES9356
|
|
+ imply SND_SOC_TAC5XX2_SDW
|
|
select SND_SOC_DMIC
|
|
select SND_SOC_INTEL_HDA_DSP_COMMON
|
|
imply SND_SOC_SDW_MOCKUP
|
|
help
|
|
Add support for Intel SoundWire-based platforms connected to
|
|
- MAX98373, RT700, RT711, RT1308 and RT715
|
|
+ MAX98373, RT700, RT711, RT1308, RT715, TAC5XX2_SDW family (including
|
|
+ TAC5572, TAC5682).
|
|
If unsure select "N".
|
|
|
|
endif
|
|
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
|
|
--- a/sound/soc/intel/boards/sof_rt5682.c
|
|
+++ b/sound/soc/intel/boards/sof_rt5682.c
|
|
@@ -908,6 +908,14 @@ static const struct platform_device_id board_ids[] = {
|
|
SOF_SSP_PORT_BT_OFFLOAD(2) |
|
|
SOF_BT_OFFLOAD_PRESENT),
|
|
},
|
|
+ {
|
|
+ .name = "nvl_rt5682_def",
|
|
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
|
|
+ SOF_SSP_PORT_CODEC(0) |
|
|
+ SOF_SSP_PORT_AMP(1) |
|
|
+ SOF_SSP_PORT_BT_OFFLOAD(2) |
|
|
+ SOF_BT_OFFLOAD_PRESENT),
|
|
+ },
|
|
{
|
|
.name = "ptl_rt5682_c1_h02",
|
|
.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
|
|
diff --git a/sound/soc/intel/common/soc-acpi-intel-nvl-match.c b/sound/soc/intel/common/soc-acpi-intel-nvl-match.c
|
|
--- a/sound/soc/intel/common/soc-acpi-intel-nvl-match.c
|
|
+++ b/sound/soc/intel/common/soc-acpi-intel-nvl-match.c
|
|
@@ -51,10 +51,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_nvl_machines[] = {
|
|
},
|
|
{
|
|
.comp_ids = &nvl_rt5682_rt5682s_hp,
|
|
- .drv_name = "sof_rt5682",
|
|
- .sof_tplg_filename = "sof-nvl-rt5682", /* the tplg suffix is added at run time */
|
|
- .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
|
|
- SND_SOC_ACPI_TPLG_INTEL_SSP_MSB,
|
|
+ .drv_name = "nvl_rt5682_def",
|
|
+ .sof_tplg_filename = "sof-nvl", /* the tplg suffix is added at run time */
|
|
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
|
|
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
|
|
},
|
|
/* place amp/hdmi-in only boards in the end of table */
|
|
{
|