diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/msm8916-wcd-digital.c | 46 | ||||
-rw-r--r-- | sound/soc/codecs/rt274.c | 9 | ||||
-rw-r--r-- | sound/soc/codecs/rt286.c | 17 | ||||
-rw-r--r-- | sound/soc/codecs/rt286.h | 2 | ||||
-rw-r--r-- | sound/soc/codecs/rt298.c | 17 | ||||
-rw-r--r-- | sound/soc/codecs/rt298.h | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9335.c | 81 | ||||
-rw-r--r-- | sound/soc/intel/boards/broadwell.c | 6 | ||||
-rw-r--r-- | sound/soc/intel/boards/bxt_rt298.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/boards/skl_rt286.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-card.c | 6 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 1 | ||||
-rw-r--r-- | sound/soc/sof/debug.c | 5 | ||||
-rw-r--r-- | sound/soc/sof/ipc3-dtrace.c | 50 | ||||
-rw-r--r-- | sound/soc/sof/ipc3.c | 2 | ||||
-rw-r--r-- | sound/soc/sof/sof-priv.h | 2 |
16 files changed, 129 insertions, 121 deletions
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 20a07c92b2fc..098a58990f07 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -328,8 +328,8 @@ static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_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 */ -static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); +/* Digital Gain control -84 dB to +40 dB in 1 dB steps */ +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); /* Cutoff Freq for High Pass Filter at -3dB */ static const char * const hpf_cutoff_text[] = { @@ -510,15 +510,15 @@ static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum), SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum), SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0), @@ -553,22 +553,22 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3), WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4), WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5), - SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, + -84, 40, digital_gain), }; diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index ab093bdb5552..a5615e94ec7d 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -980,14 +980,11 @@ static int rt274_probe(struct snd_soc_component *component) struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); rt274->component = component; + INIT_DELAYED_WORK(&rt274->jack_detect_work, rt274_jack_detect_work); - if (rt274->i2c->irq) { - INIT_DELAYED_WORK(&rt274->jack_detect_work, - rt274_jack_detect_work); + if (rt274->i2c->irq) schedule_delayed_work(&rt274->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index ad8ea1fa7c23..0534a073ee69 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -311,7 +311,8 @@ static void rt286_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt286_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); @@ -335,7 +336,6 @@ int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *j return 0; } -EXPORT_SYMBOL_GPL(rt286_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -947,17 +947,11 @@ static int rt286_probe(struct snd_soc_component *component) struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); rt286->component = component; + INIT_DELAYED_WORK(&rt286->jack_detect_work, rt286_jack_detect_work); - if (rt286->i2c->irq) { - regmap_update_bits(rt286->regmap, - RT286_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt286->jack_detect_work, - rt286_jack_detect_work); + if (rt286->i2c->irq) schedule_delayed_work(&rt286->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(50)); return 0; } @@ -1055,6 +1049,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt286 = { .suspend = rt286_suspend, .resume = rt286_resume, .set_bias_level = rt286_set_bias_level, + .set_jack = rt286_mic_detect, .controls = rt286_snd_controls, .num_controls = ARRAY_SIZE(rt286_snd_controls), .dapm_widgets = rt286_dapm_widgets, diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index f27a4e71d5b6..4b7a3bd6043d 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h @@ -196,7 +196,5 @@ enum { RT286_AIFS, }; -int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); - #endif /* __RT286_H__ */ diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index c291786dc82d..1a27e5e63289 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -326,7 +326,8 @@ static void rt298_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt298_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm; @@ -358,7 +359,6 @@ int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *j return 0; } -EXPORT_SYMBOL_GPL(rt298_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -1011,17 +1011,11 @@ static int rt298_probe(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); rt298->component = component; + INIT_DELAYED_WORK(&rt298->jack_detect_work, rt298_jack_detect_work); - if (rt298->i2c->irq) { - regmap_update_bits(rt298->regmap, - RT298_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt298->jack_detect_work, - rt298_jack_detect_work); + if (rt298->i2c->irq) schedule_delayed_work(&rt298->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } @@ -1120,6 +1114,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .suspend = rt298_suspend, .resume = rt298_resume, .set_bias_level = rt298_set_bias_level, + .set_jack = rt298_mic_detect, .controls = rt298_snd_controls, .num_controls = ARRAY_SIZE(rt298_snd_controls), .dapm_widgets = rt298_dapm_widgets, diff --git a/sound/soc/codecs/rt298.h b/sound/soc/codecs/rt298.h index ed2b8fd87f4c..f1be9c135401 100644 --- a/sound/soc/codecs/rt298.h +++ b/sound/soc/codecs/rt298.h @@ -207,7 +207,5 @@ enum { RT298_AIFS, }; -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); - #endif /* __RT298_H__ */ diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index e1b693048084..4a982770dbab 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -2253,51 +2253,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, static const struct snd_kcontrol_new wcd9335_snd_controls[] = { /* -84dB min - 40dB max */ - SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", - WCD9335_CDC_RX0_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", - WCD9335_CDC_RX1_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", - WCD9335_CDC_RX2_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", - WCD9335_CDC_RX3_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", - WCD9335_CDC_RX4_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", - WCD9335_CDC_RX5_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", - WCD9335_CDC_RX6_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", - WCD9335_CDC_RX7_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", - WCD9335_CDC_RX8_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL, + -84, 40, digital_gain), SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index b29d77dfb281..48bf3241b3e6 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -75,7 +75,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - rt286_mic_detect(component, &broadwell_headset); + snd_soc_component_set_jack(component, &broadwell_headset, NULL); return 0; } @@ -235,7 +235,7 @@ static void broadwell_disable_jack(struct snd_soc_card *card) if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); - rt286_mic_detect(component, NULL); + snd_soc_component_set_jack(component, NULL, NULL); break; } } @@ -255,7 +255,7 @@ static int broadwell_resume(struct snd_soc_card *card){ if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "enabling jack detect for resume.\n"); - rt286_mic_detect(component, &broadwell_headset); + snd_soc_component_set_jack(component, &broadwell_headset, NULL); break; } } diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 75995d17597d..4bd93c3ba377 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -176,7 +176,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - rt298_mic_detect(component, &broxton_headset); + snd_soc_component_set_jack(component, &broxton_headset, NULL); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index e9f9520dcea4..4f3d655e2bfa 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -133,7 +133,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - rt286_mic_detect(component, &skylake_headset); + snd_soc_component_set_jack(component, &skylake_headset, NULL); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); diff --git a/sound/soc/soc-card.c b/sound/soc/soc-card.c index 4158f5aacfd3..285ab4c9c716 100644 --- a/sound/soc/soc-card.c +++ b/sound/soc/soc-card.c @@ -197,6 +197,12 @@ int snd_soc_card_late_probe(struct snd_soc_card *card) return 0; } +void snd_soc_card_fixup_controls(struct snd_soc_card *card) +{ + if (card->fixup_controls) + card->fixup_controls(card); +} + int snd_soc_card_remove(struct snd_soc_card *card) { int ret = 0; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 227540851ded..57f7105c12b7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2066,6 +2066,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card) goto probe_end; snd_soc_dapm_new_widgets(card); + snd_soc_card_fixup_controls(card); ret = snd_card_register(card->snd_card); if (ret < 0) { diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index cf1271eb29b2..c5d797e97c02 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -428,7 +428,7 @@ static void snd_sof_ipc_dump(struct snd_sof_dev *sdev) } } -void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev) +void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg) { if (IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT) || sof_debug_check_flag(SOF_DBG_RETAIN_CTX)) { @@ -441,8 +441,7 @@ void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev) /* dump vital information to the logs */ snd_sof_ipc_dump(sdev); - snd_sof_dsp_dbg_dump(sdev, "Firmware exception", - SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); + snd_sof_dsp_dbg_dump(sdev, msg, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); sof_fw_trace_fw_crashed(sdev); } EXPORT_SYMBOL(snd_sof_handle_fw_exception); diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index b4e1343f9138..ecca6dceaad2 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -18,6 +18,7 @@ enum sof_dtrace_state { SOF_DTRACE_DISABLED, SOF_DTRACE_STOPPED, + SOF_DTRACE_INITIALIZING, SOF_DTRACE_ENABLED, }; @@ -32,6 +33,15 @@ struct sof_dtrace_priv { enum sof_dtrace_state dtrace_state; }; +static bool trace_pos_update_expected(struct sof_dtrace_priv *priv) +{ + if (priv->dtrace_state == SOF_DTRACE_ENABLED || + priv->dtrace_state == SOF_DTRACE_INITIALIZING) + return true; + + return false; +} + static int trace_filter_append_elem(struct snd_sof_dev *sdev, u32 key, u32 value, struct sof_ipc_trace_filter_elem *elem_list, int capacity, int *counter) @@ -157,9 +167,8 @@ static int ipc3_trace_update_filter(struct snd_sof_dev *sdev, int num_elems, msg->elem_cnt = num_elems; memcpy(&msg->elems[0], elems, num_elems * sizeof(*elems)); - ret = pm_runtime_get_sync(sdev->dev); + ret = pm_runtime_resume_and_get(sdev->dev); if (ret < 0 && ret != -EACCES) { - pm_runtime_put_noidle(sdev->dev); dev_err(sdev->dev, "enabling device failed: %d\n", ret); goto error; } @@ -242,6 +251,21 @@ static int debugfs_create_trace_filter(struct snd_sof_dev *sdev) return 0; } +static bool sof_dtrace_set_host_offset(struct sof_dtrace_priv *priv, u32 new_offset) +{ + u32 host_offset = READ_ONCE(priv->host_offset); + + if (host_offset != new_offset) { + /* This is a bit paranoid and unlikely that it is needed */ + u32 ret = cmpxchg(&priv->host_offset, host_offset, new_offset); + + if (ret == host_offset) + return true; + } + + return false; +} + static size_t sof_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, size_t buffer_size) { @@ -274,7 +298,7 @@ static size_t sof_wait_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, if (ret) return ret; - if (priv->dtrace_state != SOF_DTRACE_ENABLED && priv->dtrace_draining) { + if (priv->dtrace_draining && !trace_pos_update_expected(priv)) { /* * tracing has ended and all traces have been * read by client, return EOF @@ -328,6 +352,10 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer, return -EIO; } + /* no new trace data */ + if (!avail) + return 0; + /* make sure count is <= avail */ if (count > avail) count = avail; @@ -358,7 +386,7 @@ static int dfsentry_dtrace_release(struct inode *inode, struct file *file) /* avoid duplicate traces at next open */ if (priv->dtrace_state != SOF_DTRACE_ENABLED) - priv->host_offset = 0; + sof_dtrace_set_host_offset(priv, 0); return 0; } @@ -434,7 +462,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) params.buffer.pages = priv->dma_trace_pages; params.stream_tag = 0; - priv->host_offset = 0; + sof_dtrace_set_host_offset(priv, 0); priv->dtrace_draining = false; ret = sof_dtrace_host_init(sdev, &priv->dmatb, ¶ms); @@ -445,6 +473,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) dev_dbg(sdev->dev, "%s: stream_tag: %d\n", __func__, params.stream_tag); /* send IPC to the DSP */ + priv->dtrace_state = SOF_DTRACE_INITIALIZING; ret = sof_ipc_tx_message(sdev->ipc, ¶ms, sizeof(params), &ipc_reply, sizeof(ipc_reply)); if (ret < 0) { dev_err(sdev->dev, "can't set params for DMA for trace %d\n", ret); @@ -452,17 +481,18 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) } start: + priv->dtrace_state = SOF_DTRACE_ENABLED; + ret = sof_dtrace_host_trigger(sdev, SNDRV_PCM_TRIGGER_START); if (ret < 0) { dev_err(sdev->dev, "Host dtrace trigger start failed: %d\n", ret); goto trace_release; } - priv->dtrace_state = SOF_DTRACE_ENABLED; - return 0; trace_release: + priv->dtrace_state = SOF_DTRACE_DISABLED; sof_dtrace_host_release(sdev); return ret; } @@ -546,11 +576,9 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, if (!sdev->fw_trace_is_supported) return 0; - if (priv->dtrace_state == SOF_DTRACE_ENABLED && - priv->host_offset != posn->host_offset) { - priv->host_offset = posn->host_offset; + if (trace_pos_update_expected(priv) && + sof_dtrace_set_host_offset(priv, posn->host_offset)) wake_up(&priv->trace_sleep); - } if (posn->overflow != 0) dev_err(sdev->dev, diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index ba81a6c490e9..0df57e7e83ac 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -290,7 +290,7 @@ static int ipc3_wait_tx_done(struct snd_sof_ipc *ipc, void *reply_data) dev_err(sdev->dev, "ipc tx timed out for %#x (msg/reply size: %d/%zu)\n", hdr->cmd, hdr->size, msg->reply_size); - snd_sof_handle_fw_exception(ipc->sdev); + snd_sof_handle_fw_exception(ipc->sdev, "IPC timeout"); ret = -ETIMEDOUT; } else { ret = msg->reply_error; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 0544eb6a2322..bd637153c08f 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -657,7 +657,7 @@ void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, u32 panic_code, u32 tracep_code, void *oops, struct sof_ipc_panic_info *panic_info, void *stack, size_t stack_words); -void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev); +void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg); int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev); int snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size, |