Files
linux/sound/soc/sof/amd/renoir.c
Ajit Kumar Pandey b585692fc9 ASoC: SOF: amd: Add SOF pm ops callback for Renoir
Add SOF PM ops callback in renoir dsp ops to power off and on ACP
IP block during system suspend and resume on Renoir platform.

Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220606210212.146626-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-06-06 22:08:21 +01:00

186 lines
4.7 KiB
C

// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2021 Advanced Micro Devices, Inc.
//
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
/*
* Hardware interface for Audio DSP on Renoir platform
*/
#include <linux/platform_device.h>
#include <linux/module.h>
#include "../ops.h"
#include "../sof-audio.h"
#include "acp.h"
#include "acp-dsp-offset.h"
#define I2S_BT_INSTANCE 0
#define I2S_SP_INSTANCE 1
#define PDM_DMIC_INSTANCE 2
#define I2S_MODE 0x04
static int renoir_dai_probe(struct snd_soc_dai *dai)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
unsigned int val;
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_I2S_PIN_CONFIG);
if (val != I2S_MODE) {
dev_err(sdev->dev, "I2S Mode is not supported (I2S_PIN_CONFIG: %#x)\n", val);
return -EINVAL;
}
return 0;
}
static struct snd_soc_dai_driver renoir_sof_dai[] = {
[I2S_BT_INSTANCE] = {
.id = I2S_BT_INSTANCE,
.name = "acp-sof-bt",
.playback = {
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 96000,
},
.capture = {
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
/* Supporting only stereo for I2S BT controller capture */
.channels_min = 2,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.probe = &renoir_dai_probe,
},
[I2S_SP_INSTANCE] = {
.id = I2S_SP_INSTANCE,
.name = "acp-sof-sp",
.playback = {
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 96000,
},
.capture = {
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
/* Supporting only stereo for I2S SP controller capture */
.channels_min = 2,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.probe = &renoir_dai_probe,
},
[PDM_DMIC_INSTANCE] = {
.id = PDM_DMIC_INSTANCE,
.name = "acp-sof-dmic",
.capture = {
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 4,
.rate_min = 8000,
.rate_max = 48000,
},
},
};
static struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *sof_pdata = sdev->pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
struct snd_soc_acpi_mach *mach;
mach = snd_soc_acpi_find_machine(desc->machines);
if (!mach) {
dev_warn(sdev->dev, "No matching ASoC machine driver found\n");
return NULL;
}
sof_pdata->tplg_filename = mach->sof_tplg_filename;
sof_pdata->fw_filename = mach->fw_filename;
return mach;
}
/* AMD Renoir DSP ops */
struct snd_sof_dsp_ops sof_renoir_ops = {
/* probe and remove */
.probe = amd_sof_acp_probe,
.remove = amd_sof_acp_remove,
/* Register IO */
.write = sof_io_write,
.read = sof_io_read,
/* Block IO */
.block_read = acp_dsp_block_read,
.block_write = acp_dsp_block_write,
/*Firmware loading */
.load_firmware = snd_sof_load_firmware_memcpy,
.pre_fw_run = acp_dsp_pre_fw_run,
.get_bar_index = acp_get_bar_index,
/* DSP core boot */
.run = acp_sof_dsp_run,
/*IPC */
.send_msg = acp_sof_ipc_send_msg,
.ipc_msg_data = acp_sof_ipc_msg_data,
.get_mailbox_offset = acp_sof_ipc_get_mailbox_offset,
.irq_thread = acp_sof_ipc_irq_thread,
/* DAI drivers */
.drv = renoir_sof_dai,
.num_drv = ARRAY_SIZE(renoir_sof_dai),
/* stream callbacks */
.pcm_open = acp_pcm_open,
.pcm_close = acp_pcm_close,
.pcm_hw_params = acp_pcm_hw_params,
.hw_info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
/* Machine driver callbacks */
.machine_select = amd_sof_machine_select,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* Trace Logger */
.trace_init = acp_sof_trace_init,
.trace_release = acp_sof_trace_release,
/* PM */
.suspend = amd_sof_acp_suspend,
.resume = amd_sof_acp_resume,
};
EXPORT_SYMBOL(sof_renoir_ops);
MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON);
MODULE_DESCRIPTION("RENOIR SOF Driver");
MODULE_LICENSE("Dual BSD/GPL");