Commit c8d2dcb3 authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-v5.4-rc4' of...

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

ASoC: Fixes for v5.4

A collection of fixes that have arrived since the merge window.  There
are a small number of core fixes here but they are smaller ones around
error handling.
parents 83629532 95a32c98
...@@ -135,9 +135,9 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, ...@@ -135,9 +135,9 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
struct link_info *li); struct link_info *li);
#ifdef DEBUG #ifdef DEBUG
inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
char *name, char *name,
struct asoc_simple_dai *dai) struct asoc_simple_dai *dai)
{ {
struct device *dev = simple_priv_to_dev(priv); struct device *dev = simple_priv_to_dev(priv);
...@@ -167,7 +167,7 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, ...@@ -167,7 +167,7 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk)); dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
} }
inline void asoc_simple_debug_info(struct asoc_simple_priv *priv) static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
{ {
struct snd_soc_card *card = simple_priv_to_card(priv); struct snd_soc_card *card = simple_priv_to_card(priv);
struct device *dev = simple_priv_to_dev(priv); struct device *dev = simple_priv_to_dev(priv);
......
...@@ -901,16 +901,20 @@ static void max98373_slot_config(struct i2c_client *i2c, ...@@ -901,16 +901,20 @@ static void max98373_slot_config(struct i2c_client *i2c,
max98373->i_slot = value & 0xF; max98373->i_slot = value & 0xF;
else else
max98373->i_slot = 1; max98373->i_slot = 1;
if (dev->of_node) {
max98373->reset_gpio = of_get_named_gpio(dev->of_node, max98373->reset_gpio = of_get_named_gpio(dev->of_node,
"maxim,reset-gpio", 0); "maxim,reset-gpio", 0);
if (!gpio_is_valid(max98373->reset_gpio)) { if (!gpio_is_valid(max98373->reset_gpio)) {
dev_err(dev, "Looking up %s property in node %s failed %d\n", dev_err(dev, "Looking up %s property in node %s failed %d\n",
"maxim,reset-gpio", dev->of_node->full_name, "maxim,reset-gpio", dev->of_node->full_name,
max98373->reset_gpio); max98373->reset_gpio);
} else {
dev_dbg(dev, "maxim,reset-gpio=%d",
max98373->reset_gpio);
}
} else { } else {
dev_dbg(dev, "maxim,reset-gpio=%d", /* this makes reset_gpio as invalid */
max98373->reset_gpio); max98373->reset_gpio = -1;
} }
if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value))
......
...@@ -243,6 +243,10 @@ static const char *const rx_mix1_text[] = { ...@@ -243,6 +243,10 @@ static const char *const rx_mix1_text[] = {
"ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
}; };
static const char * const rx_mix2_text[] = {
"ZERO", "IIR1", "IIR2"
};
static const char *const dec_mux_text[] = { static const char *const dec_mux_text[] = {
"ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2" "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2"
}; };
...@@ -270,6 +274,16 @@ static const struct soc_enum rx3_mix1_inp_enum[] = { ...@@ -270,6 +274,16 @@ static const struct soc_enum rx3_mix1_inp_enum[] = {
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text), SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text),
}; };
/* RX1 MIX2 */
static const struct soc_enum rx_mix2_inp1_chain_enum =
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B3_CTL,
0, 3, rx_mix2_text);
/* RX2 MIX2 */
static const struct soc_enum rx2_mix2_inp1_chain_enum =
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B3_CTL,
0, 3, rx_mix2_text);
/* DEC */ /* DEC */
static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE( static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE(
LPASS_CDC_CONN_TX_B1_CTL, 0, 6, dec_mux_text); LPASS_CDC_CONN_TX_B1_CTL, 0, 6, dec_mux_text);
...@@ -309,6 +323,10 @@ static const struct snd_kcontrol_new rx3_mix1_inp2_mux = SOC_DAPM_ENUM( ...@@ -309,6 +323,10 @@ static const struct snd_kcontrol_new rx3_mix1_inp2_mux = SOC_DAPM_ENUM(
"RX3 MIX1 INP2 Mux", rx3_mix1_inp_enum[1]); "RX3 MIX1 INP2 Mux", rx3_mix1_inp_enum[1]);
static const struct snd_kcontrol_new rx3_mix1_inp3_mux = SOC_DAPM_ENUM( static const struct snd_kcontrol_new rx3_mix1_inp3_mux = SOC_DAPM_ENUM(
"RX3 MIX1 INP3 Mux", rx3_mix1_inp_enum[2]); "RX3 MIX1 INP3 Mux", rx3_mix1_inp_enum[2]);
static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM(
"RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum);
static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM(
"RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */ /* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */
static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0);
...@@ -740,6 +758,10 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { ...@@ -740,6 +758,10 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
&rx3_mix1_inp2_mux), &rx3_mix1_inp2_mux),
SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0,
&rx3_mix1_inp3_mux), &rx3_mix1_inp3_mux),
SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
&rx1_mix2_inp1_mux),
SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
&rx2_mix2_inp1_mux),
SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux), SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux),
SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux), SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux),
......
...@@ -1770,6 +1770,9 @@ static int rt5651_detect_headset(struct snd_soc_component *component) ...@@ -1770,6 +1770,9 @@ static int rt5651_detect_headset(struct snd_soc_component *component)
static bool rt5651_support_button_press(struct rt5651_priv *rt5651) static bool rt5651_support_button_press(struct rt5651_priv *rt5651)
{ {
if (!rt5651->hp_jack)
return false;
/* Button press support only works with internal jack-detection */ /* Button press support only works with internal jack-detection */
return (rt5651->hp_jack->status & SND_JACK_MICROPHONE) && return (rt5651->hp_jack->status & SND_JACK_MICROPHONE) &&
rt5651->gpiod_hp_det == NULL; rt5651->gpiod_hp_det == NULL;
......
...@@ -995,6 +995,16 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, ...@@ -995,6 +995,16 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component,
{ {
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
rt5682->hs_jack = hs_jack;
if (!hs_jack) {
regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2,
RT5682_JD1_EN_MASK, RT5682_JD1_DIS);
regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL,
RT5682_POW_JDH | RT5682_POW_JDL, 0);
return 0;
}
switch (rt5682->pdata.jd_src) { switch (rt5682->pdata.jd_src) {
case RT5682_JD1: case RT5682_JD1:
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_2, snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_2,
...@@ -1032,8 +1042,6 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, ...@@ -1032,8 +1042,6 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component,
break; break;
} }
rt5682->hs_jack = hs_jack;
return 0; return 0;
} }
......
...@@ -533,13 +533,10 @@ static SOC_ENUM_SINGLE_DECL(dac_osr, ...@@ -533,13 +533,10 @@ static SOC_ENUM_SINGLE_DECL(dac_osr,
static SOC_ENUM_SINGLE_DECL(adc_osr, static SOC_ENUM_SINGLE_DECL(adc_osr,
WM8994_OVERSAMPLING, 1, osr_text); WM8994_OVERSAMPLING, 1, osr_text);
static const struct snd_kcontrol_new wm8994_snd_controls[] = { static const struct snd_kcontrol_new wm8994_common_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1_ADC1_RIGHT_VOLUME,
1, 119, 0, digital_tlv), 1, 119, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
WM8994_AIF1_ADC2_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME, SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF2_ADC_RIGHT_VOLUME,
1, 119, 0, digital_tlv), 1, 119, 0, digital_tlv),
...@@ -556,8 +553,6 @@ SOC_ENUM("AIF2DACR Source", aif2dacr_src), ...@@ -556,8 +553,6 @@ SOC_ENUM("AIF2DACR Source", aif2dacr_src),
SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME, SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME, SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv), WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
...@@ -565,17 +560,12 @@ SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv), ...@@ -565,17 +560,12 @@ SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv), SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0), SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0), SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2), WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1), WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0), WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2), WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1), WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0), WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
...@@ -594,9 +584,6 @@ SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0), ...@@ -594,9 +584,6 @@ SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf), SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0), SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf), SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0), SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
...@@ -637,6 +624,24 @@ SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2, ...@@ -637,6 +624,24 @@ SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2,
8, 1, 0), 8, 1, 0),
}; };
/* Controls not available on WM1811 */
static const struct snd_kcontrol_new wm8994_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
WM8994_AIF1_ADC2_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
};
static const struct snd_kcontrol_new wm8994_eq_controls[] = { static const struct snd_kcontrol_new wm8994_eq_controls[] = {
SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0, SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
eq_tlv), eq_tlv),
...@@ -4258,13 +4263,15 @@ static int wm8994_component_probe(struct snd_soc_component *component) ...@@ -4258,13 +4263,15 @@ static int wm8994_component_probe(struct snd_soc_component *component)
wm8994_handle_pdata(wm8994); wm8994_handle_pdata(wm8994);
wm_hubs_add_analogue_controls(component); wm_hubs_add_analogue_controls(component);
snd_soc_add_component_controls(component, wm8994_snd_controls, snd_soc_add_component_controls(component, wm8994_common_snd_controls,
ARRAY_SIZE(wm8994_snd_controls)); ARRAY_SIZE(wm8994_common_snd_controls));
snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
ARRAY_SIZE(wm8994_dapm_widgets)); ARRAY_SIZE(wm8994_dapm_widgets));
switch (control->type) { switch (control->type) {
case WM8994: case WM8994:
snd_soc_add_component_controls(component, wm8994_snd_controls,
ARRAY_SIZE(wm8994_snd_controls));
snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
ARRAY_SIZE(wm8994_specific_dapm_widgets)); ARRAY_SIZE(wm8994_specific_dapm_widgets));
if (control->revision < 4) { if (control->revision < 4) {
...@@ -4284,8 +4291,10 @@ static int wm8994_component_probe(struct snd_soc_component *component) ...@@ -4284,8 +4291,10 @@ static int wm8994_component_probe(struct snd_soc_component *component)
} }
break; break;
case WM8958: case WM8958:
snd_soc_add_component_controls(component, wm8994_snd_controls,
ARRAY_SIZE(wm8994_snd_controls));
snd_soc_add_component_controls(component, wm8958_snd_controls, snd_soc_add_component_controls(component, wm8958_snd_controls,
ARRAY_SIZE(wm8958_snd_controls)); ARRAY_SIZE(wm8958_snd_controls));
snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
ARRAY_SIZE(wm8958_dapm_widgets)); ARRAY_SIZE(wm8958_dapm_widgets));
if (control->revision < 1) { if (control->revision < 1) {
......
...@@ -1259,8 +1259,7 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) ...@@ -1259,8 +1259,7 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len)
} }
if (in) { if (in) {
if (in & WMFW_CTL_FLAG_READABLE) out |= rd;
out |= rd;
if (in & WMFW_CTL_FLAG_WRITEABLE) if (in & WMFW_CTL_FLAG_WRITEABLE)
out |= wr; out |= wr;
if (in & WMFW_CTL_FLAG_VOLATILE) if (in & WMFW_CTL_FLAG_VOLATILE)
...@@ -3697,11 +3696,16 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) ...@@ -3697,11 +3696,16 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp)
u32 xmalg, addr, magic; u32 xmalg, addr, magic;
int i, ret; int i, ret;
alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
if (!alg_region) {
adsp_err(dsp, "No algorithm region found\n");
return -EINVAL;
}
buf = wm_adsp_buffer_alloc(dsp); buf = wm_adsp_buffer_alloc(dsp);
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
xmalg = dsp->ops->sys_config_size / sizeof(__be32); xmalg = dsp->ops->sys_config_size / sizeof(__be32);
addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); addr = alg_region->base + xmalg + ALG_XM_FIELD(magic);
......
...@@ -308,6 +308,9 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { ...@@ -308,6 +308,9 @@ static const struct snd_soc_dapm_widget sof_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_SPK("Spk", NULL), SND_SOC_DAPM_SPK("Spk", NULL),
};
static const struct snd_soc_dapm_widget dmic_widgets[] = {
SND_SOC_DAPM_MIC("SoC DMIC", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL),
}; };
...@@ -318,10 +321,6 @@ static const struct snd_soc_dapm_route sof_map[] = { ...@@ -318,10 +321,6 @@ static const struct snd_soc_dapm_route sof_map[] = {
/* other jacks */ /* other jacks */
{ "IN1P", NULL, "Headset Mic" }, { "IN1P", NULL, "Headset Mic" },
/* digital mics */
{"DMic", NULL, "SoC DMIC"},
}; };
static const struct snd_soc_dapm_route speaker_map[] = { static const struct snd_soc_dapm_route speaker_map[] = {
...@@ -329,6 +328,11 @@ static const struct snd_soc_dapm_route speaker_map[] = { ...@@ -329,6 +328,11 @@ static const struct snd_soc_dapm_route speaker_map[] = {
{ "Spk", NULL, "Speaker" }, { "Spk", NULL, "Speaker" },
}; };
static const struct snd_soc_dapm_route dmic_map[] = {
/* digital mics */
{"DMic", NULL, "SoC DMIC"},
};
static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
...@@ -342,6 +346,28 @@ static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) ...@@ -342,6 +346,28 @@ static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret; return ret;
} }
static int dmic_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int ret;
ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
ARRAY_SIZE(dmic_widgets));
if (ret) {
dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
/* Don't need to add routes if widget addition failed */
return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
ARRAY_SIZE(dmic_map));
if (ret)
dev_err(card->dev, "DMic map addition failed: %d\n", ret);
return ret;
}
/* sof audio machine driver for rt5682 codec */ /* sof audio machine driver for rt5682 codec */
static struct snd_soc_card sof_audio_card_rt5682 = { static struct snd_soc_card sof_audio_card_rt5682 = {
.name = "sof_rt5682", .name = "sof_rt5682",
...@@ -445,6 +471,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -445,6 +471,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].name = "dmic01"; links[id].name = "dmic01";
links[id].cpus = &cpus[id]; links[id].cpus = &cpus[id];
links[id].cpus->dai_name = "DMIC01 Pin"; links[id].cpus->dai_name = "DMIC01 Pin";
links[id].init = dmic_init;
if (dmic_be_num > 1) { if (dmic_be_num > 1) {
/* set up 2 BE links at most */ /* set up 2 BE links at most */
links[id + 1].name = "dmic16k"; links[id + 1].name = "dmic16k";
...@@ -576,6 +603,15 @@ static int sof_audio_probe(struct platform_device *pdev) ...@@ -576,6 +603,15 @@ static int sof_audio_probe(struct platform_device *pdev)
/* need to get main clock from pmc */ /* need to get main clock from pmc */
if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
if (IS_ERR(ctx->mclk)) {
ret = PTR_ERR(ctx->mclk);
dev_err(&pdev->dev,
"Failed to get MCLK from pmc_plt_clk_3: %d\n",
ret);
return ret;
}
ret = clk_prepare_enable(ctx->mclk); ret = clk_prepare_enable(ctx->mclk);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
...@@ -621,8 +657,24 @@ static int sof_audio_probe(struct platform_device *pdev) ...@@ -621,8 +657,24 @@ static int sof_audio_probe(struct platform_device *pdev)
&sof_audio_card_rt5682); &sof_audio_card_rt5682);
} }
static int sof_rt5682_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct snd_soc_component *component = NULL;
for_each_card_components(card, component) {
if (!strcmp(component->name, rt5682_component[0].name)) {
snd_soc_component_set_jack(component, NULL, NULL);
break;
}
}
return 0;
}
static struct platform_driver sof_audio = { static struct platform_driver sof_audio = {
.probe = sof_audio_probe, .probe = sof_audio_probe,
.remove = sof_rt5682_remove,
.driver = { .driver = {
.name = "sof_rt5682", .name = "sof_rt5682",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
......
...@@ -677,7 +677,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) ...@@ -677,7 +677,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
ret = rockchip_pcm_platform_register(&pdev->dev); ret = rockchip_pcm_platform_register(&pdev->dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Could not register PCM\n"); dev_err(&pdev->dev, "Could not register PCM\n");
return ret; goto err_suspend;
} }
return 0; return 0;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// Author: Claude <claude@insginal.co.kr> // Author: Claude <claude@insginal.co.kr>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h> #include <linux/clk.h>
...@@ -74,6 +75,17 @@ static struct snd_soc_card arndale_rt5631 = { ...@@ -74,6 +75,17 @@ static struct snd_soc_card arndale_rt5631 = {
.num_links = ARRAY_SIZE(arndale_rt5631_dai), .num_links = ARRAY_SIZE(arndale_rt5631_dai),
}; };
static void arndale_put_of_nodes(struct snd_soc_card *card)
{
struct snd_soc_dai_link *dai_link;
int i;
for_each_card_prelinks(card, i, dai_link) {
of_node_put(dai_link->cpus->of_node);
of_node_put(dai_link->codecs->of_node);
}
}
static int arndale_audio_probe(struct platform_device *pdev) static int arndale_audio_probe(struct platform_device *pdev)
{ {
int n, ret; int n, ret;
...@@ -103,18 +115,31 @@ static int arndale_audio_probe(struct platform_device *pdev) ...@@ -103,18 +115,31 @@ static int arndale_audio_probe(struct platform_device *pdev)
if (!arndale_rt5631_dai[0].codecs->of_node) { if (!arndale_rt5631_dai[0].codecs->of_node) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Property 'samsung,audio-codec' missing or invalid\n"); "Property 'samsung,audio-codec' missing or invalid\n");
return -EINVAL; ret = -EINVAL;
goto err_put_of_nodes;
} }
} }
ret = devm_snd_soc_register_card(card->dev, card); ret = devm_snd_soc_register_card(card->dev, card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
goto err_put_of_nodes;
}
return 0;
if (ret) err_put_of_nodes:
dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); arndale_put_of_nodes(card);
return ret; return ret;
} }
static int arndale_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
arndale_put_of_nodes(card);
return 0;
}
static const struct of_device_id samsung_arndale_rt5631_of_match[] __maybe_unused = { static const struct of_device_id samsung_arndale_rt5631_of_match[] __maybe_unused = {
{ .compatible = "samsung,arndale-rt5631", }, { .compatible = "samsung,arndale-rt5631", },
{ .compatible = "samsung,arndale-alc5631", }, { .compatible = "samsung,arndale-alc5631", },
...@@ -129,6 +154,7 @@ static struct platform_driver arndale_audio_driver = { ...@@ -129,6 +154,7 @@ static struct platform_driver arndale_audio_driver = {
.of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match),
}, },
.probe = arndale_audio_probe, .probe = arndale_audio_probe,
.remove = arndale_audio_remove,
}; };
module_platform_driver(arndale_audio_driver); module_platform_driver(arndale_audio_driver);
......
...@@ -761,6 +761,7 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -761,6 +761,7 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
} }
/* set format */ /* set format */
rdai->bit_clk_inv = 0;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
rdai->sys_delay = 0; rdai->sys_delay = 0;
......
...@@ -1070,7 +1070,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -1070,7 +1070,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return ret; return ret;
} }
snd_soc_dai_trigger(cpu_dai, substream, cmd); ret = snd_soc_dai_trigger(cpu_dai, substream, cmd);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1097,7 +1097,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream, ...@@ -1097,7 +1097,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
return ret; return ret;
} }
snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd); ret = snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1146,6 +1146,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, ...@@ -1146,6 +1146,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
{ {
struct snd_soc_dpcm *dpcm; struct snd_soc_dpcm *dpcm;
unsigned long flags; unsigned long flags;
char *name;
/* only add new dpcms */ /* only add new dpcms */
for_each_dpcm_be(fe, stream, dpcm) { for_each_dpcm_be(fe, stream, dpcm) {
...@@ -1171,9 +1172,15 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, ...@@ -1171,9 +1172,15 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
stream ? "<-" : "->", be->dai_link->name); stream ? "<-" : "->", be->dai_link->name);
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
dpcm->debugfs_state = debugfs_create_dir(be->dai_link->name, name = kasprintf(GFP_KERNEL, "%s:%s", be->dai_link->name,
fe->debugfs_dpcm_root); stream ? "capture" : "playback");
debugfs_create_u32("state", 0644, dpcm->debugfs_state, &dpcm->state); if (name) {
dpcm->debugfs_state = debugfs_create_dir(name,
fe->debugfs_dpcm_root);
debugfs_create_u32("state", 0644, dpcm->debugfs_state,
&dpcm->state);
kfree(name);
}
#endif #endif
return 1; return 1;
} }
......
...@@ -1582,7 +1582,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1582,7 +1582,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
/* map user to kernel widget ID */ /* map user to kernel widget ID */
template.id = get_widget_id(le32_to_cpu(w->id)); template.id = get_widget_id(le32_to_cpu(w->id));
if (template.id < 0) if ((int)template.id < 0)