Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…l/git/broonie/sound into for-linus

ASoC: Updates for v6.2

Some more small fixes and board quirks that came in since my last
update, the main one being the fixes from Kai for issues around the
attempts to get kexec working well on SOF based systems.
  • Loading branch information
tiwai committed Dec 22, 2022
2 parents fd28941 + a12a383 commit 6bf5f9a
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 15 deletions.
2 changes: 1 addition & 1 deletion sound/soc/codecs/lochnagar-sc.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ MODULE_DEVICE_TABLE(of, lochnagar_of_match);
static struct platform_driver lochnagar_sc_codec_driver = {
.driver = {
.name = "lochnagar-soundcard",
.of_match_table = of_match_ptr(lochnagar_of_match),
.of_match_table = lochnagar_of_match,
},

.probe = lochnagar_sc_probe,
Expand Down
2 changes: 0 additions & 2 deletions sound/soc/codecs/rt5670.c
Original file line number Diff line number Diff line change
Expand Up @@ -3311,8 +3311,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c)
if (ret < 0)
goto err;

pm_runtime_put(&i2c->dev);

return 0;
err:
pm_runtime_disable(&i2c->dev);
Expand Down
5 changes: 5 additions & 0 deletions sound/soc/codecs/wm8994.c
Original file line number Diff line number Diff line change
Expand Up @@ -3853,7 +3853,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
} else {
dev_dbg(component->dev, "Jack not detected\n");

/* Release wm8994->accdet_lock to avoid deadlock:
* cancel_delayed_work_sync() takes wm8994->mic_work internal
* lock and wm1811_mic_work takes wm8994->accdet_lock */
mutex_unlock(&wm8994->accdet_lock);
cancel_delayed_work_sync(&wm8994->mic_work);
mutex_lock(&wm8994->accdet_lock);

snd_soc_component_update_bits(component, WM8958_MICBIAS2,
WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
Expand Down
25 changes: 25 additions & 0 deletions sound/soc/intel/boards/bytcr_rt5640.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN),
},
{
/* Advantech MICA-071 */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
},
/* OVCD Th = 1500uA to reliable detect head-phones vs -set */
.driver_data = (void *)(BYT_RT5640_IN3_MAP |
BYT_RT5640_JD_SRC_JD2_IN4N |
BYT_RT5640_OVCD_TH_1500UA |
BYT_RT5640_OVCD_SF_0P75 |
BYT_RT5640_MONO_SPEAKER |
BYT_RT5640_DIFF_MIC |
BYT_RT5640_MCLK_EN),
},
{
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
Expand Down Expand Up @@ -796,6 +811,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN),
},
{ /* HP Stream 8 */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 8 Tablet"),
},
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
BYT_RT5640_JD_NOT_INV |
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN),
},
{ /* I.T.Works TW891 */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/intel/common/soc-acpi-intel-rpl-match.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = {

static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = {
{
.adr = 0x000131025D131801ull,
.adr = 0x000132025D131801ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "rt1318-1"
Expand Down
30 changes: 30 additions & 0 deletions sound/soc/mediatek/mt8195/mt8195-mt6359.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,32 @@ static const struct snd_soc_ops mt8195_rt1011_etdm_ops = {
.hw_params = mt8195_rt1011_etdm_hw_params,
};

static int mt8195_sof_be_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *cmpnt_afe = NULL;
struct snd_soc_pcm_runtime *runtime;

/* find afe component */
for_each_card_rtds(rtd->card, runtime) {
cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME);
if (cmpnt_afe)
break;
}

if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) {
dev_err(rtd->dev, "afe pm runtime is not active!!\n");
return -EINVAL;
}

return 0;
}

static const struct snd_soc_ops mt8195_sof_be_ops = {
.hw_params = mt8195_sof_be_hw_params,
};

static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
Expand Down Expand Up @@ -1272,24 +1298,28 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = {
.name = "AFE_SOF_DL2",
.no_pcm = 1,
.dpcm_playback = 1,
.ops = &mt8195_sof_be_ops,
SND_SOC_DAILINK_REG(AFE_SOF_DL2),
},
[DAI_LINK_SOF_DL3_BE] = {
.name = "AFE_SOF_DL3",
.no_pcm = 1,
.dpcm_playback = 1,
.ops = &mt8195_sof_be_ops,
SND_SOC_DAILINK_REG(AFE_SOF_DL3),
},
[DAI_LINK_SOF_UL4_BE] = {
.name = "AFE_SOF_UL4",
.no_pcm = 1,
.dpcm_capture = 1,
.ops = &mt8195_sof_be_ops,
SND_SOC_DAILINK_REG(AFE_SOF_UL4),
},
[DAI_LINK_SOF_UL5_BE] = {
.name = "AFE_SOF_UL5",
.no_pcm = 1,
.dpcm_capture = 1,
.ops = &mt8195_sof_be_ops,
SND_SOC_DAILINK_REG(AFE_SOF_UL5),
},
};
Expand Down
1 change: 1 addition & 0 deletions sound/soc/rockchip/rockchip_spdif.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)

ret = clk_prepare_enable(spdif->hclk);
if (ret) {
clk_disable_unprepare(spdif->mclk);
dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
return ret;
}
Expand Down
9 changes: 0 additions & 9 deletions sound/soc/sof/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,19 +475,10 @@ EXPORT_SYMBOL(snd_sof_device_remove);
int snd_sof_device_shutdown(struct device *dev)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_sof_pdata *pdata = sdev->pdata;

if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
cancel_work_sync(&sdev->probe_work);

/*
* make sure clients and machine driver(s) are unregistered to force
* all userspace devices to be closed prior to the DSP shutdown sequence
*/
sof_unregister_clients(sdev);

snd_sof_machine_unregister(sdev, pdata);

if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
return snd_sof_shutdown(sdev);

Expand Down
72 changes: 72 additions & 0 deletions sound/soc/sof/intel/hda-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,78 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
}

static unsigned int hda_dsp_check_for_dma_streams(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_stream *s;
unsigned int active_streams = 0;
int sd_offset;
u32 val;

list_for_each_entry(s, &bus->stream_list, list) {
sd_offset = SOF_STREAM_SD_OFFSET(s);
val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
sd_offset);
if (val & SOF_HDA_SD_CTL_DMA_START)
active_streams |= BIT(s->index);
}

return active_streams;
}

static int hda_dsp_s5_quirk(struct snd_sof_dev *sdev)
{
int ret;

/*
* Do not assume a certain timing between the prior
* suspend flow, and running of this quirk function.
* This is needed if the controller was just put
* to reset before calling this function.
*/
usleep_range(500, 1000);

/*
* Take controller out of reset to flush DMA
* transactions.
*/
ret = hda_dsp_ctrl_link_reset(sdev, false);
if (ret < 0)
return ret;

usleep_range(500, 1000);

/* Restore state for shutdown, back to reset */
ret = hda_dsp_ctrl_link_reset(sdev, true);
if (ret < 0)
return ret;

return ret;
}

int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev)
{
unsigned int active_streams;
int ret, ret2;

/* check if DMA cleanup has been successful */
active_streams = hda_dsp_check_for_dma_streams(sdev);

sdev->system_suspend_target = SOF_SUSPEND_S3;
ret = snd_sof_suspend(sdev->dev);

if (active_streams) {
dev_warn(sdev->dev,
"There were active DSP streams (%#x) at shutdown, trying to recover\n",
active_streams);
ret2 = hda_dsp_s5_quirk(sdev);
if (ret2 < 0)
dev_err(sdev->dev, "shutdown recovery failed (%d)\n", ret2);
}

return ret;
}

int hda_dsp_shutdown(struct snd_sof_dev *sdev)
{
sdev->system_suspend_target = SOF_SUSPEND_S3;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev);
int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev);
int hda_dsp_runtime_resume(struct snd_sof_dev *sdev);
int hda_dsp_runtime_idle(struct snd_sof_dev *sdev);
int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev);
int hda_dsp_shutdown(struct snd_sof_dev *sdev);
int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev);
void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags);
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/intel/tgl.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
memcpy(&sof_tgl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));

/* probe/remove/shutdown */
sof_tgl_ops.shutdown = hda_dsp_shutdown;
sof_tgl_ops.shutdown = hda_dsp_shutdown_dma_flush;

if (sdev->pdata->ipc_type == SOF_IPC) {
/* doorbell */
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/mediatek/mtk-adsp-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void mtk_adsp_dump(struct snd_sof_dev *sdev, u32 flags)
{
char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
struct sof_ipc_dsp_oops_xtensa xoops;
struct sof_ipc_panic_info panic_info;
struct sof_ipc_panic_info panic_info = {};
u32 stack[MTK_ADSP_STACK_DUMP_SIZE];
u32 status;

Expand Down

0 comments on commit 6bf5f9a

Please sign in to comment.