Commit d3bbc28b authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-v5.8-rc5' of...

Merge tag 'asoc-fix-v5.8-rc5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v5.8

An awful lot of mostly small fixes here, mainly for x86 based platforms
and the CODEC drivers mainly used on them.  For the most part this is
either minor device specific stuff which seems to come from detailed
testing or robustness against errors which comes from people having done
some fuzzing runs aginst the topology code.
parents 60379ba0 fe0a5304
...@@ -380,6 +380,8 @@ examples: ...@@ -380,6 +380,8 @@ examples:
- | - |
sound { sound {
compatible = "simple-audio-card"; compatible = "simple-audio-card";
#address-cells = <1>;
#size-cells = <0>;
simple-audio-card,name = "rsnd-ak4643"; simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j"; simple-audio-card,format = "left_j";
...@@ -393,10 +395,12 @@ examples: ...@@ -393,10 +395,12 @@ examples:
"ak4642 Playback", "DAI1 Playback"; "ak4642 Playback", "DAI1 Playback";
dpcmcpu: simple-audio-card,cpu@0 { dpcmcpu: simple-audio-card,cpu@0 {
reg = <0>;
sound-dai = <&rcar_sound 0>; sound-dai = <&rcar_sound 0>;
}; };
simple-audio-card,cpu@1 { simple-audio-card,cpu@1 {
reg = <1>;
sound-dai = <&rcar_sound 1>; sound-dai = <&rcar_sound 1>;
}; };
...@@ -420,6 +424,8 @@ examples: ...@@ -420,6 +424,8 @@ examples:
- | - |
sound { sound {
compatible = "simple-audio-card"; compatible = "simple-audio-card";
#address-cells = <1>;
#size-cells = <0>;
simple-audio-card,routing = simple-audio-card,routing =
"pcm3168a Playback", "DAI1 Playback", "pcm3168a Playback", "DAI1 Playback",
...@@ -428,6 +434,7 @@ examples: ...@@ -428,6 +434,7 @@ examples:
"pcm3168a Playback", "DAI4 Playback"; "pcm3168a Playback", "DAI4 Playback";
simple-audio-card,dai-link@0 { simple-audio-card,dai-link@0 {
reg = <0>;
format = "left_j"; format = "left_j";
bitclock-master = <&sndcpu0>; bitclock-master = <&sndcpu0>;
frame-master = <&sndcpu0>; frame-master = <&sndcpu0>;
...@@ -441,22 +448,23 @@ examples: ...@@ -441,22 +448,23 @@ examples:
}; };
simple-audio-card,dai-link@1 { simple-audio-card,dai-link@1 {
reg = <1>;
format = "i2s"; format = "i2s";
bitclock-master = <&sndcpu1>; bitclock-master = <&sndcpu1>;
frame-master = <&sndcpu1>; frame-master = <&sndcpu1>;
convert-channels = <8>; /* TDM Split */ convert-channels = <8>; /* TDM Split */
sndcpu1: cpu@0 { sndcpu1: cpu0 {
sound-dai = <&rcar_sound 1>; sound-dai = <&rcar_sound 1>;
}; };
cpu@1 { cpu1 {
sound-dai = <&rcar_sound 2>; sound-dai = <&rcar_sound 2>;
}; };
cpu@2 { cpu2 {
sound-dai = <&rcar_sound 3>; sound-dai = <&rcar_sound 3>;
}; };
cpu@3 { cpu3 {
sound-dai = <&rcar_sound 4>; sound-dai = <&rcar_sound 4>;
}; };
codec { codec {
...@@ -468,6 +476,7 @@ examples: ...@@ -468,6 +476,7 @@ examples:
}; };
simple-audio-card,dai-link@2 { simple-audio-card,dai-link@2 {
reg = <2>;
format = "i2s"; format = "i2s";
bitclock-master = <&sndcpu2>; bitclock-master = <&sndcpu2>;
frame-master = <&sndcpu2>; frame-master = <&sndcpu2>;
......
...@@ -6876,6 +6876,7 @@ M: Timur Tabi <timur@kernel.org> ...@@ -6876,6 +6876,7 @@ M: Timur Tabi <timur@kernel.org>
M: Nicolin Chen <nicoleotsuka@gmail.com> M: Nicolin Chen <nicoleotsuka@gmail.com>
M: Xiubo Li <Xiubo.Lee@gmail.com> M: Xiubo Li <Xiubo.Lee@gmail.com>
R: Fabio Estevam <festevam@gmail.com> R: Fabio Estevam <festevam@gmail.com>
R: Shengjiu Wang <shengjiu.wang@gmail.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Maintained
...@@ -11183,17 +11184,17 @@ F: drivers/iio/adc/at91-sama5d2_adc.c ...@@ -11183,17 +11184,17 @@ F: drivers/iio/adc/at91-sama5d2_adc.c
F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h
MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER
M: Nicolas Ferre <nicolas.ferre@microchip.com> M: Claudiu Beznea <claudiu.beznea@microchip.com>
S: Supported S: Supported
F: drivers/power/reset/at91-sama5d2_shdwc.c F: drivers/power/reset/at91-sama5d2_shdwc.c
MICROCHIP SPI DRIVER MICROCHIP SPI DRIVER
M: Nicolas Ferre <nicolas.ferre@microchip.com> M: Tudor Ambarus <tudor.ambarus@microchip.com>
S: Supported S: Supported
F: drivers/spi/spi-atmel.* F: drivers/spi/spi-atmel.*
MICROCHIP SSC DRIVER MICROCHIP SSC DRIVER
M: Nicolas Ferre <nicolas.ferre@microchip.com> M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Supported S: Supported
F: drivers/misc/atmel-ssc.c F: drivers/misc/atmel-ssc.c
......
...@@ -12,6 +12,7 @@ struct rt5670_platform_data { ...@@ -12,6 +12,7 @@ struct rt5670_platform_data {
int jd_mode; int jd_mode;
bool in2_diff; bool in2_diff;
bool dev_gpio; bool dev_gpio;
bool gpio1_is_ext_spk_en;
bool dmic_en; bool dmic_en;
unsigned int dmic1_data_pin; unsigned int dmic1_data_pin;
......
...@@ -161,6 +161,7 @@ void snd_soc_dai_resume(struct snd_soc_dai *dai); ...@@ -161,6 +161,7 @@ void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai, int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num); struct snd_soc_pcm_runtime *rtd, int num);
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream); bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link);
void snd_soc_dai_action(struct snd_soc_dai *dai, void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action); int stream, int action);
static inline void snd_soc_dai_activate(struct snd_soc_dai *dai, static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
......
...@@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev, ...@@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver, const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai); struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_component(struct device *dev); void snd_soc_unregister_component(struct device *dev);
void snd_soc_unregister_component_by_driver(struct device *dev,
const struct snd_soc_component_driver *component_driver);
struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev, struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
const char *driver_name); const char *driver_name);
struct snd_soc_component *snd_soc_lookup_component(struct device *dev, struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
......
...@@ -232,9 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci, ...@@ -232,9 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci,
} }
pm_runtime_set_autosuspend_delay(&pci->dev, 2000); pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
pm_runtime_use_autosuspend(&pci->dev); pm_runtime_use_autosuspend(&pci->dev);
pm_runtime_set_active(&pci->dev);
pm_runtime_put_noidle(&pci->dev); pm_runtime_put_noidle(&pci->dev);
pm_runtime_enable(&pci->dev);
pm_runtime_allow(&pci->dev); pm_runtime_allow(&pci->dev);
return 0; return 0;
...@@ -303,7 +301,7 @@ static void snd_acp3x_remove(struct pci_dev *pci) ...@@ -303,7 +301,7 @@ static void snd_acp3x_remove(struct pci_dev *pci)
ret = acp3x_deinit(adata->acp3x_base); ret = acp3x_deinit(adata->acp3x_base);
if (ret) if (ret)
dev_err(&pci->dev, "ACP de-init failed\n"); dev_err(&pci->dev, "ACP de-init failed\n");
pm_runtime_disable(&pci->dev); pm_runtime_forbid(&pci->dev);
pm_runtime_get_noresume(&pci->dev); pm_runtime_get_noresume(&pci->dev);
pci_disable_msi(pci); pci_disable_msi(pci);
pci_release_regions(pci); pci_release_regions(pci);
......
...@@ -779,13 +779,6 @@ static int max98373_probe(struct snd_soc_component *component) ...@@ -779,13 +779,6 @@ static int max98373_probe(struct snd_soc_component *component)
regmap_write(max98373->regmap, regmap_write(max98373->regmap,
MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2,
0x1); 0x1);
/* Set inital volume (0dB) */
regmap_write(max98373->regmap,
MAX98373_R203D_AMP_DIG_VOL_CTRL,
0x00);
regmap_write(max98373->regmap,
MAX98373_R203E_AMP_PATH_GAIN,
0x00);
/* Enable DC blocker */ /* Enable DC blocker */
regmap_write(max98373->regmap, regmap_write(max98373->regmap,
MAX98373_R203F_AMP_DSP_CFG, MAX98373_R203F_AMP_DSP_CFG,
...@@ -869,7 +862,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98373 = { ...@@ -869,7 +862,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98373 = {
.num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets),
.dapm_routes = max98373_audio_map, .dapm_routes = max98373_audio_map,
.num_dapm_routes = ARRAY_SIZE(max98373_audio_map), .num_dapm_routes = ARRAY_SIZE(max98373_audio_map),
.idle_bias_on = 1,
.use_pmdown_time = 1, .use_pmdown_time = 1,
.endianness = 1, .endianness = 1,
.non_legacy_dai_naming = 1, .non_legacy_dai_naming = 1,
......
...@@ -272,13 +272,13 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) ...@@ -272,13 +272,13 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf); regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf);
*mic = buf & 0x80000000; *mic = buf & 0x80000000;
} }
if (!*mic) {
if (!*hp) {
snd_soc_dapm_disable_pin(dapm, "HV"); snd_soc_dapm_disable_pin(dapm, "HV");
snd_soc_dapm_disable_pin(dapm, "VREF"); snd_soc_dapm_disable_pin(dapm, "VREF");
}
if (!*hp)
snd_soc_dapm_disable_pin(dapm, "LDO1"); snd_soc_dapm_disable_pin(dapm, "LDO1");
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
}
return 0; return 0;
} }
......
...@@ -31,18 +31,19 @@ ...@@ -31,18 +31,19 @@
#include "rt5670.h" #include "rt5670.h"
#include "rt5670-dsp.h" #include "rt5670-dsp.h"
#define RT5670_DEV_GPIO BIT(0) #define RT5670_DEV_GPIO BIT(0)
#define RT5670_IN2_DIFF BIT(1) #define RT5670_IN2_DIFF BIT(1)
#define RT5670_DMIC_EN BIT(2) #define RT5670_DMIC_EN BIT(2)
#define RT5670_DMIC1_IN2P BIT(3) #define RT5670_DMIC1_IN2P BIT(3)
#define RT5670_DMIC1_GPIO6 BIT(4) #define RT5670_DMIC1_GPIO6 BIT(4)
#define RT5670_DMIC1_GPIO7 BIT(5) #define RT5670_DMIC1_GPIO7 BIT(5)
#define RT5670_DMIC2_INR BIT(6) #define RT5670_DMIC2_INR BIT(6)
#define RT5670_DMIC2_GPIO8 BIT(7) #define RT5670_DMIC2_GPIO8 BIT(7)
#define RT5670_DMIC3_GPIO5 BIT(8) #define RT5670_DMIC3_GPIO5 BIT(8)
#define RT5670_JD_MODE1 BIT(9) #define RT5670_JD_MODE1 BIT(9)
#define RT5670_JD_MODE2 BIT(10) #define RT5670_JD_MODE2 BIT(10)
#define RT5670_JD_MODE3 BIT(11) #define RT5670_JD_MODE3 BIT(11)
#define RT5670_GPIO1_IS_EXT_SPK_EN BIT(12)
static unsigned long rt5670_quirk; static unsigned long rt5670_quirk;
static unsigned int quirk_override; static unsigned int quirk_override;
...@@ -602,9 +603,9 @@ int rt5670_set_jack_detect(struct snd_soc_component *component, ...@@ -602,9 +603,9 @@ int rt5670_set_jack_detect(struct snd_soc_component *component,
EXPORT_SYMBOL_GPL(rt5670_set_jack_detect); EXPORT_SYMBOL_GPL(rt5670_set_jack_detect);
static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0);
static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000);
static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
...@@ -1447,6 +1448,33 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w, ...@@ -1447,6 +1448,33 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static int rt5670_spk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
if (!rt5670->pdata.gpio1_is_ext_spk_en)
return 0;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_HI);
break;
case SND_SOC_DAPM_PRE_PMD:
regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_LO);
break;
default:
return 0;
}
return 0;
}
static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
...@@ -1860,7 +1888,9 @@ static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = { ...@@ -1860,7 +1888,9 @@ static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = {
}; };
static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = { static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = {
SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA_E("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
rt5670_spk_event, SND_SOC_DAPM_PRE_PMD |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_OUTPUT("SPOLP"), SND_SOC_DAPM_OUTPUT("SPOLP"),
SND_SOC_DAPM_OUTPUT("SPOLN"), SND_SOC_DAPM_OUTPUT("SPOLN"),
SND_SOC_DAPM_OUTPUT("SPORP"), SND_SOC_DAPM_OUTPUT("SPORP"),
...@@ -2857,14 +2887,14 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { ...@@ -2857,14 +2887,14 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = {
}, },
{ {
.callback = rt5670_quirk_cb, .callback = rt5670_quirk_cb,
.ident = "Lenovo Thinkpad Tablet 10", .ident = "Lenovo Miix 2 10",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
}, },
.driver_data = (unsigned long *)(RT5670_DMIC_EN | .driver_data = (unsigned long *)(RT5670_DMIC_EN |
RT5670_DMIC1_IN2P | RT5670_DMIC1_IN2P |
RT5670_DEV_GPIO | RT5670_GPIO1_IS_EXT_SPK_EN |
RT5670_JD_MODE2), RT5670_JD_MODE2),
}, },
{ {
...@@ -2924,6 +2954,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, ...@@ -2924,6 +2954,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
rt5670->pdata.dev_gpio = true; rt5670->pdata.dev_gpio = true;
dev_info(&i2c->dev, "quirk dev_gpio\n"); dev_info(&i2c->dev, "quirk dev_gpio\n");
} }
if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) {
rt5670->pdata.gpio1_is_ext_spk_en = true;
dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n");
}
if (rt5670_quirk & RT5670_IN2_DIFF) { if (rt5670_quirk & RT5670_IN2_DIFF) {
rt5670->pdata.in2_diff = true; rt5670->pdata.in2_diff = true;
dev_info(&i2c->dev, "quirk IN2_DIFF\n"); dev_info(&i2c->dev, "quirk IN2_DIFF\n");
...@@ -3023,6 +3057,13 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, ...@@ -3023,6 +3057,13 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
} }
if (rt5670->pdata.gpio1_is_ext_spk_en) {
regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1);
regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
}
if (rt5670->pdata.jd_mode) { if (rt5670->pdata.jd_mode) {
regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK,
RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
......
...@@ -757,7 +757,7 @@ ...@@ -757,7 +757,7 @@
#define RT5670_PWR_VREF2_BIT 4 #define RT5670_PWR_VREF2_BIT 4
#define RT5670_PWR_FV2 (0x1 << 3) #define RT5670_PWR_FV2 (0x1 << 3)
#define RT5670_PWR_FV2_BIT 3 #define RT5670_PWR_FV2_BIT 3
#define RT5670_LDO_SEL_MASK (0x3) #define RT5670_LDO_SEL_MASK (0x7)
#define RT5670_LDO_SEL_SFT 0 #define RT5670_LDO_SEL_SFT 0
/* Power Management for Analog 2 (0x64) */ /* Power Management for Analog 2 (0x64) */
......
...@@ -967,13 +967,12 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) ...@@ -967,13 +967,12 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
rt5682_enable_push_button_irq(component, false); rt5682_enable_push_button_irq(component, false);
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW);
if (snd_soc_dapm_get_pin_status(dapm, "MICBIAS")) if (!snd_soc_dapm_get_pin_status(dapm, "MICBIAS"))
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0); RT5682_PWR_ANLG_1, RT5682_PWR_MB, 0);
else if (!snd_soc_dapm_get_pin_status(dapm, "Vref2"))
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
RT5682_PWR_ANLG_1, RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0);
RT5682_PWR_VREF2 | RT5682_PWR_MB, 0);
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3,
RT5682_PWR_CBJ, 0); RT5682_PWR_CBJ, 0);
...@@ -992,16 +991,17 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, ...@@ -992,16 +991,17 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component,
rt5682->hs_jack = hs_jack; rt5682->hs_jack = hs_jack;
if (!rt5682->is_sdw) { if (!hs_jack) {
if (!hs_jack) { regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2,
regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, RT5682_JD1_EN_MASK, RT5682_JD1_DIS);
RT5682_JD1_EN_MASK, RT5682_JD1_DIS); regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL,
regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, RT5682_POW_JDH | RT5682_POW_JDL, 0);
RT5682_POW_JDH | RT5682_POW_JDL, 0); cancel_delayed_work_sync(&rt5682->jack_detect_work);
cancel_delayed_work_sync(&rt5682->jack_detect_work);
return 0;
}
return 0;
}
if (!rt5682->is_sdw) {
switch (rt5682->pdata.jd_src) { switch (rt5682->pdata.jd_src) {
case RT5682_JD1: case RT5682_JD1:
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
...@@ -1082,7 +1082,8 @@ void rt5682_jack_detect_handler(struct work_struct *work) ...@@ -1082,7 +1082,8 @@ void rt5682_jack_detect_handler(struct work_struct *work)
/* jack was out, report jack type */ /* jack was out, report jack type */
rt5682->jack_type = rt5682->jack_type =
rt5682_headset_detect(rt5682->component, 1); rt5682_headset_detect(rt5682->component, 1);
} else { } else if ((rt5682->jack_type & SND_JACK_HEADSET) ==
SND_JACK_HEADSET) {
/* jack is already in, report button event */ /* jack is already in, report button event */
rt5682->jack_type = SND_JACK_HEADSET; rt5682->jack_type = SND_JACK_HEADSET;
btn_type = rt5682_button_detect(rt5682->component); btn_type = rt5682_button_detect(rt5682->component);
...@@ -1608,8 +1609,7 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { ...@@ -1608,8 +1609,7 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = {
0, set_filter_clk, SND_SOC_DAPM_PRE_PMU), 0, set_filter_clk, SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0,
rt5682_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), rt5682_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, SND_SOC_DAPM_SUPPLY("Vref2", SND_SOC_NOPM, 0, 0, NULL, 0),
NULL, 0),
SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, NULL, 0),
/* ASRC */ /* ASRC */
...@@ -2492,6 +2492,15 @@ static int rt5682_wclk_prepare(struct clk_hw *hw) ...@@ -2492,6 +2492,15 @@ static int rt5682_wclk_prepare(struct clk_hw *hw)
snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS");
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1,
RT5682_PWR_MB, RT5682_PWR_MB); RT5682_PWR_MB, RT5682_PWR_MB);
snd_soc_dapm_force_enable_pin_unlocked(dapm, "Vref2");
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1,
RT5682_PWR_VREF2 | RT5682_PWR_FV2,
RT5682_PWR_VREF2);
usleep_range(55000, 60000);
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1,
RT5682_PWR_FV2, RT5682_PWR_FV2);
snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1"); snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1");
snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2F"); snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2F");
snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2B"); snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2B");
...@@ -2517,9 +2526,12 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw) ...@@ -2517,9 +2526,12 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw)
snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_mutex_lock(dapm);
snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS");
snd_soc_dapm_disable_pin_unlocked(dapm, "Vref2");
if (!rt5682->jack_type) if (!rt5682->jack_type)
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1,
RT5682_PWR_VREF2 | RT5682_PWR_FV2 |
RT5682_PWR_MB, 0); RT5682_PWR_MB, 0);
snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1"); snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1");
snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2F"); snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2F");
snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2B"); snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2B");
......
...@@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0), ...@@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
/* Boost mixer */ /* Boost mixer */
static const struct snd_kcontrol_new wm8974_boost_mixer[] = { static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 0), SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1),
}; };
/* Input PGA */ /* Input PGA */
...@@ -474,6 +474,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -474,6 +474,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
iface |= 0x0008; iface |= 0x0008;
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
if ((fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_IB_IF ||
(fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_NB_IF) {
return -EINVAL;
}
iface |= 0x00018; iface |= 0x00018;
break; break;
default: default:
......
...@@ -317,8 +317,8 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, ...@@ -317,8 +317,8 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
if (ret < 0) if (ret < 0)
goto out_put_node; goto out_put_node;
dai_link->dpcm_playback = 1; snd_soc_dai_link_set_capabilities(dai_link);
dai_link->dpcm_capture = 1;
dai_link->ops = &graph_ops; dai_link->ops = &graph_ops;
dai_link->init = asoc_simple_dai_init; dai_link->init = asoc_simple_dai_init;
......
...@@ -231,8 +231,8 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, ...@@ -231,8 +231,8 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
if (ret < 0) if (ret < 0)
goto out_put_node; goto out_put_node;
dai_link->dpcm_playback = 1; snd_soc_dai_link_set_capabilities(dai_link);
dai_link->dpcm_capture = 1;
dai_link->ops = &simple_ops; dai_link->ops = &simple_ops;
dai_link->init = asoc_simple_dai_init; dai_link->init = asoc_simple_dai_init;
......
...@@ -354,6 +354,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { ...@@ -354,6 +354,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
{ {
.name = "Codec DSP", .name = "Codec DSP",
.stream_name = "Wake on Voice", .stream_name = "Wake on Voice",
.capture_only = 1,
.ops = &bdw_rt5677_dsp_ops, .ops = &bdw_rt5677_dsp_ops,
SND_SOC_DAILINK_REG(dsp), SND_SOC_DAILINK_REG(dsp),
}, },
......
...@@ -543,8 +543,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) ...@@ -543,8 +543,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
if (cnt) { if (cnt) {
ret = device_add_properties(codec_dev, props); ret = device_add_properties(codec_dev, props);
if (ret) if (ret) {
put_device(codec_dev);
return ret; return ret;
}
} }
devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios); devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios);
......
...@@ -253,21 +253,20 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, ...@@ -253,21 +253,20 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
/* /*
* Default mode for SSP configuration is TDM 4 slot * Default mode for SSP configuration is TDM 4 slot. One board/design,
* the Lenovo Miix 2 10 uses not 1 but 2 codecs connected to SSP2. The
* second piggy-backed, output-only codec is inside the keyboard-dock
* (which has extra speakers). Unlike the main rt5672 codec, we cannot
* configure this codec, it is hard coded to use 2 channel 24 bit I2S.
* Since we only support 2 channels anyways, there is no need for TDM
* on any cht-bsw-rt5672 designs. So we simply use I2S 2ch everywhere.
*/ */
ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS); SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0) { if (ret < 0) {
dev_err(rtd->dev, "can't set format to TDM %d\n", ret); dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
return ret;
}
/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24);
if (ret < 0) {
dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret);
return ret; return ret;
} }
......
...@@ -72,7 +72,7 @@ config SND_SOC_QDSP6_ASM_DAI ...@@ -72,7 +72,7 @@ config SND_SOC_QDSP6_ASM_DAI
config SND_SOC_QDSP6 config SND_SOC_QDSP6
tristate "SoC ALSA audio driver for QDSP6" tristate "SoC ALSA audio driver for QDSP6"
depends on QCOM_APR && HAS_DMA depends on QCOM_APR
select SND_SOC_QDSP6_COMMON select SND_SOC_QDSP6_COMMON
select SND_SOC_QDSP6_CORE select SND_SOC_QDSP6_CORE
select SND_SOC_QDSP6_AFE select SND_SOC_QDSP6_AFE
......
...@@ -219,19 +219,32 @@ static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, ...@@ -219,19 +219,32 @@ static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int rockchip_sound_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
8000, 96000);
}
static const struct snd_soc_ops rockchip_sound_max98357a_ops = { static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
.startup = rockchip_sound_startup,
.hw_params = rockchip_sound_max98357a_hw_params, .hw_params = rockchip_sound_max98357a_hw_params,
}; };
static const struct snd_soc_ops rockchip_sound_rt5514_ops = { static const struct snd_soc_ops rockchip_sound_rt5514_ops = {
.startup = rockchip_sound_startup,
.hw_params = rockchip_sound_rt5514_hw_params, .hw_params = rockchip_sound_rt5514_hw_params,
}; };
static const struct snd_soc_ops rockchip_sound_da7219_ops = { static const struct snd_soc_ops rockchip_sound_da7219_ops = {
.startup = rockchip_sound_startup,
.hw_params = rockchip_sound_da7219_hw_params, .hw_params = rockchip_sound_da7219_hw_params,
}; };
static const struct snd_soc_ops rockchip_sound_dmic_ops = { static const struct snd_soc_ops rockchip_sound_dmic_ops = {
.startup = rockchip_sound_startup,
.hw_params = rockchip_sound_dmic_hw_params, .hw_params = rockchip_sound_dmic_hw_params,
}; };
......
...@@ -2572,6 +2572,33 @@ int snd_soc_register_component(struct device *dev, ...@@ -2572,6 +2572,33 @@ int snd_soc_register_component(struct device *dev,
} }
EXPORT_SYMBOL_GPL(snd_soc_register_component); EXPORT_SYMBOL_GPL(snd_soc_register_component);
/**
* snd_soc_unregister_component_by_driver - Unregister component using a given driver
* from the ASoC core
*
* @dev: The device to unregister
* @component_driver: The component driver to unregister
*/
void snd_soc_unregister_component_by_driver(struct device *dev,
const struct snd_soc_component_driver *component_driver)
{
struct snd_soc_component *component;
if (!component_driver)
return;
mutex_lock(&client_mutex);
component = snd_soc_lookup_component_nolocked(dev, component_driver->name);
if (!component)
goto out;
snd_soc_del_component_unlocked(component);
out:
mutex_unlock(&client_mutex);
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver);
/** /**
* snd_soc_unregister_component - Unregister all related component * snd_soc_unregister_component - Unregister all related component
* from the ASoC core * from the ASoC core
......
...@@ -391,6 +391,44 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir) ...@@ -391,6 +391,44 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
return stream->channels_min; return stream->channels_min;
} }
/*
* snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs
*/
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
{
struct snd_soc_dai_link_component *cpu;
struct snd_soc_dai_link_component *codec;
struct snd_soc_dai *dai;
bool supported[SNDRV_PCM_STREAM_LAST + 1];
int direction;
int i;
for_each_pcm_streams(direction) {
supported[direction] = true;
for_each_link_cpus(dai_link, i, cpu) {
dai = snd_soc_find_dai(cpu);
if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {
supported[direction] = false;
break;
}
}
if (!supported[direction])
continue;
for_each_link_codecs(dai_link, i, codec) {
dai = snd_soc_find_dai(codec);
if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {
supported[direction] = false;
break;
}
}
}
dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK];
dai_link->dpcm_capture = supported[SNDRV_PCM_STREAM_CAPTURE];
}
EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities);
void snd_soc_dai_action(struct snd_soc_dai *dai, void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action) int stream, int action)
{ {
......
...@@ -48,7 +48,9 @@ EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai); ...@@ -48,7 +48,9 @@ EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai);
static void devm_component_release(struct device *dev, void *res) static void devm_component_release(struct device *dev, void *res)
{ {
snd_soc_unregister_component(*(struct device **)res); const struct snd_soc_component_driver **cmpnt_drv = res;
snd_soc_unregister_component_by_driver(dev, *cmpnt_drv);
} }
/** /**
...@@ -65,7 +67,7 @@ int devm_snd_soc_register_component(struct device *dev, ...@@ -65,7 +67,7 @@ int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *cmpnt_drv, const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai) struct snd_soc_dai_driver *dai_drv, int num_dai)
{ {
struct device **ptr; const struct snd_soc_component_driver **ptr;
int ret; int ret;
ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL);
...@@ -74,7 +76,7 @@ int devm_snd_soc_register_component(struct device *dev, ...@@ -74,7 +76,7 @@ int devm_snd_soc_register_component(struct device *dev,
ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai);
if (ret == 0) { if (ret == 0) {
*ptr = dev; *ptr = cmpnt_drv;
devres_add(dev, ptr); devres_add(dev, ptr);
} else { } else {
devres_free(ptr); devres_free(ptr);
......
...@@ -478,7 +478,7 @@ void snd_dmaengine_pcm_unregister(struct device *dev) ...@@ -478,7 +478,7 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
pcm = soc_component_to_pcm(component); pcm = soc_component_to_pcm(component);
snd_soc_unregister_component(dev); snd_soc_unregister_component_by_driver(dev, component->driver);
dmaengine_pcm_release_chan(pcm); dmaengine_pcm_release_chan(pcm);
kfree(pcm); kfree(pcm);
} }
......
...@@ -1261,17 +1261,29 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, ...@@ -1261,17 +1261,29 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list); list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list);
ret = soc_tplg_add_route(tplg, routes[i]); ret = soc_tplg_add_route(tplg, routes[i]);
if (ret < 0) if (ret < 0) {
/*
* this route was added to the list, it will
* be freed in remove_route() so increment the
* counter to skip it in the error handling
* below.
*/
i++;
break; break;
}
/* add route, but keep going if some fail */ /* add route, but keep going if some fail */
snd_soc_dapm_add_routes(dapm, routes[i], 1); snd_soc_dapm_add_routes(dapm, routes[i], 1);
} }
/* free memory allocated for all dapm routes in case of error */ /*
if (ret < 0) * free memory allocated for all dapm routes not added to the
for (i = 0; i < count ; i++) * list in case of error
kfree(routes[i]); */
if (ret < 0) {
while (i < count)
kfree(routes[i++]);
}
/* /*
* free pointer to array of dapm routes as this is no longer needed. * free pointer to array of dapm routes as this is no longer needed.
...@@ -1359,7 +1371,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( ...@@ -1359,7 +1371,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n", dev_err(tplg->dev, "ASoC: failed to init %s\n",
mc->hdr.name); mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc[i]);
goto err_sm; goto err_sm;
} }
} }
...@@ -1367,6 +1378,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( ...@@ -1367,6 +1378,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
err_sm: err_sm:
for (; i >= 0; i--) { for (; i >= 0; i--) {
soc_tplg_free_tlv(tplg, &kc[i]);
sm = (struct soc_mixer_control *)kc[i].private_value; sm = (struct soc_mixer_control *)kc[i].private_value;
kfree(sm); kfree(sm);
kfree(kc[i].name); kfree(kc[i].name);
......
...@@ -345,15 +345,15 @@ int snd_sof_device_remove(struct device *dev) ...@@ -345,15 +345,15 @@ int snd_sof_device_remove(struct device *dev)
struct snd_sof_pdata *pdata = sdev->pdata; struct snd_sof_pdata *pdata = sdev->pdata;
int ret; int ret;
ret = snd_sof_dsp_power_down_notify(sdev);
if (ret < 0)
dev_warn(dev, "error: %d failed to prepare DSP for device removal",
ret);
if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
cancel_work_sync(&sdev->probe_work); cancel_work_sync(&sdev->probe_work);
if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
ret = snd_sof_dsp_power_down_notify(sdev);
if (ret < 0)
dev_warn(dev, "error: %d failed to prepare DSP for device removal",
ret);
snd_sof_fw_unload(sdev); snd_sof_fw_unload(sdev);
snd_sof_ipc_free(sdev); snd_sof_ipc_free(sdev);
snd_sof_free_debug(sdev); snd_sof_free_debug(sdev);
......
...@@ -375,6 +375,14 @@ static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev, ...@@ -375,6 +375,14 @@ static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev,
static struct snd_soc_dai_driver imx8_dai[] = { static struct snd_soc_dai_driver imx8_dai[] = {
{ {
.name = "esai-port", .name = "esai-port",
.playback = {
.channels_min = 1,
.channels_max = 8,
},
.capture = {
.channels_min = 1,
.channels_max = 8,
},
}, },
}; };
......
...@@ -240,6 +240,14 @@ static int imx8m_ipc_pcm_params(struct snd_sof_dev *sdev, ...@@ -240,6 +240,14 @@ static int imx8m_ipc_pcm_params(struct snd_sof_dev *sdev,
static struct snd_soc_dai_driver imx8m_dai[] = { static struct snd_soc_dai_driver imx8m_dai[] = {
{ {
.name = "sai-port", .name = "sai-port",
.playback = {
.channels_min = 1,
.channels_max = 32,
},
.capture = {
.channels_min = 1,
.channels_max = 32,
},
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment