From 168eed447129899611098219b70ef97b605bc6e1 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Date: Tue, 2 Nov 2021 12:10:17 +0200 Subject: ASoC: SOF: IPC: Add new IPC command to free trace DMA Add a new SOF_IPC_TRACE_DMA_FREE IPC command to stop and free trace DMA in the FW. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20211102101019.14037-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof/header.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/sound/sof/header.h b/include/sound/sof/header.h index 4c747c52e01b..b97a76bcb655 100644 --- a/include/sound/sof/header.h +++ b/include/sound/sof/header.h @@ -119,6 +119,7 @@ #define SOF_IPC_TRACE_DMA_POSITION SOF_CMD_TYPE(0x002) #define SOF_IPC_TRACE_DMA_PARAMS_EXT SOF_CMD_TYPE(0x003) #define SOF_IPC_TRACE_FILTER_UPDATE SOF_CMD_TYPE(0x004) /**< ABI3.17 */ +#define SOF_IPC_TRACE_DMA_FREE SOF_CMD_TYPE(0x005) /**< ABI3.20 */ /* debug */ #define SOF_IPC_DEBUG_MEM_USAGE SOF_CMD_TYPE(0x001) -- cgit v1.2.3-70-g09d2 From 749303055b78bc38ec0790ccc596cae235446367 Mon Sep 17 00:00:00 2001 From: Simon Trimmer <simont@opensource.cirrus.com> Date: Mon, 15 Nov 2021 12:02:15 +0000 Subject: firmware: cs_dsp: tidy includes in cs_dsp.c and cs_dsp.h This patch removes unused included header files and moves others into cs_dsp.h to ensure that types referenced in the header file are properly described to prevent compiler warnings. Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com> Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211115120215.56824-1-simont@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/firmware/cirrus/cs_dsp.c | 6 ------ include/linux/firmware/cirrus/cs_dsp.h | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 948dd8382686..1a0c6c793f6a 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -12,16 +12,10 @@ #include <linux/ctype.h> #include <linux/debugfs.h> #include <linux/delay.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/interrupt.h> -#include <linux/list.h> #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/regmap.h> #include <linux/slab.h> #include <linux/vmalloc.h> -#include <linux/workqueue.h> #include <linux/firmware/cirrus/cs_dsp.h> #include <linux/firmware/cirrus/wmfw.h> diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index 9ad9eaaaa552..3a54b1afc48f 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -11,6 +11,11 @@ #ifndef __CS_DSP_H #define __CS_DSP_H +#include <linux/device.h> +#include <linux/firmware.h> +#include <linux/list.h> +#include <linux/regmap.h> + #define CS_ADSP2_REGION_0 BIT(0) #define CS_ADSP2_REGION_1 BIT(1) #define CS_ADSP2_REGION_2 BIT(2) -- cgit v1.2.3-70-g09d2 From efb931cdc4b94a0f7ed17a76844f08cef1bdffe5 Mon Sep 17 00:00:00 2001 From: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> Date: Wed, 17 Nov 2021 11:37:24 +0200 Subject: ASoC: SOF: topology: Add support for AMD ACP DAIs Add new sof dais and config to pass topology file configuration to SOF firmware running on ACP's DSP core. ACP firmware support I2S_BT, I2S_SP and DMIC controller hence add three new dais to the list of supported sof_dais Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> Reviewed-by: Bard Liao <bard.liao@intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Link: https://lore.kernel.org/r/20211117093734.17407-12-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof/dai-amd.h | 21 +++++++++ include/sound/sof/dai.h | 7 +++ sound/soc/sof/pcm.c | 36 +++++++++++++++ sound/soc/sof/topology.c | 109 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 include/sound/sof/dai-amd.h (limited to 'include') diff --git a/include/sound/sof/dai-amd.h b/include/sound/sof/dai-amd.h new file mode 100644 index 000000000000..90d09dbdd709 --- /dev/null +++ b/include/sound/sof/dai-amd.h @@ -0,0 +1,21 @@ +/* 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.. All rights reserved. + */ + +#ifndef __INCLUDE_SOUND_SOF_DAI_AMD_H__ +#define __INCLUDE_SOUND_SOF_DAI_AMD_H__ + +#include <sound/sof/header.h> + +/* ACP Configuration Request - SOF_IPC_DAI_AMD_CONFIG */ +struct sof_ipc_dai_acp_params { + struct sof_ipc_hdr hdr; + + uint32_t fsync_rate; /* FSYNC frequency in Hz */ + uint32_t tdm_slots; +} __packed; +#endif diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index 9625f47557b8..3782127a7095 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -12,6 +12,7 @@ #include <sound/sof/header.h> #include <sound/sof/dai-intel.h> #include <sound/sof/dai-imx.h> +#include <sound/sof/dai-amd.h> /* * DAI Configuration. @@ -66,6 +67,9 @@ enum sof_ipc_dai_type { SOF_DAI_INTEL_ALH, /**< Intel ALH */ SOF_DAI_IMX_SAI, /**< i.MX SAI */ SOF_DAI_IMX_ESAI, /**< i.MX ESAI */ + SOF_DAI_AMD_BT, /**< AMD ACP BT*/ + SOF_DAI_AMD_SP, /**< AMD ACP SP */ + SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */ }; /* general purpose DAI configuration */ @@ -90,6 +94,9 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_alh_params alh; struct sof_ipc_dai_esai_params esai; struct sof_ipc_dai_sai_params sai; + struct sof_ipc_dai_acp_params acpbt; + struct sof_ipc_dai_acp_params acpsp; + struct sof_ipc_dai_acp_params acpdmic; }; } __packed; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index fa0bfcd2474e..8d313c9862cb 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -826,6 +826,42 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa "channels_min: %d channels_max: %d\n", channels->min, channels->max); break; + case SOF_DAI_AMD_BT: + rate->min = dai->dai_config->acpbt.fsync_rate; + rate->max = dai->dai_config->acpbt.fsync_rate; + channels->min = dai->dai_config->acpbt.tdm_slots; + channels->max = dai->dai_config->acpbt.tdm_slots; + + dev_dbg(component->dev, + "AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, + "AMD_BT channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_AMD_SP: + rate->min = dai->dai_config->acpsp.fsync_rate; + rate->max = dai->dai_config->acpsp.fsync_rate; + channels->min = dai->dai_config->acpsp.tdm_slots; + channels->max = dai->dai_config->acpsp.tdm_slots; + + dev_dbg(component->dev, + "AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, + "AMD_SP channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_AMD_DMIC: + rate->min = dai->dai_config->acpdmic.fsync_rate; + rate->max = dai->dai_config->acpdmic.fsync_rate; + channels->min = dai->dai_config->acpdmic.tdm_slots; + channels->max = dai->dai_config->acpdmic.tdm_slots; + + dev_dbg(component->dev, + "AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, + "AMD_DMIC channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; default: dev_err(component->dev, "error: invalid DAI type %d\n", dai->dai_config->type); diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index bb9e62bbe5db..72e671c15a34 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -376,6 +376,9 @@ static const struct sof_dai_types sof_dais[] = { {"ALH", SOF_DAI_INTEL_ALH}, {"SAI", SOF_DAI_IMX_SAI}, {"ESAI", SOF_DAI_IMX_ESAI}, + {"ACP", SOF_DAI_AMD_BT}, + {"ACPSP", SOF_DAI_AMD_SP}, + {"ACPDMIC", SOF_DAI_AMD_DMIC}, }; static enum sof_ipc_dai_type find_dai(const char *name) @@ -2992,6 +2995,102 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, int index, return ret; } +static int sof_link_acp_dmic_load(struct snd_soc_component *scomp, int index, + struct snd_soc_dai_link *link, + struct snd_soc_tplg_link_config *cfg, + struct snd_soc_tplg_hw_config *hw_config, + struct sof_ipc_dai_config *config) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + u32 size = sizeof(*config); + int ret; + + /* handle master/slave and inverted clocks */ + sof_dai_set_format(hw_config, config); + + /* init IPC */ + memset(&config->acpdmic, 0, sizeof(struct sof_ipc_dai_acp_params)); + config->hdr.size = size; + + config->acpdmic.fsync_rate = le32_to_cpu(hw_config->fsync_rate); + config->acpdmic.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + + dev_info(scomp->dev, "ACP_DMIC config ACP%d channel %d rate %d\n", + config->dai_index, config->acpdmic.tdm_slots, + config->acpdmic.fsync_rate); + + /* set config for all DAI's with name matching the link name */ + ret = sof_set_dai_config(sdev, size, link, config); + if (ret < 0) + dev_err(scomp->dev, "ACP_DMIC failed to save DAI config for ACP%d\n", + config->dai_index); + return ret; +} + +static int sof_link_acp_bt_load(struct snd_soc_component *scomp, int index, + struct snd_soc_dai_link *link, + struct snd_soc_tplg_link_config *cfg, + struct snd_soc_tplg_hw_config *hw_config, + struct sof_ipc_dai_config *config) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + u32 size = sizeof(*config); + int ret; + + /* handle master/slave and inverted clocks */ + sof_dai_set_format(hw_config, config); + + /* init IPC */ + memset(&config->acpbt, 0, sizeof(struct sof_ipc_dai_acp_params)); + config->hdr.size = size; + + config->acpbt.fsync_rate = le32_to_cpu(hw_config->fsync_rate); + config->acpbt.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + + dev_info(scomp->dev, "ACP_BT config ACP%d channel %d rate %d\n", + config->dai_index, config->acpbt.tdm_slots, + config->acpbt.fsync_rate); + + /* set config for all DAI's with name matching the link name */ + ret = sof_set_dai_config(sdev, size, link, config); + if (ret < 0) + dev_err(scomp->dev, "ACP_BT failed to save DAI config for ACP%d\n", + config->dai_index); + return ret; +} + +static int sof_link_acp_sp_load(struct snd_soc_component *scomp, int index, + struct snd_soc_dai_link *link, + struct snd_soc_tplg_link_config *cfg, + struct snd_soc_tplg_hw_config *hw_config, + struct sof_ipc_dai_config *config) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + u32 size = sizeof(*config); + int ret; + + /* handle master/slave and inverted clocks */ + sof_dai_set_format(hw_config, config); + + /* init IPC */ + memset(&config->acpsp, 0, sizeof(struct sof_ipc_dai_acp_params)); + config->hdr.size = size; + + config->acpsp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); + config->acpsp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + + dev_info(scomp->dev, "ACP_SP config ACP%d channel %d rate %d\n", + config->dai_index, config->acpsp.tdm_slots, + config->acpsp.fsync_rate); + + /* set config for all DAI's with name matching the link name */ + ret = sof_set_dai_config(sdev, size, link, config); + if (ret < 0) + dev_err(scomp->dev, "ACP_SP failed to save DAI config for ACP%d\n", + config->dai_index); + return ret; +} + static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link, struct snd_soc_tplg_link_config *cfg, @@ -3277,6 +3376,16 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, case SOF_DAI_IMX_ESAI: ret = sof_link_esai_load(scomp, index, link, cfg, hw_config + curr_conf, config); break; + case SOF_DAI_AMD_BT: + ret = sof_link_acp_bt_load(scomp, index, link, cfg, hw_config + curr_conf, config); + break; + case SOF_DAI_AMD_SP: + ret = sof_link_acp_sp_load(scomp, index, link, cfg, hw_config + curr_conf, config); + break; + case SOF_DAI_AMD_DMIC: + ret = sof_link_acp_dmic_load(scomp, index, link, cfg, hw_config + curr_conf, + config); + break; default: dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type); ret = -EINVAL; -- cgit v1.2.3-70-g09d2 From 2925748eadc33cba3bded7b69475a1b002b124ac Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Wed, 17 Nov 2021 13:22:53 +0000 Subject: firmware: cs_dsp: Add version checks on coefficient loading The firmware coefficient files contain version information that is currently ignored by the cs_dsp code. This information specifies which version of the firmware the coefficient were generated for. Add a check into the code which prints a warning in the case the coefficient and firmware differ in version, in many cases this will be ok but it is not always, so best to let the user know there is a potential issue. Co-authored-by: Simon Trimmer <simont@opensource.cirrus.com> Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211117132300.1290-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/firmware/cirrus/cs_dsp.c | 49 +++++++++++++++++++++++++--------- include/linux/firmware/cirrus/cs_dsp.h | 2 ++ 2 files changed, 38 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 0d1ba7d8efa4..0da454a8498d 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -1569,7 +1569,7 @@ EXPORT_SYMBOL_GPL(cs_dsp_find_alg_region); static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, int type, __be32 id, - __be32 base) + __be32 ver, __be32 base) { struct cs_dsp_alg_region *alg_region; @@ -1579,6 +1579,7 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, alg_region->type = type; alg_region->alg = be32_to_cpu(id); + alg_region->ver = be32_to_cpu(ver); alg_region->base = be32_to_cpu(base); list_add_tail(&alg_region->list, &dsp->alg_regions); @@ -1628,14 +1629,14 @@ static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, nalgs); } -static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, - const int *type, __be32 *base) +static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, __be32 ver, + int nregions, const int *type, __be32 *base) { struct cs_dsp_alg_region *alg_region; int i; for (i = 0; i < nregions; i++) { - alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); + alg_region = cs_dsp_create_region(dsp, type[i], id, ver, base[i]); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); } @@ -1670,12 +1671,14 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, - adsp1_id.fw.id, adsp1_id.zm); + adsp1_id.fw.id, adsp1_id.fw.ver, + adsp1_id.zm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, - adsp1_id.fw.id, adsp1_id.dm); + adsp1_id.fw.id, adsp1_id.fw.ver, + adsp1_id.dm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); @@ -1698,6 +1701,7 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, adsp1_alg[i].alg.id, + adsp1_alg[i].alg.ver, adsp1_alg[i].dm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); @@ -1719,6 +1723,7 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, adsp1_alg[i].alg.id, + adsp1_alg[i].alg.ver, adsp1_alg[i].zm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); @@ -1771,17 +1776,20 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, - adsp2_id.fw.id, adsp2_id.xm); + adsp2_id.fw.id, adsp2_id.fw.ver, + adsp2_id.xm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, - adsp2_id.fw.id, adsp2_id.ym); + adsp2_id.fw.id, adsp2_id.fw.ver, + adsp2_id.ym); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, - adsp2_id.fw.id, adsp2_id.zm); + adsp2_id.fw.id, adsp2_id.fw.ver, + adsp2_id.zm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); @@ -1806,6 +1814,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, adsp2_alg[i].alg.id, + adsp2_alg[i].alg.ver, adsp2_alg[i].xm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); @@ -1827,6 +1836,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, adsp2_alg[i].alg.id, + adsp2_alg[i].alg.ver, adsp2_alg[i].ym); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); @@ -1848,6 +1858,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, adsp2_alg[i].alg.id, + adsp2_alg[i].alg.ver, adsp2_alg[i].zm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); @@ -1873,7 +1884,7 @@ out: return ret; } -static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, +static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, __be32 ver, __be32 xm_base, __be32 ym_base) { static const int types[] = { @@ -1882,7 +1893,7 @@ static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, }; __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; - return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); + return cs_dsp_create_regions(dsp, id, ver, ARRAY_SIZE(types), types, bases); } static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) @@ -1910,7 +1921,7 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); - ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, + ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, halo_id.fw.ver, halo_id.xm_base, halo_id.ym_base); if (ret) return ret; @@ -1934,6 +1945,7 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) be32_to_cpu(halo_alg[i].ym_base)); ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, + halo_alg[i].alg.ver, halo_alg[i].xm_base, halo_alg[i].ym_base); if (ret) @@ -1955,7 +1967,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware const struct cs_dsp_region *mem; struct cs_dsp_alg_region *alg_region; const char *region_name; - int ret, pos, blocks, type, offset, reg; + int ret, pos, blocks, type, offset, reg, version; struct cs_dsp_buf *buf; if (!firmware) @@ -1999,6 +2011,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware type = le16_to_cpu(blk->type); offset = le16_to_cpu(blk->offset); + version = le32_to_cpu(blk->ver) >> 8; cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", file, blocks, le32_to_cpu(blk->id), @@ -2056,6 +2069,16 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware alg_region = cs_dsp_find_alg_region(dsp, type, le32_to_cpu(blk->id)); if (alg_region) { + if (version != alg_region->ver) + cs_dsp_warn(dsp, + "Algorithm coefficient version %d.%d.%d but expected %d.%d.%d\n", + (version >> 16) & 0xFF, + (version >> 8) & 0xFF, + version & 0xFF, + (alg_region->ver >> 16) & 0xFF, + (alg_region->ver >> 8) & 0xFF, + alg_region->ver & 0xFF); + reg = alg_region->base; reg = dsp->ops->region_to_reg(mem, reg); reg += offset; diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index 3a54b1afc48f..ce54705e2bec 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -54,12 +54,14 @@ struct cs_dsp_region { * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space * @list: List node for internal use * @alg: Algorithm id + * @ver: Expected algorithm version * @type: Memory region type * @base: Address of region */ struct cs_dsp_alg_region { struct list_head list; unsigned int alg; + unsigned int ver; int type; unsigned int base; }; -- cgit v1.2.3-70-g09d2 From 14055b5a3a23204c4702ae5d3f2a819ee081ce33 Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Wed, 17 Nov 2021 13:22:54 +0000 Subject: firmware: cs_dsp: Add pre_run callback The code already has a post_run callback, add a matching pre_run callback to the client_ops that is called before execution is started. This callback provides a convenient place for the client code to set DSP controls or hardware that requires configuration before the DSP core actually starts execution. Note that placing this callback before cs_dsp_coeff_sync_controls is important to ensure that any control values are then correctly synced out to the chip. Co-authored-by: Simon Trimmer <simont@opensource.cirrus.com> Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211117132300.1290-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/firmware/cirrus/cs_dsp.c | 6 ++++++ include/linux/firmware/cirrus/cs_dsp.h | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 0da454a8498d..ef7afadea42d 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -2627,6 +2627,12 @@ int cs_dsp_run(struct cs_dsp *dsp) goto err; } + if (dsp->client_ops->pre_run) { + ret = dsp->client_ops->pre_run(dsp); + if (ret) + goto err; + } + /* Sync set controls */ ret = cs_dsp_coeff_sync_controls(dsp); if (ret != 0) diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index ce54705e2bec..0bf849baeaa5 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -187,7 +187,8 @@ struct cs_dsp { * struct cs_dsp_client_ops - client callbacks * @control_add: Called under the pwr_lock when a control is created * @control_remove: Called under the pwr_lock when a control is destroyed - * @post_run: Called under the pwr_lock by cs_dsp_run() + * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started + * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started * @post_stop: Called under the pwr_lock by cs_dsp_stop() * @watchdog_expired: Called when a watchdog expiry is detected * @@ -197,6 +198,7 @@ struct cs_dsp { struct cs_dsp_client_ops { int (*control_add)(struct cs_dsp_coeff_ctl *ctl); void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); + int (*pre_run)(struct cs_dsp *dsp); int (*post_run)(struct cs_dsp *dsp); void (*post_stop)(struct cs_dsp *dsp); void (*watchdog_expired)(struct cs_dsp *dsp); -- cgit v1.2.3-70-g09d2 From b329b3d39497a9fdb175d7e4fd77ae7170d5d26c Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Wed, 17 Nov 2021 13:22:58 +0000 Subject: firmware: cs_dsp: Clarify some kernel doc comments Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211117132300.1290-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/firmware/cirrus/cs_dsp.c | 4 ++-- include/linux/firmware/cirrus/cs_dsp.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 9eecd1626537..d1bcade2efe2 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -746,7 +746,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, * cs_dsp_coeff_write_ctrl() - Writes the given buffer to the given coefficient control * @ctl: pointer to coefficient control * @buf: the buffer to write to the given control - * @len: the length of the buffer + * @len: the length of the buffer in bytes * * Must be called with pwr_lock held. * @@ -808,7 +808,7 @@ static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, s * cs_dsp_coeff_read_ctrl() - Reads the given coefficient control into the given buffer * @ctl: pointer to coefficient control * @buf: the buffer to store to the given control - * @len: the length of the buffer + * @len: the length of the buffer in bytes * * Must be called with pwr_lock held. * diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index 0bf849baeaa5..1ad1b173417a 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -76,8 +76,8 @@ struct cs_dsp_alg_region { * @enabled: Flag indicating whether control is enabled * @list: List node for internal use * @cache: Cached value of the control - * @offset: Offset of control within alg_region - * @len: Length of the cached value + * @offset: Offset of control within alg_region in words + * @len: Length of the cached value in bytes * @set: Flag indicating the value has been written by the user * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h -- cgit v1.2.3-70-g09d2 From f444da38ac924748de696c393327a44c4b8d727e Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Wed, 17 Nov 2021 13:22:59 +0000 Subject: firmware: cs_dsp: Add offset to cs_dsp read/write Provide a mechanism to access only part of a control through the cs_dsp interface. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211117132300.1290-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/firmware/cirrus/cs_dsp.c | 44 +++++++++++++++++++++------------- include/linux/firmware/cirrus/cs_dsp.h | 6 +++-- sound/soc/codecs/wm_adsp.c | 14 +++++------ 3 files changed, 39 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index d1bcade2efe2..5fe08de91ecd 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -616,7 +616,8 @@ static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) offs[0], offs[1], offs[2], offs[3]); } -static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) +static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg, + unsigned int off) { const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; struct cs_dsp *dsp = ctl->dsp; @@ -629,7 +630,7 @@ static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg return -EINVAL; } - *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); + *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset + off); return 0; } @@ -658,7 +659,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int if (!dsp->running) return -EPERM; - ret = cs_dsp_coeff_base_reg(ctl, ®); + ret = cs_dsp_coeff_base_reg(ctl, ®, 0); if (ret) return ret; @@ -712,14 +713,14 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_acked_control); static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, - const void *buf, size_t len) + unsigned int off, const void *buf, size_t len) { struct cs_dsp *dsp = ctl->dsp; void *scratch; int ret; unsigned int reg; - ret = cs_dsp_coeff_base_reg(ctl, ®); + ret = cs_dsp_coeff_base_reg(ctl, ®, off); if (ret) return ret; @@ -745,6 +746,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, /** * cs_dsp_coeff_write_ctrl() - Writes the given buffer to the given coefficient control * @ctl: pointer to coefficient control + * @off: word offset at which data should be written * @buf: the buffer to write to the given control * @len: the length of the buffer in bytes * @@ -752,7 +754,8 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, * * Return: Zero for success, a negative number on error. */ -int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) +int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, + unsigned int off, const void *buf, size_t len) { int ret = 0; @@ -761,27 +764,31 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_ if (!ctl) return -ENOENT; + if (len + off * sizeof(u32) > ctl->len) + return -EINVAL; + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) ret = -EPERM; else if (buf != ctl->cache) - memcpy(ctl->cache, buf, len); + memcpy(ctl->cache + off * sizeof(u32), buf, len); ctl->set = 1; if (ctl->enabled && ctl->dsp->running) - ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); + ret = cs_dsp_coeff_write_ctrl_raw(ctl, off, buf, len); return ret; } EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_ctrl); -static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) +static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + unsigned int off, void *buf, size_t len) { struct cs_dsp *dsp = ctl->dsp; void *scratch; int ret; unsigned int reg; - ret = cs_dsp_coeff_base_reg(ctl, ®); + ret = cs_dsp_coeff_base_reg(ctl, ®, off); if (ret) return ret; @@ -807,6 +814,7 @@ static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, s /** * cs_dsp_coeff_read_ctrl() - Reads the given coefficient control into the given buffer * @ctl: pointer to coefficient control + * @off: word offset at which data should be read * @buf: the buffer to store to the given control * @len: the length of the buffer in bytes * @@ -814,7 +822,8 @@ static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, s * * Return: Zero for success, a negative number on error. */ -int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) +int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, + unsigned int off, void *buf, size_t len) { int ret = 0; @@ -823,17 +832,20 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) if (!ctl) return -ENOENT; + if (len + off * sizeof(u32) > ctl->len) + return -EINVAL; + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { if (ctl->enabled && ctl->dsp->running) - return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); + return cs_dsp_coeff_read_ctrl_raw(ctl, off, buf, len); else return -EPERM; } else { if (!ctl->flags && ctl->enabled && ctl->dsp->running) - ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len); if (buf != ctl->cache) - memcpy(buf, ctl->cache, len); + memcpy(buf, ctl->cache + off * sizeof(u32), len); } return ret; @@ -857,7 +869,7 @@ static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) * created so we don't need to do anything. */ if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { - ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len); if (ret < 0) return ret; } @@ -875,7 +887,7 @@ static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) if (!ctl->enabled) continue; if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { - ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, + ret = cs_dsp_coeff_write_ctrl_raw(ctl, 0, ctl->cache, ctl->len); if (ret < 0) return ret; diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index 1ad1b173417a..38b4da3ddfe4 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -232,8 +232,10 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); -int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len); -int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len); +int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, + const void *buf, size_t len); +int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, + void *buf, size_t len); struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, unsigned int alg); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 404717e30f44..f084b093cff6 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -401,7 +401,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, int ret = 0; mutex_lock(&cs_ctl->dsp->pwr_lock); - ret = cs_dsp_coeff_write_ctrl(cs_ctl, p, cs_ctl->len); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, p, cs_ctl->len); mutex_unlock(&cs_ctl->dsp->pwr_lock); return ret; @@ -421,7 +421,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, if (copy_from_user(cs_ctl->cache, bytes, size)) ret = -EFAULT; else - ret = cs_dsp_coeff_write_ctrl(cs_ctl, cs_ctl->cache, size); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, cs_ctl->cache, size); mutex_unlock(&cs_ctl->dsp->pwr_lock); @@ -464,7 +464,7 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, int ret; mutex_lock(&cs_ctl->dsp->pwr_lock); - ret = cs_dsp_coeff_read_ctrl(cs_ctl, p, cs_ctl->len); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, p, cs_ctl->len); mutex_unlock(&cs_ctl->dsp->pwr_lock); return ret; @@ -481,7 +481,7 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, mutex_lock(&cs_ctl->dsp->pwr_lock); - ret = cs_dsp_coeff_read_ctrl(cs_ctl, cs_ctl->cache, size); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, cs_ctl->cache, size); if (!ret && copy_to_user(bytes, cs_ctl->cache, size)) ret = -EFAULT; @@ -684,7 +684,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, if (len > cs_ctl->len) return -EINVAL; - ret = cs_dsp_coeff_write_ctrl(cs_ctl, buf, len); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); if (ret) return ret; @@ -723,7 +723,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, if (len > cs_ctl->len) return -EINVAL; - return cs_dsp_coeff_read_ctrl(cs_ctl, buf, len); + return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); } EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); @@ -1432,7 +1432,7 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) int ret, i; for (i = 0; i < 5; ++i) { - ret = cs_dsp_coeff_read_ctrl(cs_ctl, &coeff_v1, sizeof(coeff_v1)); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, sizeof(coeff_v1)); if (ret < 0) return ret; -- cgit v1.2.3-70-g09d2 From 5c903f64ce97172d63f7591cfa9e37cba58867b2 Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Wed, 17 Nov 2021 13:23:00 +0000 Subject: firmware: cs_dsp: Allow creation of event controls Some firmwares contain controls intended to convey firmware state back to the host. Whilst more infrastructure will probably be needed for these in time, as a first step allow creation of the controls, so said firmwares arn't completely rejected. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211117132300.1290-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/firmware/cirrus/cs_dsp.c | 1 + include/linux/firmware/cirrus/wmfw.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 5fe08de91ecd..3814cbba0a54 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -1177,6 +1177,7 @@ static int cs_dsp_parse_coeff(struct cs_dsp *dsp, return -EINVAL; break; case WMFW_CTL_TYPE_HOSTEVENT: + case WMFW_CTL_TYPE_FWEVENT: ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_VOLATILE | diff --git a/include/linux/firmware/cirrus/wmfw.h b/include/linux/firmware/cirrus/wmfw.h index a19bf7c6fc8b..74e5a4f6c13a 100644 --- a/include/linux/firmware/cirrus/wmfw.h +++ b/include/linux/firmware/cirrus/wmfw.h @@ -29,6 +29,7 @@ #define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ #define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ #define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ +#define WMFW_CTL_TYPE_FWEVENT 0x1004 /* firmware event control */ struct wmfw_header { char magic[4]; -- cgit v1.2.3-70-g09d2 From e6feefa541f309afed8aa54431681261bc57bcde Mon Sep 17 00:00:00 2001 From: YC Hung <yc.hung@mediatek.com> Date: Thu, 18 Nov 2021 12:07:43 +0200 Subject: ASoC: SOF: tokens: add token for Mediatek AFE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the definition for Mediatek audio front end(AFE) tokens,include AFE sampling rate, channels, and format. Signed-off-by: YC Hung <yc.hung@mediatek.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Link: https://lore.kernel.org/r/20211118100749.54628-3-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/uapi/sound/sof/tokens.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index 02b71a8deea4..b72fa385bebf 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -140,4 +140,9 @@ #define SOF_TKN_INTEL_HDA_RATE 1500 #define SOF_TKN_INTEL_HDA_CH 1501 +/* AFE */ +#define SOF_TKN_MEDIATEK_AFE_RATE 1600 +#define SOF_TKN_MEDIATEK_AFE_CH 1601 +#define SOF_TKN_MEDIATEK_AFE_FORMAT 1602 + #endif -- cgit v1.2.3-70-g09d2 From b72bfcffcfc11858a8fc92998733372606db485e Mon Sep 17 00:00:00 2001 From: YC Hung <yc.hung@mediatek.com> Date: Thu, 18 Nov 2021 12:07:44 +0200 Subject: ASoC: SOF: topology: Add support for Mediatek AFE DAI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new sof dai and config to pass topology file configuration to SOF firmware running on Mediatek platform DSP core. Add mediatek audio front end(AFE) to the list of supported sof_dais Signed-off-by: YC Hung <yc.hung@mediatek.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Link: https://lore.kernel.org/r/20211118100749.54628-4-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof/dai-mediatek.h | 23 ++++++++++++++++ include/sound/sof/dai.h | 3 ++ sound/soc/sof/pcm.c | 12 ++++++++ sound/soc/sof/topology.c | 59 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 include/sound/sof/dai-mediatek.h (limited to 'include') diff --git a/include/sound/sof/dai-mediatek.h b/include/sound/sof/dai-mediatek.h new file mode 100644 index 000000000000..62dd4720558d --- /dev/null +++ b/include/sound/sof/dai-mediatek.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * Copyright(c) 2021 Mediatek Corporation. All rights reserved. + * + * Author: Bo Pan <bo.pan@mediatek.com> + */ + +#ifndef __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__ +#define __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__ + +#include <sound/sof/header.h> + +struct sof_ipc_dai_mtk_afe_params { + struct sof_ipc_hdr hdr; + u32 channels; + u32 rate; + u32 format; + u32 stream_id; + u32 reserved[4]; /* reserve for future */ +} __packed; + +#endif + diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index 3782127a7095..5132bc60f54b 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -13,6 +13,7 @@ #include <sound/sof/dai-intel.h> #include <sound/sof/dai-imx.h> #include <sound/sof/dai-amd.h> +#include <sound/sof/dai-mediatek.h> /* * DAI Configuration. @@ -70,6 +71,7 @@ enum sof_ipc_dai_type { SOF_DAI_AMD_BT, /**< AMD ACP BT*/ SOF_DAI_AMD_SP, /**< AMD ACP SP */ SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */ + SOF_DAI_MEDIATEK_AFE, /**< Mediatek AFE */ }; /* general purpose DAI configuration */ @@ -97,6 +99,7 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_acp_params acpbt; struct sof_ipc_dai_acp_params acpsp; struct sof_ipc_dai_acp_params acpdmic; + struct sof_ipc_dai_mtk_afe_params afe; }; } __packed; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 8d313c9862cb..31dd79b794f1 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -808,6 +808,18 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa channels->min = dai->dai_config->esai.tdm_slots; channels->max = dai->dai_config->esai.tdm_slots; + dev_dbg(component->dev, + "rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, + "channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_MEDIATEK_AFE: + rate->min = dai->dai_config->afe.rate; + rate->max = dai->dai_config->afe.rate; + channels->min = dai->dai_config->afe.channels; + channels->max = dai->dai_config->afe.channels; + dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); dev_dbg(component->dev, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 72e671c15a34..10caf2b1a33c 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -379,6 +379,7 @@ static const struct sof_dai_types sof_dais[] = { {"ACP", SOF_DAI_AMD_BT}, {"ACPSP", SOF_DAI_AMD_SP}, {"ACPDMIC", SOF_DAI_AMD_DMIC}, + {"AFE", SOF_DAI_MEDIATEK_AFE}, }; static enum sof_ipc_dai_type find_dai(const char *name) @@ -806,6 +807,19 @@ static const struct sof_topology_token led_tokens[] = { get_token_u32, offsetof(struct snd_sof_led_control, direction), 0}, }; +/* AFE */ +static const struct sof_topology_token afe_tokens[] = { + {SOF_TKN_MEDIATEK_AFE_RATE, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_mtk_afe_params, rate), 0}, + {SOF_TKN_MEDIATEK_AFE_CH, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_mtk_afe_params, channels), 0}, + {SOF_TKN_MEDIATEK_AFE_FORMAT, + SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_format, + offsetof(struct sof_ipc_dai_mtk_afe_params, format), 0}, +}; + static int sof_parse_uuid_tokens(struct snd_soc_component *scomp, void *object, const struct sof_topology_token *tokens, @@ -3091,6 +3105,48 @@ static int sof_link_acp_sp_load(struct snd_soc_component *scomp, int index, return ret; } +static int sof_link_afe_load(struct snd_soc_component *scomp, int index, + struct snd_soc_dai_link *link, + struct snd_soc_tplg_link_config *cfg, + struct snd_soc_tplg_hw_config *hw_config, + struct sof_ipc_dai_config *config) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct snd_soc_tplg_private *private = &cfg->priv; + struct snd_soc_dai *dai; + u32 size = sizeof(*config); + int ret; + + config->hdr.size = size; + + /* get any bespoke DAI tokens */ + ret = sof_parse_tokens(scomp, &config->afe, afe_tokens, + ARRAY_SIZE(afe_tokens), private->array, + le32_to_cpu(private->size)); + if (ret != 0) { + dev_err(scomp->dev, "parse afe tokens failed %d\n", + le32_to_cpu(private->size)); + return ret; + } + + dev_dbg(scomp->dev, "AFE config rate %d channels %d format:%d\n", + config->afe.rate, config->afe.channels, config->afe.format); + + dai = snd_soc_find_dai(link->cpus); + if (!dai) { + dev_err(scomp->dev, "%s: failed to find dai %s", __func__, link->cpus->dai_name); + return -EINVAL; + } + + config->afe.stream_id = DMA_CHAN_INVALID; + + ret = sof_set_dai_config(sdev, size, link, config); + if (ret < 0) + dev_err(scomp->dev, "failed to process afe dai link %s", link->name); + + return ret; +} + static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link, struct snd_soc_tplg_link_config *cfg, @@ -3386,6 +3442,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, ret = sof_link_acp_dmic_load(scomp, index, link, cfg, hw_config + curr_conf, config); break; + case SOF_DAI_MEDIATEK_AFE: + ret = sof_link_afe_load(scomp, index, link, cfg, hw_config + curr_conf, config); + break; default: dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type); ret = -EINVAL; -- cgit v1.2.3-70-g09d2 From b456abe63f60ad93c83a526d33b71574bc32656c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Date: Fri, 19 Nov 2021 17:08:50 -0600 Subject: ALSA: pcm: introduce INFO_NO_REWINDS flag When the hardware can only deal with a monotonically increasing appl_ptr, this flag can be set. In case the application requests a rewind, be it with a snd_pcm_rewind() or with a direct change of a mmap'ed pointer followed by a SNDRV_PCM_IOCTL_SYNC_PTR, this patch checks if a rewind occurred and returns an error. Credits to Takashi Iwai for identifying the path with SYNC_PTR and suggesting the pointer checks. Suggested-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20211119230852.206310-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/uapi/sound/asound.h | 2 +- sound/core/pcm_lib.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 5fbb79e30819..ff7e638221c5 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -300,7 +300,7 @@ typedef int __bitwise snd_pcm_subformat_t; #define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 /* report estimated link audio time */ #define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 /* report synchronized audio/system time */ #define SNDRV_PCM_INFO_EXPLICIT_SYNC 0x10000000 /* needs explicit sync of pointers and data */ - +#define SNDRV_PCM_INFO_NO_REWINDS 0x20000000 /* hardware can only support monotonic changes of appl_ptr */ #define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */ #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index fdd992772b20..f2090025236b 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -2128,6 +2128,7 @@ int pcm_lib_apply_appl_ptr(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t old_appl_ptr = runtime->control->appl_ptr; + snd_pcm_sframes_t diff; int ret; if (old_appl_ptr == appl_ptr) @@ -2135,6 +2136,19 @@ int pcm_lib_apply_appl_ptr(struct snd_pcm_substream *substream, if (appl_ptr >= runtime->boundary) return -EINVAL; + /* + * check if a rewind is requested by the application + */ + if (substream->runtime->info & SNDRV_PCM_INFO_NO_REWINDS) { + diff = appl_ptr - old_appl_ptr; + if (diff >= 0) { + if (diff > runtime->buffer_size) + return -EINVAL; + } else { + if (runtime->boundary + diff > runtime->buffer_size) + return -EINVAL; + } + } runtime->control->appl_ptr = appl_ptr; if (substream->ops->ack) { -- cgit v1.2.3-70-g09d2 From 083a7fba38885a8ffa03a2857e383421cefd36e6 Mon Sep 17 00:00:00 2001 From: Oder Chiou <oder_chiou@realtek.com> Date: Thu, 25 Nov 2021 13:58:11 +0800 Subject: ASoC: rt5640: Add the binding include file for the HDA header support The patch adds the binding include file for the HDA header support. Signed-off-by: Oder Chiou <oder_chiou@realtek.com> Link: https://lore.kernel.org/r/20211125055812.8911-1-oder_chiou@realtek.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/dt-bindings/sound/rt5640.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/dt-bindings/sound/rt5640.h b/include/dt-bindings/sound/rt5640.h index 154c9b4414f2..655f6946388a 100644 --- a/include/dt-bindings/sound/rt5640.h +++ b/include/dt-bindings/sound/rt5640.h @@ -16,6 +16,7 @@ #define RT5640_JD_SRC_GPIO2 4 #define RT5640_JD_SRC_GPIO3 5 #define RT5640_JD_SRC_GPIO4 6 +#define RT5640_JD_SRC_HDA_HEADER 7 #define RT5640_OVCD_SF_0P5 0 #define RT5640_OVCD_SF_0P75 1 -- cgit v1.2.3-70-g09d2 From a0f84dfb3f6d9f78f862cbe885036d3e4449fc6f Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Date: Thu, 25 Nov 2021 12:15:19 +0200 Subject: ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags Some DAI components, such as HDaudio, need to be stopped in two steps a) stop the DAI component b) stop the DAI DMA This patch enables this two-step stop by expanding the DAI_CONFIG IPC flags and split them into 2 parts. The 4 LSB bits indicate when the DAI_CONFIG IPC is sent, ex: hw_params, hw_free or pause. The 4 MSB bits are used as the quirk flags to be used along with the command flags. The quirk flag called SOF_DAI_CONFIG_FLAGS_2_STEP_STOP shall be set along with the HW_PARAMS command flag, i.e. before the pipeline is started so that the stop/pause trigger op in the FW can take the appropriate action to either perform/skip the DMA stop. If set, the DMA stop will be executed when the DAI_CONFIG IPC is sent during hw_free. In the case of pause, DMA pause will be handled when the DAI_CONFIG IPC is sent with the PAUSE command flag. Along with this, modify the signature for the hda_ctrl_dai_widget_setup/ hda_ctrl_dai_widget_free() functions to take additional flags as an argument and modify all users to pass the appropriate quirk flags. Only the HDA DAI's need to pass the SOF_DAI_CONFIG_FLAGS_2_STEP_STOP quirk flag during hw_params to indicate that it supports two-step stop and pause. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Link: https://lore.kernel.org/r/20211125101520.291581-10-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof/dai.h | 25 +++++++++++++++++++------ sound/soc/sof/intel/hda-dai.c | 8 ++++---- sound/soc/sof/intel/hda.c | 26 ++++++++++++++++++-------- sound/soc/sof/intel/hda.h | 4 ++-- sound/soc/sof/sof-audio.c | 2 +- 5 files changed, 44 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index 5132bc60f54b..59ee50ac7705 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -52,12 +52,25 @@ #define SOF_DAI_FMT_INV_MASK 0x0f00 #define SOF_DAI_FMT_CLOCK_PROVIDER_MASK 0xf000 -/* DAI_CONFIG flags */ -#define SOF_DAI_CONFIG_FLAGS_MASK 0x3 -#define SOF_DAI_CONFIG_FLAGS_NONE (0 << 0) /**< DAI_CONFIG sent without stage information */ -#define SOF_DAI_CONFIG_FLAGS_HW_PARAMS (1 << 0) /**< DAI_CONFIG sent during hw_params stage */ -#define SOF_DAI_CONFIG_FLAGS_HW_FREE (2 << 0) /**< DAI_CONFIG sent during hw_free stage */ -#define SOF_DAI_CONFIG_FLAGS_RFU (3 << 0) /**< not used, reserved for future use */ +/* + * DAI_CONFIG flags. The 4 LSB bits are used for the commands, HW_PARAMS, HW_FREE and PAUSE + * representing when the IPC is sent. The 4 MSB bits are used to add quirks along with the above + * commands. + */ +#define SOF_DAI_CONFIG_FLAGS_CMD_MASK 0xF +#define SOF_DAI_CONFIG_FLAGS_NONE 0 /**< DAI_CONFIG sent without stage information */ +#define SOF_DAI_CONFIG_FLAGS_HW_PARAMS BIT(0) /**< DAI_CONFIG sent during hw_params stage */ +#define SOF_DAI_CONFIG_FLAGS_HW_FREE BIT(1) /**< DAI_CONFIG sent during hw_free stage */ +/**< DAI_CONFIG sent during pause trigger. Only available ABI 3.20 onwards */ +#define SOF_DAI_CONFIG_FLAGS_PAUSE BIT(2) +#define SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT 4 +#define SOF_DAI_CONFIG_FLAGS_QUIRK_MASK (0xF << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT) +/* + * This should be used along with the SOF_DAI_CONFIG_FLAGS_HW_PARAMS to indicate that pipeline + * stop/pause and DAI DMA stop/pause should happen in two steps. This change is only available + * ABI 3.20 onwards. + */ +#define SOF_DAI_CONFIG_FLAGS_2_STEP_STOP BIT(0) /** \brief Types of DAI */ enum sof_ipc_dai_type { diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 748e8ed61475..bce5366cf913 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -197,9 +197,9 @@ static int hda_link_dai_widget_update(struct sof_intel_hda_stream *hda_stream, /* set up/free DAI widget and send DAI_CONFIG IPC */ if (widget_setup) - return hda_ctrl_dai_widget_setup(w); + return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP); - return hda_ctrl_dai_widget_free(w); + return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE); } static int hda_link_hw_params(struct snd_pcm_substream *substream, @@ -452,9 +452,9 @@ static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd return 0; if (setup) - return hda_ctrl_dai_widget_setup(w); + return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE); - return hda_ctrl_dai_widget_free(w); + return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE); } static int ssp_dai_startup(struct snd_pcm_substream *substream, diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 1e1e9659ea86..cfe026dbf124 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -41,7 +41,7 @@ #define EXCEPT_MAX_HDR_SIZE 0x400 #define HDA_EXT_ROM_STATUS_SIZE 8 -int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w) +int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags) { struct snd_sof_widget *swidget = w->dobj.private; struct snd_soc_component *component = swidget->scomp; @@ -58,6 +58,13 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w) return -EINVAL; } + /* DAI already configured, reset it before reconfiguring it */ + if (sof_dai->configured) { + ret = hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE); + if (ret < 0) + return ret; + } + config = &sof_dai->dai_config[sof_dai->current_config]; /* @@ -71,8 +78,10 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w) return ret; } - /* set HW_PARAMS flag */ - config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_MASK, SOF_DAI_CONFIG_FLAGS_HW_PARAMS); + /* set HW_PARAMS flag along with quirks */ + config->flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS | + quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT; + /* send DAI_CONFIG IPC */ ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size, @@ -87,7 +96,7 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w) return 0; } -int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w) +int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags) { struct snd_sof_widget *swidget = w->dobj.private; struct snd_soc_component *component = swidget->scomp; @@ -110,8 +119,9 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w) config = &sof_dai->dai_config[sof_dai->current_config]; - /* set HW_FREE flag */ - config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_MASK, SOF_DAI_CONFIG_FLAGS_HW_FREE); + /* set HW_FREE flag along with any quirks */ + config->flags = SOF_DAI_CONFIG_FLAGS_HW_FREE | + quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT; ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size, &reply, sizeof(reply)); @@ -166,9 +176,9 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev, config->alh.stream_id = alh_stream_id; if (setup) - return hda_ctrl_dai_widget_setup(w); + return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE); - return hda_ctrl_dai_widget_free(w); + return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE); } static int sdw_params_stream(struct device *dev, diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 60139ea9b8de..72e78c449aa8 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -739,7 +739,7 @@ int hda_pci_intel_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) struct snd_sof_dai; struct sof_ipc_dai_config; -int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w); -int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w); +int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags); +int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags); #endif diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index a275f7b7c812..58a62bfb16ab 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -57,7 +57,7 @@ static int sof_dai_config_setup(struct snd_sof_dev *sdev, struct snd_sof_dai *da } /* set NONE flag to clear all previous settings */ - config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_MASK, SOF_DAI_CONFIG_FLAGS_NONE); + config->flags = SOF_DAI_CONFIG_FLAGS_NONE; ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size, &reply, sizeof(reply)); -- cgit v1.2.3-70-g09d2 From 8544f08c816292c2219f28c6eaa69236b978bfb9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Date: Tue, 16 Nov 2021 16:45:12 +0900 Subject: ASoC: soc-dai: update snd_soc_dai_delay() to snd_soc_pcm_dai_delay() Current soc_pcm_pointer() is manually calculating both CPU-DAI's max delay (= A) and Codec-DAI's max delay (= B). static snd_pcm_uframes_t soc_pcm_pointer(...) { ... ^ for_each_rtd_cpu_dais(rtd, i, cpu_dai) (A) cpu_delay = max(cpu_delay, ...); v delay += cpu_delay; ^ for_each_rtd_codec_dais(rtd, i, codec_dai) (B) codec_delay = max(codec_delay, ...); v delay += codec_delay; runtime->delay = delay; ... } Current soc_pcm_pointer() and the total delay calculating is not readable / difficult to understand. This patch update snd_soc_dai_delay() to snd_soc_pcm_dai_delay(), and calcule both CPU/Codec delay in one function. Link: https://lore.kernel.org/r/87fszl4yrq.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/875yssy25z.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/soc-dai.h | 4 ++-- sound/soc/soc-dai.c | 40 ++++++++++++++++++++++++++++------------ sound/soc/soc-pcm.c | 18 ++---------------- 3 files changed, 32 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 0dcb361a98bb..5d4dd7c5450b 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -208,8 +208,6 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai, struct snd_pcm_substream *substream); void snd_soc_dai_shutdown(struct snd_soc_dai *dai, struct snd_pcm_substream *substream, int rollback); -snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai, - struct snd_pcm_substream *substream); void snd_soc_dai_suspend(struct snd_soc_dai *dai); void snd_soc_dai_resume(struct snd_soc_dai *dai); int snd_soc_dai_compress_new(struct snd_soc_dai *dai, @@ -238,6 +236,8 @@ int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd, int rollback); int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream, int cmd); +void snd_soc_pcm_dai_delay(struct snd_pcm_substream *substream, + snd_pcm_sframes_t *cpu_delay, snd_pcm_sframes_t *codec_delay); int snd_soc_dai_compr_startup(struct snd_soc_dai *dai, struct snd_compr_stream *cstream); diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 3db0fcf24385..6078afe335f8 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -453,18 +453,6 @@ void snd_soc_dai_shutdown(struct snd_soc_dai *dai, soc_dai_mark_pop(dai, substream, startup); } -snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai, - struct snd_pcm_substream *substream) -{ - int delay = 0; - - if (dai->driver->ops && - dai->driver->ops->delay) - delay = dai->driver->ops->delay(substream, dai); - - return delay; -} - int snd_soc_dai_compress_new(struct snd_soc_dai *dai, struct snd_soc_pcm_runtime *rtd, int num) { @@ -693,6 +681,34 @@ int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream, return 0; } +void snd_soc_pcm_dai_delay(struct snd_pcm_substream *substream, + snd_pcm_sframes_t *cpu_delay, + snd_pcm_sframes_t *codec_delay) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_dai *dai; + int i; + + /* + * We're looking for the delay through the full audio path so it needs to + * be the maximum of the DAIs doing transmit and the maximum of the DAIs + * doing receive (ie, all CPUs and all CODECs) rather than just the maximum + * of all DAIs. + */ + + /* for CPU */ + for_each_rtd_cpu_dais(rtd, i, dai) + if (dai->driver->ops && + dai->driver->ops->delay) + *cpu_delay = max(*cpu_delay, dai->driver->ops->delay(substream, dai)); + + /* for Codec */ + for_each_rtd_codec_dais(rtd, i, dai) + if (dai->driver->ops && + dai->driver->ops->delay) + *codec_delay = max(*codec_delay, dai->driver->ops->delay(substream, dai)); +} + int snd_soc_dai_compr_startup(struct snd_soc_dai *dai, struct snd_compr_stream *cstream) { diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 4d41ad302802..82fd170e16af 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1084,15 +1084,11 @@ start_err: */ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *cpu_dai; - struct snd_soc_dai *codec_dai; struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t offset = 0; snd_pcm_sframes_t delay = 0; snd_pcm_sframes_t codec_delay = 0; snd_pcm_sframes_t cpu_delay = 0; - int i; /* clearing the previous total delay */ runtime->delay = 0; @@ -1102,19 +1098,9 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) /* base delay if assigned in pointer callback */ delay = runtime->delay; - for_each_rtd_cpu_dais(rtd, i, cpu_dai) { - cpu_delay = max(cpu_delay, - snd_soc_dai_delay(cpu_dai, substream)); - } - delay += cpu_delay; - - for_each_rtd_codec_dais(rtd, i, codec_dai) { - codec_delay = max(codec_delay, - snd_soc_dai_delay(codec_dai, substream)); - } - delay += codec_delay; + snd_soc_pcm_dai_delay(substream, &cpu_delay, &codec_delay); - runtime->delay = delay; + runtime->delay = delay + cpu_delay + codec_delay; return offset; } -- cgit v1.2.3-70-g09d2 From 403f830e7a0be5a9e33c7a9d208574f79887ec57 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Date: Tue, 16 Nov 2021 16:45:18 +0900 Subject: ASoC: soc-component: add snd_soc_pcm_component_delay() Current soc-pcm.c :: soc_pcm_pointer() is assuming that component driver might update runtime->delay silently in snd_soc_pcm_component_pointer() (= A). static snd_pcm_uframes_t soc_pcm_pointer(...) { ... /* clearing the previous total delay */ => runtime->delay = 0; (A) offset = snd_soc_pcm_component_pointer(substream); /* base delay if assigned in pointer callback */ => delay = runtime->delay; ... } 1) The behavior that ".pointer callback secretly updates runtime->delay" is strange and confusable. 2) Current snd_soc_pcm_component_pointer() uses 1st found component's .pointer callback only, thus it is no problem for now. But runtime->delay might be overwrote if it adjusted to multiple components in the future. 3) Component delay is updated at .pointer callback timing (secretly). But some components which doesn't have .pointer callback might want to increase runtime->delay for some reasons. We already have .delay function for DAI, but not have for Component. This patch adds new snd_soc_pcm_component_delay() for it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/874k8cy25t.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/soc-component.h | 4 ++++ sound/soc/soc-component.c | 28 ++++++++++++++++++++++++++++ sound/soc/soc-pcm.c | 2 ++ 3 files changed, 34 insertions(+) (limited to 'include') diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index a4317144ab62..a52080407b98 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -148,6 +148,8 @@ struct snd_soc_component_driver { struct vm_area_struct *vma); int (*ack)(struct snd_soc_component *component, struct snd_pcm_substream *substream); + snd_pcm_sframes_t (*delay)(struct snd_soc_component *component, + struct snd_pcm_substream *substream); const struct snd_compress_ops *compress_ops; @@ -505,5 +507,7 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd, void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd, void *stream, int rollback); int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream); +void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream, + snd_pcm_sframes_t *cpu_delay, snd_pcm_sframes_t *codec_delay); #endif /* __SOC_COMPONENT_H */ diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index c76ff9c59dfb..c0664f94990c 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -932,6 +932,34 @@ int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) return 0; } +void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream, + snd_pcm_sframes_t *cpu_delay, + snd_pcm_sframes_t *codec_delay) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_component *component; + snd_pcm_sframes_t delay; + int i; + + /* + * We're looking for the delay through the full audio path so it needs to + * be the maximum of the Components doing transmit and the maximum of the + * Components doing receive (ie, all CPUs and all CODECs) rather than + * just the maximum of all Components. + */ + for_each_rtd_components(rtd, i, component) { + if (!component->driver->delay) + continue; + + delay = component->driver->delay(component, substream); + + if (snd_soc_component_is_codec(component)) + *codec_delay = max(*codec_delay, delay); + else + *cpu_delay = max(*cpu_delay, delay); + } +} + int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 82fd170e16af..493d231a2ffd 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1098,7 +1098,9 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) /* base delay if assigned in pointer callback */ delay = runtime->delay; + /* should be called *after* snd_soc_pcm_component_pointer() */ snd_soc_pcm_dai_delay(substream, &cpu_delay, &codec_delay); + snd_soc_pcm_component_delay(substream, &cpu_delay, &codec_delay); runtime->delay = delay + cpu_delay + codec_delay; -- cgit v1.2.3-70-g09d2 From 7cfa3d00730a4c0694b55fb1974823baeab8815b Mon Sep 17 00:00:00 2001 From: Shuming Fan <shumingf@realtek.com> Date: Wed, 8 Dec 2021 18:17:18 +0800 Subject: ASoC: rt5682s: add delay time to fix pop sound issue There is a pop noise at the beginning of the capture data. This patch adds the delay time before stereo1 ADC unmute to fix the pop sound issue. Signed-off-by: Shuming Fan <shumingf@realtek.com> Link: https://lore.kernel.org/r/20211208101718.28945-1-shumingf@realtek.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/rt5682s.h | 1 + sound/soc/codecs/rt5682s.c | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/sound/rt5682s.h b/include/sound/rt5682s.h index accfbc2dcdd2..f18d91308b9a 100644 --- a/include/sound/rt5682s.h +++ b/include/sound/rt5682s.h @@ -40,6 +40,7 @@ struct rt5682s_platform_data { enum rt5682s_jd_src jd_src; unsigned int dmic_clk_rate; unsigned int dmic_delay; + unsigned int amic_delay; bool dmic_clk_driving_high; const char *dai_clk_names[RT5682S_DAI_NUM_CLKS]; diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index d49a4f68566d..efa1016831dd 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -1367,6 +1367,31 @@ static int rt5682s_hp_amp_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt5682s_stereo1_adc_mixl_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 rt5682s_priv *rt5682s = snd_soc_component_get_drvdata(component); + unsigned int delay = 0; + + if (rt5682s->pdata.amic_delay) + delay = rt5682s->pdata.amic_delay; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msleep(delay); + snd_soc_component_update_bits(component, RT5682S_STO1_ADC_DIG_VOL, + RT5682S_L_MUTE, 0); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_component_update_bits(component, RT5682S_STO1_ADC_DIG_VOL, + RT5682S_L_MUTE, RT5682S_L_MUTE); + break; + } + + return 0; +} + static int sar_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1680,9 +1705,10 @@ static const struct snd_soc_dapm_widget rt5682s_dapm_widgets[] = { /* ADC Mixer */ SND_SOC_DAPM_SUPPLY("ADC Stereo1 Filter", RT5682S_PWR_DIG_2, RT5682S_PWR_ADC_S1F_BIT, 0, set_filter_clk, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", RT5682S_STO1_ADC_DIG_VOL, - RT5682S_L_MUTE_SFT, 1, rt5682s_sto1_adc_l_mix, - ARRAY_SIZE(rt5682s_sto1_adc_l_mix)), + SND_SOC_DAPM_MIXER_E("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, + rt5682s_sto1_adc_l_mix, ARRAY_SIZE(rt5682s_sto1_adc_l_mix), + rt5682s_stereo1_adc_mixl_event, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", RT5682S_STO1_ADC_DIG_VOL, RT5682S_R_MUTE_SFT, 1, rt5682s_sto1_adc_r_mix, ARRAY_SIZE(rt5682s_sto1_adc_r_mix)), @@ -2885,6 +2911,8 @@ static int rt5682s_parse_dt(struct rt5682s_priv *rt5682s, struct device *dev) &rt5682s->pdata.dmic_clk_rate); device_property_read_u32(dev, "realtek,dmic-delay-ms", &rt5682s->pdata.dmic_delay); + device_property_read_u32(dev, "realtek,amic-delay-ms", + &rt5682s->pdata.amic_delay); rt5682s->pdata.ldo1_en = of_get_named_gpio(dev->of_node, "realtek,ldo1-en-gpios", 0); -- cgit v1.2.3-70-g09d2 From b7898396f4bbe160f546d0c5e9fa17cca9a7d153 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Tue, 7 Dec 2021 11:37:42 -0600 Subject: ASoC: soc-pcm: Fix and cleanup DPCM locking The existing locking for DPCM has several issues a) a confusing mix of card->mutex and card->pcm_mutex. b) a dpcm_lock spinlock added inconsistently and on paths that could be recursively taken. The use of irqsave/irqrestore was also overkill. The suggested model is: 1) The pcm_mutex is the top-most protection of BE links in the FE. The pcm_mutex is applied always on either the top PCM callbacks or the external call from DAPM, not taken in the internal functions. 2) the FE stream lock is taken in higher levels before invoking dpcm_be_dai_trigger() 3) when adding and deleting a BE, both the pcm_mutex and FE stream lock are taken. Signed-off-by: Takashi Iwai <tiwai@suse.de> [clarification of commit message by plbossart] Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20211207173745.15850-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/soc.h | 2 - sound/soc/soc-core.c | 1 - sound/soc/soc-pcm.c | 229 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 152 insertions(+), 80 deletions(-) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index 8e6dd8a257c5..5872a8864f3b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -893,8 +893,6 @@ struct snd_soc_card { struct mutex pcm_mutex; enum snd_soc_pcm_subclass pcm_subclass; - spinlock_t dpcm_lock; - int (*probe)(struct snd_soc_card *card); int (*late_probe)(struct snd_soc_card *card); int (*remove)(struct snd_soc_card *card); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index dcf6be4c4aaa..1d62160f96b1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2315,7 +2315,6 @@ int snd_soc_register_card(struct snd_soc_card *card) mutex_init(&card->mutex); mutex_init(&card->dapm_mutex); mutex_init(&card->pcm_mutex); - spin_lock_init(&card->dpcm_lock); return snd_soc_bind_card(card); } diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 3a34b71fd3c1..2e282c42bac2 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -27,6 +27,31 @@ #include <sound/soc-link.h> #include <sound/initval.h> +static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd) +{ + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); +} + +static inline void snd_soc_dpcm_mutex_unlock(struct snd_soc_pcm_runtime *rtd) +{ + mutex_unlock(&rtd->card->pcm_mutex); +} + +#define snd_soc_dpcm_mutex_assert_held(rtd) \ + lockdep_assert_held(&(rtd)->card->pcm_mutex) + +static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd, + int stream) +{ + snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream)); +} + +static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd, + int stream) +{ + snd_pcm_stream_unlock_irq(snd_soc_dpcm_get_substream(rtd, stream)); +} + #define DPCM_MAX_BE_USERS 8 static inline const char *soc_cpu_dai_name(struct snd_soc_pcm_runtime *rtd) @@ -73,7 +98,6 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; struct snd_soc_dpcm *dpcm; ssize_t offset = 0; - unsigned long flags; /* FE state */ offset += scnprintf(buf + offset, size - offset, @@ -101,7 +125,6 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, goto out; } - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; params = &dpcm->hw_params; @@ -122,7 +145,6 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, params_channels(params), params_rate(params)); } - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); out: return offset; } @@ -145,11 +167,13 @@ static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; + snd_soc_dpcm_mutex_lock(fe); for_each_pcm_streams(stream) if (snd_soc_dai_stream_valid(asoc_rtd_to_cpu(fe, 0), stream)) offset += dpcm_show_state(fe, stream, buf + offset, out_count - offset); + snd_soc_dpcm_mutex_unlock(fe); ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset); @@ -221,14 +245,14 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, struct snd_pcm_substream *substream = snd_soc_dpcm_get_substream(fe, stream); - snd_pcm_stream_lock_irq(substream); + snd_soc_dpcm_stream_lock_irq(fe, stream); if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) { dpcm_fe_dai_do_trigger(substream, fe->dpcm[stream].trigger_pending - 1); fe->dpcm[stream].trigger_pending = 0; } fe->dpcm[stream].runtime_update = state; - snd_pcm_stream_unlock_irq(substream); + snd_soc_dpcm_stream_unlock_irq(fe, stream); } static void dpcm_set_be_update_state(struct snd_soc_pcm_runtime *be, @@ -256,7 +280,7 @@ void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai; int i; - lockdep_assert_held(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_assert_held(rtd); for_each_rtd_dais(rtd, i, dai) snd_soc_dai_action(dai, stream, action); @@ -309,6 +333,8 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, { struct snd_soc_dpcm *dpcm; + snd_soc_dpcm_mutex_assert_held(fe); + for_each_dpcm_be(fe, dir, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; @@ -646,14 +672,14 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream, return ret; } -static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback) +static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream, int rollback) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component; struct snd_soc_dai *dai; int i; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); if (!rollback) snd_soc_runtime_deactivate(rtd, substream->stream); @@ -665,9 +691,6 @@ static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback) soc_pcm_components_close(substream, rollback); - - mutex_unlock(&rtd->card->pcm_mutex); - snd_soc_pcm_component_pm_runtime_put(rtd, substream, rollback); for_each_rtd_components(rtd, i, component) @@ -682,9 +705,21 @@ static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback) * freed here. The cpu DAI, codec DAI, machine and components are also * shutdown. */ +static int __soc_pcm_close(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) +{ + return soc_pcm_clean(rtd, substream, 0); +} + +/* PCM close ops for non-DPCM streams */ static int soc_pcm_close(struct snd_pcm_substream *substream) { - return soc_pcm_clean(substream, 0); + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + + snd_soc_dpcm_mutex_lock(rtd); + soc_pcm_clean(rtd, substream, 0); + snd_soc_dpcm_mutex_unlock(rtd); + return 0; } static int soc_hw_sanity_check(struct snd_pcm_substream *substream) @@ -730,21 +765,21 @@ config_err: * then initialized and any private data can be allocated. This also calls * startup for the cpu DAI, component, machine and codec DAI. */ -static int soc_pcm_open(struct snd_pcm_substream *substream) +static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component; struct snd_soc_dai *dai; int i, ret = 0; + snd_soc_dpcm_mutex_assert_held(rtd); + for_each_rtd_components(rtd, i, component) pinctrl_pm_select_default_state(component->dev); ret = snd_soc_pcm_component_pm_runtime_get(rtd, substream); if (ret < 0) - goto pm_err; - - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + goto err; ret = soc_pcm_components_open(substream); if (ret < 0) @@ -791,16 +826,26 @@ dynamic: snd_soc_runtime_activate(rtd, substream->stream); ret = 0; err: - mutex_unlock(&rtd->card->pcm_mutex); -pm_err: if (ret < 0) { - soc_pcm_clean(substream, 1); + soc_pcm_clean(rtd, substream, 1); dev_err(rtd->dev, "%s() failed (%d)", __func__, ret); } return ret; } +/* PCM open ops for non-DPCM streams */ +static int soc_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_open(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd) { /* @@ -816,13 +861,13 @@ static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd) * rate, etc. This function is non atomic and can be called multiple times, * it can refer to the runtime info. */ -static int soc_pcm_prepare(struct snd_pcm_substream *substream) +static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *dai; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); ret = snd_soc_link_prepare(substream); if (ret < 0) @@ -850,14 +895,24 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) snd_soc_dai_digital_mute(dai, 0, substream->stream); out: - mutex_unlock(&rtd->card->pcm_mutex); - if (ret < 0) dev_err(rtd->dev, "ASoC: %s() failed (%d)\n", __func__, ret); return ret; } +/* PCM prepare ops for non-DPCM streams */ +static int soc_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_prepare(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params, unsigned int mask) { @@ -869,13 +924,13 @@ static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params, interval->max = channels; } -static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback) +static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream, int rollback) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *dai; int i; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); /* clear the corresponding DAIs parameters when going to be inactive */ for_each_rtd_dais(rtd, i, dai) { @@ -900,16 +955,28 @@ static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback) if (snd_soc_dai_stream_valid(dai, substream->stream)) snd_soc_dai_hw_free(dai, substream, rollback); - mutex_unlock(&rtd->card->pcm_mutex); return 0; } /* * Frees resources allocated by hw_params, can be called multiple times */ +static int __soc_pcm_hw_free(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) +{ + return soc_pcm_hw_clean(rtd, substream, 0); +} + +/* hw_free PCM ops for non-DPCM streams */ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) { - return soc_pcm_hw_clean(substream, 0); + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_hw_free(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; } /* @@ -917,15 +984,15 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) * function can also be called multiple times and can allocate buffers * (using snd_pcm_lib_* ). It's non-atomic. */ -static int soc_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) +static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, + 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_dai *cpu_dai; struct snd_soc_dai *codec_dai; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); ret = soc_pcm_params_symmetry(substream, params); if (ret) @@ -997,16 +1064,27 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_pcm_component_hw_params(substream, params); out: - mutex_unlock(&rtd->card->pcm_mutex); - if (ret < 0) { - soc_pcm_hw_clean(substream, 1); + soc_pcm_hw_clean(rtd, substream, 1); dev_err(rtd->dev, "ASoC: %s() failed (%d)\n", __func__, ret); } return ret; } +/* hw_params PCM ops for non-DPCM streams */ +static int soc_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_hw_params(rtd, substream, params); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); @@ -1107,7 +1185,8 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, struct snd_pcm_substream *fe_substream; struct snd_pcm_substream *be_substream; struct snd_soc_dpcm *dpcm; - unsigned long flags; + + snd_soc_dpcm_mutex_assert_held(fe); /* only add new dpcms */ for_each_dpcm_be(fe, stream, dpcm) { @@ -1137,10 +1216,10 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, dpcm->fe = fe; be->dpcm[stream].runtime = fe->dpcm[stream].runtime; dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; - spin_lock_irqsave(&fe->card->dpcm_lock, flags); + snd_soc_dpcm_stream_lock_irq(fe, stream); list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + snd_soc_dpcm_stream_unlock_irq(fe, stream); dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", stream ? "capture" : "playback", fe->dai_link->name, @@ -1183,8 +1262,10 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm, *d; - unsigned long flags; + snd_soc_dpcm_mutex_assert_held(fe); + + snd_soc_dpcm_stream_lock_irq(fe, stream); for_each_dpcm_be_safe(fe, stream, dpcm, d) { dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", stream ? "capture" : "playback", @@ -1202,12 +1283,11 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) dpcm_remove_debugfs_state(dpcm); - spin_lock_irqsave(&fe->card->dpcm_lock, flags); list_del(&dpcm->list_be); list_del(&dpcm->list_fe); - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); kfree(dpcm); } + snd_soc_dpcm_stream_unlock_irq(fe, stream); } /* get BE for DAI widget and stream */ @@ -1431,12 +1511,9 @@ int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; - unsigned long flags; - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_NO); - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); } void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, @@ -1472,12 +1549,12 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, continue; if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) { - soc_pcm_hw_free(be_substream); + __soc_pcm_hw_free(be, be_substream); be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; } } - soc_pcm_close(be_substream); + __soc_pcm_close(be, be_substream); be_substream->runtime = NULL; be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; } @@ -1525,7 +1602,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) stream ? "capture" : "playback", be->dai_link->name); be_substream->runtime = be->dpcm[stream].runtime; - err = soc_pcm_open(be_substream); + err = __soc_pcm_open(be, be_substream); if (err < 0) { be->dpcm[stream].users--; if (be->dpcm[stream].users < 0) @@ -1769,7 +1846,7 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name); /* start the DAI frontend */ - ret = soc_pcm_open(fe_substream); + ret = __soc_pcm_open(fe, fe_substream); if (ret < 0) goto unwind; @@ -1800,6 +1877,8 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int stream = substream->stream; + snd_soc_dpcm_mutex_assert_held(fe); + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); /* shutdown the BEs */ @@ -1808,7 +1887,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); /* now shutdown the frontend */ - soc_pcm_close(substream); + __soc_pcm_close(fe, substream); /* run the stream stop event */ dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); @@ -1853,7 +1932,7 @@ void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: hw_free BE %s\n", be->dai_link->name); - soc_pcm_hw_free(be_substream); + __soc_pcm_hw_free(be, be_substream); be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; } @@ -1864,13 +1943,13 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int stream = substream->stream; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name); /* call hw_free on the frontend */ - soc_pcm_hw_free(substream); + soc_pcm_hw_clean(fe, substream, 0); /* only hw_params backends that are either sinks or sources * to this frontend DAI */ @@ -1879,7 +1958,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); return 0; } @@ -1923,7 +2002,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: hw_params BE %s\n", be->dai_link->name); - ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); + ret = __soc_pcm_hw_params(be, be_substream, &dpcm->hw_params); if (ret < 0) goto unwind; @@ -1953,7 +2032,7 @@ unwind: (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) continue; - soc_pcm_hw_free(be_substream); + __soc_pcm_hw_free(be, be_substream); } return ret; @@ -1965,7 +2044,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int ret, stream = substream->stream; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); memcpy(&fe->dpcm[stream].hw_params, params, @@ -1979,7 +2058,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, params_channels(params), params_format(params)); /* call hw_params on the frontend */ - ret = soc_pcm_hw_params(substream, params); + ret = __soc_pcm_hw_params(fe, substream, params); if (ret < 0) dpcm_be_dai_hw_free(fe, stream); else @@ -1987,7 +2066,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, out: dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); if (ret < 0) dev_err(fe->dev, "ASoC: %s failed (%d)\n", __func__, ret); @@ -2258,7 +2337,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: prepare BE %s\n", be->dai_link->name); - ret = soc_pcm_prepare(be_substream); + ret = __soc_pcm_prepare(be, be_substream); if (ret < 0) break; @@ -2276,7 +2355,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int stream = substream->stream, ret = 0; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name); @@ -2295,7 +2374,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) goto out; /* call prepare on the frontend */ - ret = soc_pcm_prepare(substream); + ret = __soc_pcm_prepare(fe, substream); if (ret < 0) goto out; @@ -2303,7 +2382,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) out: dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); if (ret < 0) dev_err(fe->dev, "ASoC: %s() failed (%d)\n", __func__, ret); @@ -2354,7 +2433,6 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) struct snd_soc_dpcm *dpcm; enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; int ret = 0; - unsigned long flags; dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", stream ? "capture" : "playback", fe->dai_link->name); @@ -2423,7 +2501,6 @@ close: dpcm_be_dai_shutdown(fe, stream); disconnect: /* disconnect any pending BEs */ - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; @@ -2435,7 +2512,6 @@ disconnect: be->dpcm[stream].state == SND_SOC_DPCM_STATE_NEW) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; } - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); if (ret < 0) dev_err(fe->dev, "ASoC: %s() failed (%d)\n", __func__, ret); @@ -2510,7 +2586,7 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) struct snd_soc_pcm_runtime *fe; int ret = 0; - mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass); /* shutdown all old paths first */ for_each_card_rtds(card, fe) { ret = soc_dpcm_fe_runtime_update(fe, 0); @@ -2526,7 +2602,7 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) } out: - mutex_unlock(&card->mutex); + mutex_unlock(&card->pcm_mutex); return ret; } EXPORT_SYMBOL_GPL(snd_soc_dpcm_runtime_update); @@ -2537,6 +2613,8 @@ static void dpcm_fe_dai_cleanup(struct snd_pcm_substream *fe_substream) struct snd_soc_dpcm *dpcm; int stream = fe_substream->stream; + snd_soc_dpcm_mutex_assert_held(fe); + /* mark FE's links ready to prune */ for_each_dpcm_be(fe, stream, dpcm) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; @@ -2551,12 +2629,12 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(fe_substream); int ret; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); ret = dpcm_fe_dai_shutdown(fe_substream); dpcm_fe_dai_cleanup(fe_substream); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); return ret; } @@ -2567,7 +2645,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) int ret; int stream = fe_substream->stream; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); fe->dpcm[stream].runtime = fe_substream->runtime; ret = dpcm_path_get(fe, stream, &list); @@ -2584,7 +2662,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) dpcm_clear_pending_state(fe, stream); dpcm_path_put(&list); open_end: - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); return ret; } @@ -2845,10 +2923,8 @@ static int snd_soc_dpcm_check_state(struct snd_soc_pcm_runtime *fe, struct snd_soc_dpcm *dpcm; int state; int ret = 1; - unsigned long flags; int i; - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_fe(be, stream, dpcm) { if (dpcm->fe == fe) @@ -2862,7 +2938,6 @@ static int snd_soc_dpcm_check_state(struct snd_soc_pcm_runtime *fe, } } } - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); /* it's safe to do this BE DAI */ return ret; -- cgit v1.2.3-70-g09d2 From 848aedfdc6ba25ad5652797db9266007773e44dd Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Date: Tue, 7 Dec 2021 11:37:44 -0600 Subject: ASoC: soc-pcm: test refcount before triggering On start/pause_release/resume, when more than one FE is connected to the same BE, it's possible that the trigger is sent more than once. This is not desirable, we only want to trigger a BE once, which is straightforward to implement with a refcount. For stop/pause/suspend, the problem is more complicated: the check implemented in snd_soc_dpcm_can_be_free_stop() may fail due to a conceptual deadlock when we trigger the BE before the FE. In this case, the FE states have not yet changed, so there are corner cases where the TRIGGER_STOP is never sent - the dual case of start where multiple triggers might be sent. This patch suggests an unconditional trigger in all cases, without checking the FE states, using a refcount protected by the BE PCM stream lock. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20211207173745.15850-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/soc-dpcm.h | 2 ++ sound/soc/soc-pcm.c | 53 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h index bc7af90099a8..75b92d883976 100644 --- a/include/sound/soc-dpcm.h +++ b/include/sound/soc-dpcm.h @@ -101,6 +101,8 @@ struct snd_soc_dpcm_runtime { enum snd_soc_dpcm_state state; int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */ + + int be_start; /* refcount protected by BE stream pcm lock */ }; #define for_each_dpcm_fe(be, stream, _dpcm) \ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 7043857e30b1..05a0f52eb11b 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1619,7 +1619,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; goto unwind; } - + be->dpcm[stream].be_start = 0; be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; count++; } @@ -2105,14 +2105,21 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && + if (!be->dpcm[stream].be_start && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; + be->dpcm[stream].be_start++; + if (be->dpcm[stream].be_start != 1) + goto next; + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start--; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; @@ -2120,9 +2127,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) goto next; + be->dpcm[stream].be_start++; + if (be->dpcm[stream].be_start != 1) + goto next; + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start--; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; @@ -2130,9 +2143,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; + be->dpcm[stream].be_start++; + if (be->dpcm[stream].be_start != 1) + goto next; + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start--; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; @@ -2141,12 +2160,18 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; - if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) + if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_START) + be->dpcm[stream].be_start--; + + if (be->dpcm[stream].be_start != 0) goto next; ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_START) + be->dpcm[stream].be_start++; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; break; @@ -2154,12 +2179,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) goto next; - if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) + be->dpcm[stream].be_start--; + if (be->dpcm[stream].be_start != 0) goto next; ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start++; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND; break; @@ -2167,12 +2195,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) goto next; - if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) + be->dpcm[stream].be_start--; + if (be->dpcm[stream].be_start != 0) goto next; ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start++; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; break; -- cgit v1.2.3-70-g09d2 From bdecfceffeeb9000e78b0f613069f5c06974b347 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Mon, 22 Nov 2021 23:21:54 +0100 Subject: ASoC: dai_dma: remove slave_id field This field is no longer set from any driver now, so remove the last references as well. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20211122222203.4103644-3-arnd@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org> --- include/sound/dmaengine_pcm.h | 2 -- sound/core/pcm_dmaengine.c | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 96666efddb39..38ea046e653c 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -60,7 +60,6 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) * @maxburst: Maximum number of words(note: words, as in units of the * src_addr_width member, not bytes) that can be send to or received from the * DAI in one burst. - * @slave_id: Slave requester id for the DMA channel. * @filter_data: Custom DMA channel filter data, this will usually be used when * requesting the DMA channel. * @chan_name: Custom channel name to use when requesting DMA channel. @@ -74,7 +73,6 @@ struct snd_dmaengine_dai_dma_data { dma_addr_t addr; enum dma_slave_buswidth addr_width; u32 maxburst; - unsigned int slave_id; void *filter_data; const char *chan_name; unsigned int fifo_size; diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 1fc2fa077574..af6f717e1e7e 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -91,8 +91,8 @@ EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); * @dma_data: DAI DMA data * @slave_config: DMA slave configuration * - * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and - * slave_id fields of the DMA slave config from the same fields of the DAI DMA + * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width + * fields of the DMA slave config from the same fields of the DAI DMA * data struct. The src and dst fields will be initialized depending on the * direction of the substream. If the substream is a playback stream the dst * fields will be initialized, if it is a capture stream the src fields will be @@ -124,7 +124,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data( slave_config->src_addr_width = dma_data->addr_width; } - slave_config->slave_id = dma_data->slave_id; slave_config->peripheral_config = dma_data->peripheral_config; slave_config->peripheral_size = dma_data->peripheral_size; } -- cgit v1.2.3-70-g09d2 From 03de6b273805b3c552ff158f8688555937375926 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Mon, 22 Nov 2021 23:22:00 +0100 Subject: dmaengine: qcom-adm: stop abusing slave_id config The slave_id was previously used to pick one DMA slave instead of another, but this is now done through the DMA descriptors in device tree. For the qcom_adm driver, the configuration is documented in the DT binding to contain a tuple of device identifier and a "crci" field, but the implementation ends up using only a single cell for identifying the slave, with the crci getting passed in nonstandard properties of the device, and passed through the dma driver using the old slave_id field. Part of the problem apparently is that the nand driver ends up using only a single DMA request ID, but requires distinct values for "crci" depending on the type of transfer. Change both the dmaengine driver and the two slave drivers to allow the documented binding to work in addition to the ad-hoc passing of crci values. In order to no longer abuse the slave_id field, pass the data using the "peripheral_config" mechanism instead. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20211122222203.4103644-9-arnd@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org> --- drivers/dma/qcom/qcom_adm.c | 56 ++++++++++++++++++++++++++++++++++----- drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++++-- drivers/tty/serial/msm_serial.c | 15 +++++++++-- include/linux/dma/qcom_adm.h | 12 +++++++++ 4 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 include/linux/dma/qcom_adm.h (limited to 'include') diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c index ee78bed8d60d..facdacf8aede 100644 --- a/drivers/dma/qcom/qcom_adm.c +++ b/drivers/dma/qcom/qcom_adm.c @@ -8,6 +8,7 @@ #include <linux/device.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> +#include <linux/dma/qcom_adm.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -140,6 +141,8 @@ struct adm_chan { struct adm_async_desc *curr_txd; struct dma_slave_config slave; + u32 crci; + u32 mux; struct list_head node; int error; @@ -379,8 +382,8 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, return ERR_PTR(-EINVAL); } - crci = achan->slave.slave_id & 0xf; - if (!crci || achan->slave.slave_id > 0x1f) { + crci = achan->crci & 0xf; + if (!crci || achan->crci > 0x1f) { dev_err(adev->dev, "invalid crci value\n"); return ERR_PTR(-EINVAL); } @@ -403,9 +406,7 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, if (!async_desc) return ERR_PTR(-ENOMEM); - if (crci) - async_desc->mux = achan->slave.slave_id & ADM_CRCI_MUX_SEL ? - ADM_CRCI_CTL_MUX_SEL : 0; + async_desc->mux = achan->mux ? ADM_CRCI_CTL_MUX_SEL : 0; async_desc->crci = crci; async_desc->blk_size = blk_size; async_desc->dma_len = single_count * sizeof(struct adm_desc_hw_single) + @@ -488,10 +489,13 @@ static int adm_terminate_all(struct dma_chan *chan) static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) { struct adm_chan *achan = to_adm_chan(chan); + struct qcom_adm_peripheral_config *config = cfg->peripheral_config; unsigned long flag; spin_lock_irqsave(&achan->vc.lock, flag); memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config)); + if (cfg->peripheral_size == sizeof(config)) + achan->crci = config->crci; spin_unlock_irqrestore(&achan->vc.lock, flag); return 0; @@ -694,6 +698,45 @@ static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan, achan->vc.desc_free = adm_dma_free_desc; } +/** + * adm_dma_xlate + * @dma_spec: pointer to DMA specifier as found in the device tree + * @ofdma: pointer to DMA controller data + * + * This can use either 1-cell or 2-cell formats, the first cell + * identifies the slave device, while the optional second cell + * contains the crci value. + * + * Returns pointer to appropriate dma channel on success or NULL on error. + */ +static struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct dma_device *dev = ofdma->of_dma_data; + struct dma_chan *chan, *candidate = NULL; + struct adm_chan *achan; + + if (!dev || dma_spec->args_count > 2) + return NULL; + + list_for_each_entry(chan, &dev->channels, device_node) + if (chan->chan_id == dma_spec->args[0]) { + candidate = chan; + break; + } + + if (!candidate) + return NULL; + + achan = to_adm_chan(candidate); + if (dma_spec->args_count == 2) + achan->crci = dma_spec->args[1]; + else + achan->crci = 0; + + return dma_get_slave_channel(candidate); +} + static int adm_dma_probe(struct platform_device *pdev) { struct adm_device *adev; @@ -838,8 +881,7 @@ static int adm_dma_probe(struct platform_device *pdev) goto err_disable_clks; } - ret = of_dma_controller_register(pdev->dev.of_node, - of_dma_xlate_by_chan_id, + ret = of_dma_controller_register(pdev->dev.of_node, adm_dma_xlate, &adev->common); if (ret) goto err_unregister_dma; diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 04e6f7b26706..7c6efa3b6255 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -6,6 +6,7 @@ #include <linux/clk.h> #include <linux/slab.h> #include <linux/bitops.h> +#include <linux/dma/qcom_adm.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/module.h> @@ -952,6 +953,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, struct dma_async_tx_descriptor *dma_desc; struct scatterlist *sgl; struct dma_slave_config slave_conf; + struct qcom_adm_peripheral_config periph_conf = {}; enum dma_transfer_direction dir_eng; int ret; @@ -983,11 +985,19 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, if (read) { slave_conf.src_maxburst = 16; slave_conf.src_addr = nandc->base_dma + reg_off; - slave_conf.slave_id = nandc->data_crci; + if (nandc->data_crci) { + periph_conf.crci = nandc->data_crci; + slave_conf.peripheral_config = &periph_conf; + slave_conf.peripheral_size = sizeof(periph_conf); + } } else { slave_conf.dst_maxburst = 16; slave_conf.dst_addr = nandc->base_dma + reg_off; - slave_conf.slave_id = nandc->cmd_crci; + if (nandc->cmd_crci) { + periph_conf.crci = nandc->cmd_crci; + slave_conf.peripheral_config = &periph_conf; + slave_conf.peripheral_size = sizeof(periph_conf); + } } ret = dmaengine_slave_config(nandc->chan, &slave_conf); diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index fcef7a961430..c6be09f44dc1 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -9,6 +9,7 @@ #include <linux/kernel.h> #include <linux/atomic.h> +#include <linux/dma/qcom_adm.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/module.h> @@ -290,6 +291,7 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) { struct device *dev = msm_port->uart.dev; struct dma_slave_config conf; + struct qcom_adm_peripheral_config periph_conf = {}; struct msm_dma *dma; u32 crci = 0; int ret; @@ -308,7 +310,11 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) conf.device_fc = true; conf.dst_addr = base + UARTDM_TF; conf.dst_maxburst = UARTDM_BURST_SIZE; - conf.slave_id = crci; + if (crci) { + conf.peripheral_config = &periph_conf; + conf.peripheral_size = sizeof(periph_conf); + periph_conf.crci = crci; + } ret = dmaengine_slave_config(dma->chan, &conf); if (ret) @@ -333,6 +339,7 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base) { struct device *dev = msm_port->uart.dev; struct dma_slave_config conf; + struct qcom_adm_peripheral_config periph_conf = {}; struct msm_dma *dma; u32 crci = 0; int ret; @@ -355,7 +362,11 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base) conf.device_fc = true; conf.src_addr = base + UARTDM_RF; conf.src_maxburst = UARTDM_BURST_SIZE; - conf.slave_id = crci; + if (crci) { + conf.peripheral_config = &periph_conf; + conf.peripheral_size = sizeof(periph_conf); + periph_conf.crci = crci; + } ret = dmaengine_slave_config(dma->chan, &conf); if (ret) diff --git a/include/linux/dma/qcom_adm.h b/include/linux/dma/qcom_adm.h new file mode 100644 index 000000000000..af20df674f0c --- /dev/null +++ b/include/linux/dma/qcom_adm.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-only +#ifndef __LINUX_DMA_QCOM_ADM_H +#define __LINUX_DMA_QCOM_ADM_H + +#include <linux/types.h> + +struct qcom_adm_peripheral_config { + u32 crci; + u32 mux; +}; + +#endif /* __LINUX_DMA_QCOM_ADM_H */ -- cgit v1.2.3-70-g09d2 From 93cdb5b0dc56cc7a8b87a61146495f3bdc93d7ba Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Mon, 22 Nov 2021 23:22:01 +0100 Subject: dmaengine: xilinx_dpdma: stop using slave_id field The display driver wants to pass a custom flag to the DMA engine driver, which it started doing by using the slave_id field that was traditionally used for a different purpose. As there is no longer a correct use for the slave_id field, it should really be removed, and the remaining users changed over to something different. The new mechanism for passing nonstandard settings is using the .peripheral_config field, so use that to pass a newly defined structure here, making it clear that this will not work in portable drivers. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20211122222203.4103644-10-arnd@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org> --- drivers/dma/xilinx/xilinx_dpdma.c | 17 +++++++++++------ drivers/gpu/drm/xlnx/zynqmp_disp.c | 9 +++++++-- include/linux/dma/xilinx_dpdma.h | 11 +++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 include/linux/dma/xilinx_dpdma.h (limited to 'include') diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c index ce5c66e6897d..b0f4948b00a5 100644 --- a/drivers/dma/xilinx/xilinx_dpdma.c +++ b/drivers/dma/xilinx/xilinx_dpdma.c @@ -12,6 +12,7 @@ #include <linux/clk.h> #include <linux/debugfs.h> #include <linux/delay.h> +#include <linux/dma/xilinx_dpdma.h> #include <linux/dmaengine.h> #include <linux/dmapool.h> #include <linux/interrupt.h> @@ -1273,6 +1274,7 @@ static int xilinx_dpdma_config(struct dma_chan *dchan, struct dma_slave_config *config) { struct xilinx_dpdma_chan *chan = to_xilinx_chan(dchan); + struct xilinx_dpdma_peripheral_config *pconfig; unsigned long flags; /* @@ -1282,15 +1284,18 @@ static int xilinx_dpdma_config(struct dma_chan *dchan, * fixed both on the DPDMA side and on the DP controller side. */ - spin_lock_irqsave(&chan->lock, flags); - /* - * Abuse the slave_id to indicate that the channel is part of a video - * group. + * Use the peripheral_config to indicate that the channel is part + * of a video group. This requires matching use of the custom + * structure in each driver. */ - if (chan->id <= ZYNQMP_DPDMA_VIDEO2) - chan->video_group = config->slave_id != 0; + pconfig = config->peripheral_config; + if (WARN_ON(pconfig && config->peripheral_size != sizeof(*pconfig))) + return -EINVAL; + spin_lock_irqsave(&chan->lock, flags); + if (chan->id <= ZYNQMP_DPDMA_VIDEO2 && pconfig) + chan->video_group = pconfig->video_group; spin_unlock_irqrestore(&chan->lock, flags); return 0; diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index ff2b308d8651..11c409cbc88e 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -24,6 +24,7 @@ #include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma/xilinx_dpdma.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/module.h> @@ -1058,14 +1059,18 @@ static void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer, zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt); /* - * Set slave_id for each DMA channel to indicate they're part of a + * Set pconfig for each DMA channel to indicate they're part of a * video group. */ for (i = 0; i < info->num_planes; i++) { struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; + struct xilinx_dpdma_peripheral_config pconfig = { + .video_group = true, + }; struct dma_slave_config config = { .direction = DMA_MEM_TO_DEV, - .slave_id = 1, + .peripheral_config = &pconfig, + .peripheral_size = sizeof(pconfig), }; dmaengine_slave_config(dma->chan, &config); diff --git a/include/linux/dma/xilinx_dpdma.h b/include/linux/dma/xilinx_dpdma.h new file mode 100644 index 000000000000..83a1377f03f8 --- /dev/null +++ b/include/linux/dma/xilinx_dpdma.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __LINUX_DMA_XILINX_DPDMA_H +#define __LINUX_DMA_XILINX_DPDMA_H + +#include <linux/types.h> + +struct xilinx_dpdma_peripheral_config { + bool video_group; +}; + +#endif /* __LINUX_DMA_XILINX_DPDMA_H */ -- cgit v1.2.3-70-g09d2 From 3c219644075795a99271d345efdfa8b256e55161 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Mon, 22 Nov 2021 23:22:03 +0100 Subject: dmaengine: remove slave_id config field All references to the slave_id field have been removed, so remove the field as well to prevent new references from creeping in again. Originally this allowed slave DMA drivers to configure which device is accessed with the dmaengine_slave_config() call, but this was inconsistent, as the same information is also passed while requesting a channel, and never changes in practice. In modern kernels, the device is always selected when requesting the channel, so the .slave_id field is no longer useful. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20211122222203.4103644-12-arnd@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org> --- include/linux/dmaengine.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 9000f3ffce8b..0349b35235e6 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -418,9 +418,6 @@ enum dma_slave_buswidth { * @device_fc: Flow Controller Settings. Only valid for slave channels. Fill * with 'true' if peripheral should be flow controller. Direction will be * selected at Runtime. - * @slave_id: Slave requester id. Only valid for slave channels. The dma - * slave peripheral will have unique id as dma requester which need to be - * pass as slave config. * @peripheral_config: peripheral configuration for programming peripheral * for dmaengine transfer * @peripheral_size: peripheral configuration buffer size @@ -448,7 +445,6 @@ struct dma_slave_config { u32 src_port_window_size; u32 dst_port_window_size; bool device_fc; - unsigned int slave_id; void *peripheral_config; size_t peripheral_size; }; -- cgit v1.2.3-70-g09d2 From 60ded273e4c047aec364f70195aced71a4082f90 Mon Sep 17 00:00:00 2001 From: Karol Trzcinski <karolx.trzcinski@linux.intel.com> Date: Thu, 16 Dec 2021 17:24:22 -0600 Subject: ipc: debug: Add shared memory heap to memory scan Newly added shared heap zones should be taken into account during memory usage scanning. Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Signed-off-by: Karol Trzcinski <karolx.trzcinski@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20211216232422.345164-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof/debug.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/sound/sof/debug.h b/include/sound/sof/debug.h index 3ecb5793789d..38693e3fb514 100644 --- a/include/sound/sof/debug.h +++ b/include/sound/sof/debug.h @@ -19,6 +19,8 @@ enum sof_ipc_dbg_mem_zone { SOF_IPC_MEM_ZONE_SYS_RUNTIME = 1, /**< System-runtime zone */ SOF_IPC_MEM_ZONE_RUNTIME = 2, /**< Runtime zone */ SOF_IPC_MEM_ZONE_BUFFER = 3, /**< Buffer zone */ + SOF_IPC_MEM_ZONE_RUNTIME_SHARED = 4, /**< System runtime zone */ + SOF_IPC_MEM_ZONE_SYS_SHARED = 5, /**< System shared zone */ }; /** ABI3.18 */ -- cgit v1.2.3-70-g09d2 From e047d0372689f5d4231eefb731b60ac64720bbf0 Mon Sep 17 00:00:00 2001 From: Ricard Wanderlof <ricardw@axis.com> Date: Wed, 15 Dec 2021 18:01:24 +0100 Subject: ASoC: tlv320adc3xxx: New codec bindings DT bindings for Texas Instruments TLV320ADC3001 and TLV320ADC3101 audio ADCs. Signed-off-by: Ricard Wanderlof <ricardw@axis.com> Link: https://lore.kernel.org/r/alpine.DEB.2.21.2112151759170.27889@lap5cg0092dnk.se.axis.com Signed-off-by: Mark Brown <broonie@kernel.org> --- .../bindings/sound/ti,tlv320adc3xxx.yaml | 137 +++++++++++++++++++++ include/dt-bindings/sound/tlv320adc3xxx.h | 28 +++++ 2 files changed, 165 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ti,tlv320adc3xxx.yaml create mode 100644 include/dt-bindings/sound/tlv320adc3xxx.h (limited to 'include') diff --git a/Documentation/devicetree/bindings/sound/ti,tlv320adc3xxx.yaml b/Documentation/devicetree/bindings/sound/ti,tlv320adc3xxx.yaml new file mode 100644 index 000000000000..83936f594d1a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,tlv320adc3xxx.yaml @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,tlv320adc3xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TLV320ADC3001/TLV320ADC3101 Stereo ADC + +maintainers: + - Ricard Wanderlof <ricardw@axis.com> + +description: | + Texas Instruments TLV320ADC3001 and TLV320ADC3101 Stereo ADC + https://www.ti.com/product/TLV320ADC3001 + https://www.ti.com/product/TLV320ADC3101 + +properties: + compatible: + enum: + - ti,tlv320adc3001 + - ti,tlv320adc3101 + + reg: + maxItems: 1 + description: I2C address + + '#sound-dai-cells': + const: 0 + + '#gpio-cells': + const: 2 + + gpio-controller: true + + reset-gpios: + maxItems: 1 + description: GPIO pin used for codec reset (RESET pin) + + clocks: + maxItems: 1 + description: Master clock (MCLK) + + ti,dmdin-gpio1: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # ADC3XXX_GPIO_DISABLED - I/O buffers powered down and not used + - 1 # ADC3XXX_GPIO_INPUT - Various non-GPIO input functions + - 2 # ADC3XXX_GPIO_GPI - General purpose input + - 3 # ADC3XXX_GPIO_GPO - General purpose output + - 4 # ADC3XXX_GPIO_CLKOUT - Clock source set in CLKOUT_MUX reg + - 5 # ADC3XXX_GPIO_INT1 - INT1 output + - 6 # ADC3XXX_GPIO_SECONDARY_BCLK - Codec interface secondary BCLK + - 7 # ADC3XXX_GPIO_SECONDARY_WCLK - Codec interface secondary WCLK + default: 0 + description: | + Configuration for DMDIN/GPIO1 pin. + + When ADC3XXX_GPIO_GPO is configured, this causes corresponding the + ALSA control "GPIOx Output" to appear, as a switch control. + + ti,dmclk-gpio2: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # ADC3XXX_GPIO_DISABLED - I/O buffers powered down and not used + - 1 # ADC3XXX_GPIO_INPUT - Various non-GPIO input functions + - 2 # ADC3XXX_GPIO_GPI - General purpose input + - 3 # ADC3XXX_GPIO_GPO - General purpose output + - 4 # ADC3XXX_GPIO_CLKOUT - Clock source set in CLKOUT_MUX reg + - 5 # ADC3XXX_GPIO_INT1 - INT1 output + - 6 # ADC3XXX_GPIO_SECONDARY_BCLK - Codec interface secondary BCLK + - 7 # ADC3XXX_GPIO_SECONDARY_WCLK - Codec interface secondary WCLK + default: 0 + description: | + Configuration for DMCLK/GPIO2 pin. + + When ADC3XXX_GPIO_GPO is configured, this causes corresponding the + ALSA control "GPIOx Output" to appear, as a switch control. + + Note that there is currently no support for reading the GPIO pins as + inputs. + + ti,micbias1-vg: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # ADC3XXX_MICBIAS_OFF - Mic bias is powered down + - 1 # ADC3XXX_MICBIAS_2_0V - Mic bias is set to 2.0V + - 2 # ADC3XXX_MICBIAS_2_5V - Mic bias is set to 2.5V + - 3 # ADC3XXX_MICBIAS_AVDD - Mic bias is same as AVDD supply + default: 0 + description: | + Mic bias voltage output on MICBIAS1 pin + + ti,micbias2-vg: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # ADC3XXX_MICBIAS_OFF - Mic bias is powered down + - 1 # ADC3XXX_MICBIAS_2_0V - Mic bias is set to 2.0V + - 2 # ADC3XXX_MICBIAS_2_5V - Mic bias is set to 2.5V + - 3 # ADC3XXX_MICBIAS_AVDD - Mic bias is same as AVDD supply + default: 0 + description: | + Mic bias voltage output on MICBIAS2 pin + +required: + - compatible + - reg + - clocks + +additionalProperties: false + +examples: + - | + + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/sound/tlv320adc3xxx.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + tlv320adc3101: audio-codec@18 { + compatible = "ti,tlv320adc3101"; + reg = <0x18>; + reset-gpios = <&gpio_pc 3 GPIO_ACTIVE_LOW>; + clocks = <&audio_mclk>; + gpio-controller; + #gpio-cells = <2>; + ti,dmdin-gpio1 = <ADC3XXX_GPIO_GPO>; + ti,micbias1-vg = <ADC3XXX_MICBIAS_AVDD>; + }; + }; + + audio_mclk: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; +... diff --git a/include/dt-bindings/sound/tlv320adc3xxx.h b/include/dt-bindings/sound/tlv320adc3xxx.h new file mode 100644 index 000000000000..ec988439da20 --- /dev/null +++ b/include/dt-bindings/sound/tlv320adc3xxx.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Devicetree bindings definitions for tlv320adc3xxx driver. + * + * Copyright (C) 2021 Axis Communications AB + */ +#ifndef __DT_TLV320ADC3XXX_H +#define __DT_TLV320ADC3XXX_H + +#define ADC3XXX_GPIO_DISABLED 0 /* I/O buffers powered down */ +#define ADC3XXX_GPIO_INPUT 1 /* Various non-GPIO inputs */ +#define ADC3XXX_GPIO_GPI 2 /* General purpose input */ +#define ADC3XXX_GPIO_GPO 3 /* General purpose output */ +#define ADC3XXX_GPIO_CLKOUT 4 /* Source set in reg. CLKOUT_MUX */ +#define ADC3XXX_GPIO_INT1 5 /* INT1 output */ +#define ADC3XXX_GPIO_INT2 6 /* INT2 output */ +/* value 7 is reserved */ +#define ADC3XXX_GPIO_SECONDARY_BCLK 8 /* Codec interface secondary BCLK */ +#define ADC3XXX_GPIO_SECONDARY_WCLK 9 /* Codec interface secondary WCLK */ +#define ADC3XXX_GPIO_ADC_MOD_CLK 10 /* Clock output for digital mics */ +/* values 11-15 reserved */ + +#define ADC3XXX_MICBIAS_OFF 0 /* Micbias pin powered off */ +#define ADC3XXX_MICBIAS_2_0V 1 /* Micbias pin set to 2.0V */ +#define ADC3XXX_MICBIAS_2_5V 2 /* Micbias pin set to 2.5V */ +#define ADC3XXX_MICBIAS_AVDD 3 /* Use AVDD voltage for micbias pin */ + +#endif /* __DT_TLV320ADC3XXX_H */ -- cgit v1.2.3-70-g09d2 From fc179420fde3821c4d191e81b4f7b05c1dab87e2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Date: Thu, 23 Dec 2021 13:36:17 +0200 Subject: ASoC: SOF: Move the definition of enum snd_sof_fw_state to global header Move the enum snd_sof_fw_state to include/sound/sof.h to be accessible outside of the core SOF stack. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Paul Olaru <paul.olaru@oss.nxp.com> Link: https://lore.kernel.org/r/20211223113628.18582-10-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof.h | 22 ++++++++++++++++++++++ sound/soc/sof/sof-priv.h | 11 ----------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/sound/sof.h b/include/sound/sof.h index 23b374311d16..b9131c01eefd 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -17,6 +17,28 @@ struct snd_sof_dsp_ops; +/** + * enum snd_sof_fw_state - DSP firmware state definitions + * @SOF_FW_BOOT_NOT_STARTED: firmware boot is not yet started + * @SOF_FW_BOOT_PREPARE: preparing for boot (firmware loading for exaqmple) + * @SOF_FW_BOOT_IN_PROGRESS: firmware boot is in progress + * @SOF_FW_BOOT_FAILED: firmware boot failed + * @SOF_FW_BOOT_READY_FAILED: firmware booted but fw_ready op failed + * @SOF_FW_BOOT_READY_OK: firmware booted and fw_ready op passed + * @SOF_FW_BOOT_COMPLETE: firmware is booted up and functional + * @SOF_FW_CRASHED: firmware crashed after successful boot + */ +enum snd_sof_fw_state { + SOF_FW_BOOT_NOT_STARTED = 0, + SOF_FW_BOOT_PREPARE, + SOF_FW_BOOT_IN_PROGRESS, + SOF_FW_BOOT_FAILED, + SOF_FW_BOOT_READY_FAILED, + SOF_FW_BOOT_READY_OK, + SOF_FW_BOOT_COMPLETE, + SOF_FW_CRASHED, +}; + /* * SOF Platform data. */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index c92103a028ff..a1ebc89b216a 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -375,17 +375,6 @@ struct snd_sof_ipc_msg { bool ipc_complete; }; -enum snd_sof_fw_state { - SOF_FW_BOOT_NOT_STARTED = 0, - SOF_FW_BOOT_PREPARE, - SOF_FW_BOOT_IN_PROGRESS, - SOF_FW_BOOT_FAILED, - SOF_FW_BOOT_READY_FAILED, /* firmware booted but fw_ready op failed */ - SOF_FW_BOOT_READY_OK, - SOF_FW_BOOT_COMPLETE, - SOF_FW_CRASHED, -}; - /* * SOF Device Level. */ -- cgit v1.2.3-70-g09d2 From d41607d37c1385da799f9a2ddb10c460e573687e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Date: Thu, 23 Dec 2021 13:36:18 +0200 Subject: ASoC: SOF: Rename 'enum snd_sof_fw_state' to 'enum sof_fw_state' Since there is nothing SND about the firmware state, rename the enum from `snd_sof_fw_state` to simply `sof_fw_state` Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Paul Olaru <paul.olaru@oss.nxp.com> Link: https://lore.kernel.org/r/20211223113628.18582-11-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/sof.h | 4 ++-- sound/soc/sof/debug.c | 2 +- sound/soc/sof/sof-priv.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/sound/sof.h b/include/sound/sof.h index b9131c01eefd..813680ab9aad 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -18,7 +18,7 @@ struct snd_sof_dsp_ops; /** - * enum snd_sof_fw_state - DSP firmware state definitions + * enum sof_fw_state - DSP firmware state definitions * @SOF_FW_BOOT_NOT_STARTED: firmware boot is not yet started * @SOF_FW_BOOT_PREPARE: preparing for boot (firmware loading for exaqmple) * @SOF_FW_BOOT_IN_PROGRESS: firmware boot is in progress @@ -28,7 +28,7 @@ struct snd_sof_dsp_ops; * @SOF_FW_BOOT_COMPLETE: firmware is booted up and functional * @SOF_FW_CRASHED: firmware crashed after successful boot */ -enum snd_sof_fw_state { +enum sof_fw_state { SOF_FW_BOOT_NOT_STARTED = 0, SOF_FW_BOOT_PREPARE, SOF_FW_BOOT_IN_PROGRESS, diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index 75aaf0da87a0..d3640ff33134 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -930,7 +930,7 @@ void snd_sof_free_debug(struct snd_sof_dev *sdev) EXPORT_SYMBOL_GPL(snd_sof_free_debug); static const struct soc_fw_state_info { - enum snd_sof_fw_state state; + enum sof_fw_state state; const char *name; } fw_state_dbg[] = { {SOF_FW_BOOT_NOT_STARTED, "SOF_FW_BOOT_NOT_STARTED"}, diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index a1ebc89b216a..44ae8d8d1333 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -399,7 +399,7 @@ struct snd_sof_dev { /* DSP firmware boot */ wait_queue_head_t boot_wait; - enum snd_sof_fw_state fw_state; + enum sof_fw_state fw_state; bool first_boot; /* work queue in case the probe is implemented in two steps */ @@ -591,7 +591,7 @@ extern const struct dsp_arch_ops sof_xtensa_arch_ops; * Firmware state tracking */ static inline void sof_set_fw_state(struct snd_sof_dev *sdev, - enum snd_sof_fw_state new_state) + enum sof_fw_state new_state) { if (sdev->fw_state == new_state) return; -- cgit v1.2.3-70-g09d2 From 3d4641a42ccf1593b3f3a474ee7541727acbb8e0 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold <stephan@gerhold.net> Date: Tue, 14 Dec 2021 15:20:46 +0100 Subject: ASoC: core: Add snd_soc_of_parse_pin_switches() from simple-card-utils The ASoC core already has several helpers to parse card properties from the device tree. Move the parsing code for "pin-switches" from simple-card-utils to a shared snd_soc_of_parse_pin_switches() function so other drivers can also use it to set up pin switches configured in the device tree. Cc: Paul Cercueil <paul@crapouillou.net> Signed-off-by: Stephan Gerhold <stephan@gerhold.net> Link: https://lore.kernel.org/r/20211214142049.20422-2-stephan@gerhold.net Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/soc.h | 1 + sound/soc/generic/simple-card-utils.c | 45 +------------------------------ sound/soc/soc-core.c | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index 5872a8864f3b..7a1650b303f1 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1211,6 +1211,7 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, const char *propname); int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, const char *propname); +int snd_soc_of_parse_pin_switches(struct snd_soc_card *card, const char *prop); int snd_soc_of_get_slot_mask(struct device_node *np, const char *prop_name, unsigned int *mask); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 850e968677f1..a81323d1691d 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -499,57 +499,14 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_widgets); int asoc_simple_parse_pin_switches(struct snd_soc_card *card, char *prefix) { - const unsigned int nb_controls_max = 16; - const char **strings, *control_name; - struct snd_kcontrol_new *controls; - struct device *dev = card->dev; - unsigned int i, nb_controls; char prop[128]; - int ret; if (!prefix) prefix = ""; snprintf(prop, sizeof(prop), "%s%s", prefix, "pin-switches"); - if (!of_property_read_bool(dev->of_node, prop)) - return 0; - - strings = devm_kcalloc(dev, nb_controls_max, - sizeof(*strings), GFP_KERNEL); - if (!strings) - return -ENOMEM; - - ret = of_property_read_string_array(dev->of_node, prop, - strings, nb_controls_max); - if (ret < 0) - return ret; - - nb_controls = (unsigned int)ret; - - controls = devm_kcalloc(dev, nb_controls, - sizeof(*controls), GFP_KERNEL); - if (!controls) - return -ENOMEM; - - for (i = 0; i < nb_controls; i++) { - control_name = devm_kasprintf(dev, GFP_KERNEL, - "%s Switch", strings[i]); - if (!control_name) - return -ENOMEM; - - controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; - controls[i].name = control_name; - controls[i].info = snd_soc_dapm_info_pin_switch; - controls[i].get = snd_soc_dapm_get_pin_switch; - controls[i].put = snd_soc_dapm_put_pin_switch; - controls[i].private_value = (unsigned long)strings[i]; - } - - card->controls = controls; - card->num_controls = nb_controls; - - return 0; + return snd_soc_of_parse_pin_switches(card, prop); } EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1d62160f96b1..434e61b46983 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2823,6 +2823,56 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); +int snd_soc_of_parse_pin_switches(struct snd_soc_card *card, const char *prop) +{ + const unsigned int nb_controls_max = 16; + const char **strings, *control_name; + struct snd_kcontrol_new *controls; + struct device *dev = card->dev; + unsigned int i, nb_controls; + int ret; + + if (!of_property_read_bool(dev->of_node, prop)) + return 0; + + strings = devm_kcalloc(dev, nb_controls_max, + sizeof(*strings), GFP_KERNEL); + if (!strings) + return -ENOMEM; + + ret = of_property_read_string_array(dev->of_node, prop, + strings, nb_controls_max); + if (ret < 0) + return ret; + + nb_controls = (unsigned int)ret; + + controls = devm_kcalloc(dev, nb_controls, + sizeof(*controls), GFP_KERNEL); + if (!controls) + return -ENOMEM; + + for (i = 0; i < nb_controls; i++) { + control_name = devm_kasprintf(dev, GFP_KERNEL, + "%s Switch", strings[i]); + if (!control_name) + return -ENOMEM; + + controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + controls[i].name = control_name; + controls[i].info = snd_soc_dapm_info_pin_switch; + controls[i].get = snd_soc_dapm_get_pin_switch; + controls[i].put = snd_soc_dapm_put_pin_switch; + controls[i].private_value = (unsigned long)strings[i]; + } + + card->controls = controls; + card->num_controls = nb_controls; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_of_parse_pin_switches); + int snd_soc_of_get_slot_mask(struct device_node *np, const char *prop_name, unsigned int *mask) -- cgit v1.2.3-70-g09d2 From b86947b52f0d0e5b6e6f0510933ca13aad266e47 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Date: Fri, 24 Dec 2021 10:10:29 +0800 Subject: ASoC/soundwire: intel: simplify callbacks for params/hw_free We don't really need to pass a substream to the callback, we only need the direction. No functionality change, only simplification to enable improve suspend with paused streams. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Acked-By: Vinod Koul <vkoul@kernel.org> Link: https://lore.kernel.org/r/20211224021034.26635-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/soundwire/intel.c | 14 +++++++------- include/linux/soundwire/sdw_intel.h | 4 ++-- sound/soc/sof/intel/hda.c | 6 ++---- 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 78037ffdb09b..25c5f5b9f058 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -711,7 +711,7 @@ intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi) } static int intel_params_stream(struct sdw_intel *sdw, - struct snd_pcm_substream *substream, + int stream, struct snd_soc_dai *dai, struct snd_pcm_hw_params *hw_params, int link_id, int alh_stream_id) @@ -719,7 +719,7 @@ static int intel_params_stream(struct sdw_intel *sdw, struct sdw_intel_link_res *res = sdw->link_res; struct sdw_intel_stream_params_data params_data; - params_data.substream = substream; + params_data.stream = stream; /* direction */ params_data.dai = dai; params_data.hw_params = hw_params; params_data.link_id = link_id; @@ -732,14 +732,14 @@ static int intel_params_stream(struct sdw_intel *sdw, } static int intel_free_stream(struct sdw_intel *sdw, - struct snd_pcm_substream *substream, + int stream, struct snd_soc_dai *dai, int link_id) { struct sdw_intel_link_res *res = sdw->link_res; struct sdw_intel_stream_free_data free_data; - free_data.substream = substream; + free_data.stream = stream; /* direction */ free_data.dai = dai; free_data.link_id = link_id; @@ -876,7 +876,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, dma->hw_params = params; /* Inform DSP about PDI stream number */ - ret = intel_params_stream(sdw, substream, dai, params, + ret = intel_params_stream(sdw, substream->stream, dai, params, sdw->instance, pdi->intel_alh_id); if (ret) @@ -953,7 +953,7 @@ static int intel_prepare(struct snd_pcm_substream *substream, sdw_cdns_config_stream(cdns, ch, dir, dma->pdi); /* Inform DSP about PDI stream number */ - ret = intel_params_stream(sdw, substream, dai, + ret = intel_params_stream(sdw, substream->stream, dai, dma->hw_params, sdw->instance, dma->pdi->intel_alh_id); @@ -987,7 +987,7 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) return ret; } - ret = intel_free_stream(sdw, substream, dai, sdw->instance); + ret = intel_free_stream(sdw, substream->stream, dai, sdw->instance); if (ret < 0) { dev_err(dai->dev, "intel_free_stream: failed %d\n", ret); return ret; diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index 8a463b8fc12a..67e0d3e750b5 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -92,7 +92,7 @@ * firmware. */ struct sdw_intel_stream_params_data { - struct snd_pcm_substream *substream; + int stream; struct snd_soc_dai *dai; struct snd_pcm_hw_params *hw_params; int link_id; @@ -105,7 +105,7 @@ struct sdw_intel_stream_params_data { * firmware. */ struct sdw_intel_stream_free_data { - struct snd_pcm_substream *substream; + int stream; struct snd_soc_dai *dai; int link_id; }; diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 99255028d3fe..c8fb082209ce 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -184,12 +184,11 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev, static int sdw_params_stream(struct device *dev, struct sdw_intel_stream_params_data *params_data) { - struct snd_pcm_substream *substream = params_data->substream; struct snd_sof_dev *sdev = dev_get_drvdata(dev); struct snd_soc_dai *d = params_data->dai; struct snd_soc_dapm_widget *w; - w = snd_soc_dai_get_widget(d, substream->stream); + w = snd_soc_dai_get_widget(d, params_data->stream); return sdw_dai_config_ipc(sdev, w, params_data->link_id, params_data->alh_stream_id, d->id, true); @@ -198,12 +197,11 @@ static int sdw_params_stream(struct device *dev, static int sdw_free_stream(struct device *dev, struct sdw_intel_stream_free_data *free_data) { - struct snd_pcm_substream *substream = free_data->substream; struct snd_sof_dev *sdev = dev_get_drvdata(dev); struct snd_soc_dai *d = free_data->dai; struct snd_soc_dapm_widget *w; - w = snd_soc_dai_get_widget(d, substream->stream); + w = snd_soc_dai_get_widget(d, free_data->stream); /* send invalid stream_id */ return sdw_dai_config_ipc(sdev, w, free_data->link_id, 0xFFFF, d->id, false); -- cgit v1.2.3-70-g09d2 From e8444560b4d9302a511f0996f4cfdf85b628f4ca Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Date: Fri, 24 Dec 2021 10:10:31 +0800 Subject: ASoC/SoundWire: dai: expand 'stream' concept beyond SoundWire The HDAudio ASoC support relies on the set_tdm_slots() helper to store the HDaudio stream tag in the tx_mask. This only works because of the pre-existing order in soc-pcm.c, where the hw_params() is handled for codec_dais *before* cpu_dais. When the order is reversed, the stream_tag is used as a mask in the codec fixup functions: /* fixup params based on TDM slot masks */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && codec_dai->tx_mask) soc_pcm_codec_params_fixup(&codec_params, codec_dai->tx_mask); As a result of this confusion, the codec_params_fixup() ends-up generating bad channel masks, depending on what stream_tag was allocated. We could add a flag to state that the tx_mask is really not a mask, but it would be quite ugly to persist in overloading concepts. Instead, this patch suggests a more generic get/set 'stream' API based on the existing model for SoundWire. We can expand the concept to store 'stream' opaque information that is specific to different DAI types. In the case of HDAudio DAIs, we only need to store a stream tag as an unsigned char pointer. The TDM rx_ and tx_masks should really only be used to store masks. Rename get_sdw_stream/set_sdw_stream callbacks and helpers as get_stream/set_stream. No functionality change beyond the rename. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Acked-By: Vinod Koul <vkoul@kernel.org> Link: https://lore.kernel.org/r/20211224021034.26635-5-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/soundwire/intel.c | 8 ++++---- drivers/soundwire/qcom.c | 8 ++++---- drivers/soundwire/stream.c | 4 ++-- include/sound/soc-dai.h | 32 ++++++++++++++++---------------- sound/soc/codecs/max98373-sdw.c | 2 +- sound/soc/codecs/rt1308-sdw.c | 2 +- sound/soc/codecs/rt1316-sdw.c | 2 +- sound/soc/codecs/rt5682-sdw.c | 2 +- sound/soc/codecs/rt700.c | 2 +- sound/soc/codecs/rt711-sdca.c | 2 +- sound/soc/codecs/rt711.c | 2 +- sound/soc/codecs/rt715-sdca.c | 2 +- sound/soc/codecs/rt715.c | 2 +- sound/soc/codecs/sdw-mockup.c | 2 +- sound/soc/codecs/wcd938x.c | 2 +- sound/soc/codecs/wsa881x.c | 2 +- sound/soc/intel/boards/sof_sdw.c | 6 +++--- sound/soc/qcom/sdm845.c | 4 ++-- sound/soc/qcom/sm8250.c | 4 ++-- 19 files changed, 45 insertions(+), 45 deletions(-) (limited to 'include') diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 3d29f02ad5a6..70d164372a2b 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1129,8 +1129,8 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = { .hw_free = intel_hw_free, .trigger = intel_trigger, .shutdown = intel_shutdown, - .set_sdw_stream = intel_pcm_set_sdw_stream, - .get_sdw_stream = intel_get_sdw_stream, + .set_stream = intel_pcm_set_sdw_stream, + .get_stream = intel_get_sdw_stream, }; static const struct snd_soc_dai_ops intel_pdm_dai_ops = { @@ -1139,8 +1139,8 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = { .prepare = intel_prepare, .hw_free = intel_hw_free, .shutdown = intel_shutdown, - .set_sdw_stream = intel_pdm_set_sdw_stream, - .get_sdw_stream = intel_get_sdw_stream, + .set_stream = intel_pdm_set_sdw_stream, + .get_stream = intel_get_sdw_stream, }; static const struct snd_soc_component_driver dai_component = { diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index a317bea2d42d..9d42891ac3d6 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -1024,8 +1024,8 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream, ctrl->sruntime[dai->id] = sruntime; for_each_rtd_codec_dais(rtd, i, codec_dai) { - ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime, - substream->stream); + ret = snd_soc_dai_set_stream(codec_dai, sruntime, + substream->stream); if (ret < 0 && ret != -ENOTSUPP) { dev_err(dai->dev, "Failed to set sdw stream on %s\n", codec_dai->name); @@ -1051,8 +1051,8 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = { .hw_free = qcom_swrm_hw_free, .startup = qcom_swrm_startup, .shutdown = qcom_swrm_shutdown, - .set_sdw_stream = qcom_swrm_set_sdw_stream, - .get_sdw_stream = qcom_swrm_get_sdw_stream, + .set_stream = qcom_swrm_set_sdw_stream, + .get_stream = qcom_swrm_get_sdw_stream, }; static const struct snd_soc_component_driver qcom_swrm_dai_component = { diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 5d4f6b308ef7..980f26d49b66 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1863,7 +1863,7 @@ static int set_stream(struct snd_pcm_substream *substream, /* Set stream pointer on all DAIs */ for_each_rtd_dais(rtd, i, dai) { - ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream); + ret = snd_soc_dai_set_stream(dai, sdw_stream, substream->stream); if (ret < 0) { dev_err(rtd->dev, "failed to set stream pointer on dai %s\n", dai->name); break; @@ -1934,7 +1934,7 @@ void sdw_shutdown_stream(void *sdw_substream) /* Find stream from first CPU DAI */ dai = asoc_rtd_to_cpu(rtd, 0); - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 5d4dd7c5450b..bbd821d2df9c 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -295,9 +295,9 @@ struct snd_soc_dai_ops { unsigned int *rx_num, unsigned int *rx_slot); int (*set_tristate)(struct snd_soc_dai *dai, int tristate); - int (*set_sdw_stream)(struct snd_soc_dai *dai, - void *stream, int direction); - void *(*get_sdw_stream)(struct snd_soc_dai *dai, int direction); + int (*set_stream)(struct snd_soc_dai *dai, + void *stream, int direction); + void *(*get_stream)(struct snd_soc_dai *dai, int direction); /* * DAI digital mute - optional. @@ -515,42 +515,42 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai) } /** - * snd_soc_dai_set_sdw_stream() - Configures a DAI for SDW stream operation + * snd_soc_dai_set_stream() - Configures a DAI for stream operation * @dai: DAI - * @stream: STREAM + * @stream: STREAM (opaque structure depending on DAI type) * @direction: Stream direction(Playback/Capture) - * SoundWire subsystem doesn't have a notion of direction and we reuse + * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse * the ASoC stream direction to configure sink/source ports. * Playback maps to source ports and Capture for sink ports. * * This should be invoked with NULL to clear the stream set previously. * Returns 0 on success, a negative error code otherwise. */ -static inline int snd_soc_dai_set_sdw_stream(struct snd_soc_dai *dai, - void *stream, int direction) +static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai, + void *stream, int direction) { - if (dai->driver->ops->set_sdw_stream) - return dai->driver->ops->set_sdw_stream(dai, stream, direction); + if (dai->driver->ops->set_stream) + return dai->driver->ops->set_stream(dai, stream, direction); else return -ENOTSUPP; } /** - * snd_soc_dai_get_sdw_stream() - Retrieves SDW stream from DAI + * snd_soc_dai_get_stream() - Retrieves stream from DAI * @dai: DAI * @direction: Stream direction(Playback/Capture) * * This routine only retrieves that was previously configured - * with snd_soc_dai_get_sdw_stream() + * with snd_soc_dai_get_stream() * * Returns pointer to stream or an ERR_PTR value, e.g. * ERR_PTR(-ENOTSUPP) if callback is not supported; */ -static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai, - int direction) +static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai, + int direction) { - if (dai->driver->ops->get_sdw_stream) - return dai->driver->ops->get_sdw_stream(dai, direction); + if (dai->driver->ops->get_stream) + return dai->driver->ops->get_stream(dai, direction); else return ERR_PTR(-ENOTSUPP); } diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index dc520effc61c..f47e956d4f55 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -741,7 +741,7 @@ static int max98373_sdw_set_tdm_slot(struct snd_soc_dai *dai, static const struct snd_soc_dai_ops max98373_dai_sdw_ops = { .hw_params = max98373_sdw_dai_hw_params, .hw_free = max98373_pcm_hw_free, - .set_sdw_stream = max98373_set_sdw_stream, + .set_stream = max98373_set_sdw_stream, .shutdown = max98373_shutdown, .set_tdm_slot = max98373_sdw_set_tdm_slot, }; diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index f716668de640..149a76075c76 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -613,7 +613,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1308 = { static const struct snd_soc_dai_ops rt1308_aif_dai_ops = { .hw_params = rt1308_sdw_hw_params, .hw_free = rt1308_sdw_pcm_hw_free, - .set_sdw_stream = rt1308_set_sdw_stream, + .set_stream = rt1308_set_sdw_stream, .shutdown = rt1308_sdw_shutdown, .set_tdm_slot = rt1308_sdw_set_tdm_slot, }; diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 09b4914bba1b..c66d7b20cb4d 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -602,7 +602,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1316 = { static const struct snd_soc_dai_ops rt1316_aif_dai_ops = { .hw_params = rt1316_sdw_hw_params, .hw_free = rt1316_sdw_pcm_hw_free, - .set_sdw_stream = rt1316_set_sdw_stream, + .set_stream = rt1316_set_sdw_stream, .shutdown = rt1316_sdw_shutdown, }; diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 31a4f286043e..248257a2e4e0 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -272,7 +272,7 @@ static int rt5682_sdw_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rt5682_sdw_ops = { .hw_params = rt5682_sdw_hw_params, .hw_free = rt5682_sdw_hw_free, - .set_sdw_stream = rt5682_set_sdw_stream, + .set_stream = rt5682_set_sdw_stream, .shutdown = rt5682_sdw_shutdown, }; diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 921382724f9c..e61a8257bf64 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -1005,7 +1005,7 @@ static int rt700_pcm_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rt700_ops = { .hw_params = rt700_pcm_hw_params, .hw_free = rt700_pcm_hw_free, - .set_sdw_stream = rt700_set_sdw_stream, + .set_stream = rt700_set_sdw_stream, .shutdown = rt700_shutdown, }; diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 2e992589f1e4..bdb1375f0338 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1358,7 +1358,7 @@ static int rt711_sdca_pcm_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rt711_sdca_ops = { .hw_params = rt711_sdca_pcm_hw_params, .hw_free = rt711_sdca_pcm_hw_free, - .set_sdw_stream = rt711_sdca_set_sdw_stream, + .set_stream = rt711_sdca_set_sdw_stream, .shutdown = rt711_sdca_shutdown, }; diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index a7c5608a0ef8..6770825d037a 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -1089,7 +1089,7 @@ static int rt711_pcm_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rt711_ops = { .hw_params = rt711_pcm_hw_params, .hw_free = rt711_pcm_hw_free, - .set_sdw_stream = rt711_set_sdw_stream, + .set_stream = rt711_set_sdw_stream, .shutdown = rt711_shutdown, }; diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 66e166568c50..bfa536bd7196 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -938,7 +938,7 @@ static int rt715_sdca_pcm_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rt715_sdca_ops = { .hw_params = rt715_sdca_pcm_hw_params, .hw_free = rt715_sdca_pcm_hw_free, - .set_sdw_stream = rt715_sdca_set_sdw_stream, + .set_stream = rt715_sdca_set_sdw_stream, .shutdown = rt715_sdca_shutdown, }; diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 1352869cc086..a64d11a74751 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -909,7 +909,7 @@ static int rt715_pcm_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rt715_ops = { .hw_params = rt715_pcm_hw_params, .hw_free = rt715_pcm_hw_free, - .set_sdw_stream = rt715_set_sdw_stream, + .set_stream = rt715_set_sdw_stream, .shutdown = rt715_shutdown, }; diff --git a/sound/soc/codecs/sdw-mockup.c b/sound/soc/codecs/sdw-mockup.c index 8ea13cfa9f8e..7c612aaf31c7 100644 --- a/sound/soc/codecs/sdw-mockup.c +++ b/sound/soc/codecs/sdw-mockup.c @@ -138,7 +138,7 @@ static int sdw_mockup_pcm_hw_free(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops sdw_mockup_ops = { .hw_params = sdw_mockup_pcm_hw_params, .hw_free = sdw_mockup_pcm_hw_free, - .set_sdw_stream = sdw_mockup_set_sdw_stream, + .set_stream = sdw_mockup_set_sdw_stream, .shutdown = sdw_mockup_shutdown, }; diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 67151c7770c6..0b5266c56a3f 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -4287,7 +4287,7 @@ static int wcd938x_codec_set_sdw_stream(struct snd_soc_dai *dai, static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = { .hw_params = wcd938x_codec_hw_params, .hw_free = wcd938x_codec_free, - .set_sdw_stream = wcd938x_codec_set_sdw_stream, + .set_stream = wcd938x_codec_set_sdw_stream, }; static struct snd_soc_dai_driver wcd938x_dais[] = { diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 2da4a5fa7a18..ffc025e01bce 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1018,7 +1018,7 @@ static const struct snd_soc_dai_ops wsa881x_dai_ops = { .hw_params = wsa881x_hw_params, .hw_free = wsa881x_hw_free, .mute_stream = wsa881x_digital_mute, - .set_sdw_stream = wsa881x_set_sdw_stream, + .set_stream = wsa881x_set_sdw_stream, }; static struct snd_soc_dai_driver wsa881x_dais[] = { diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index de303a980879..da515eb1ddbe 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -347,7 +347,7 @@ int sdw_prepare(struct snd_pcm_substream *substream) /* Find stream from first CPU DAI */ dai = asoc_rtd_to_cpu(rtd, 0); - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s", dai->name); @@ -367,7 +367,7 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd) /* Find stream from first CPU DAI */ dai = asoc_rtd_to_cpu(rtd, 0); - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s", dai->name); @@ -406,7 +406,7 @@ int sdw_hw_free(struct snd_pcm_substream *substream) /* Find stream from first CPU DAI */ dai = asoc_rtd_to_cpu(rtd, 0); - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s", dai->name); diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c index 10d724bd1d67..5c1d13eccbee 100644 --- a/sound/soc/qcom/sdm845.c +++ b/sound/soc/qcom/sdm845.c @@ -57,8 +57,8 @@ static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream, int ret = 0, i; for_each_rtd_codec_dais(rtd, i, codec_dai) { - sruntime = snd_soc_dai_get_sdw_stream(codec_dai, - substream->stream); + sruntime = snd_soc_dai_get_stream(codec_dai, + substream->stream); if (sruntime != ERR_PTR(-ENOTSUPP)) pdata->sruntime[cpu_dai->id] = sruntime; diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index b2ca2579810b..114a29e01c0f 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -136,8 +136,8 @@ static int sm8250_snd_hw_params(struct snd_pcm_substream *substream, case TX_CODEC_DMA_TX_2: case TX_CODEC_DMA_TX_3: for_each_rtd_codec_dais(rtd, i, codec_dai) { - sruntime = snd_soc_dai_get_sdw_stream(codec_dai, - substream->stream); + sruntime = snd_soc_dai_get_stream(codec_dai, + substream->stream); if (sruntime != ERR_PTR(-ENOTSUPP)) pdata->sruntime[cpu_dai->id] = sruntime; } -- cgit v1.2.3-70-g09d2 From a87d42227cf5614fe0040ddd1fe642c54298b42c Mon Sep 17 00:00:00 2001 From: Lucas Tanure <tanureal@opensource.cirrus.com> Date: Fri, 17 Dec 2021 11:56:59 +0000 Subject: ASoC: cs35l41: Convert tables to shared source code To support CS35L41 in HDA systems the HDA driver for CS35L41 would have to duplicate some functions that already exist on ASoC driver So instead of duplicate the code, use the new lib source as a shared resource for both ASoC and HDA Also, change the way CONFIG_SND_SOC_CS35L41 is selected, as reported by Intel Kernel test robot, it is possible to build SND_SOC_CS35L41_SPI/I2C without the main driver, which would lead to build failures. Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Reported-by: kernel test robot <lkp@intel.com> Link: https://lore.kernel.org/r/20211217115708.882525-2-tanureal@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/cs35l41.h | 733 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/Kconfig | 11 +- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/cs35l41-i2c.c | 1 - sound/soc/codecs/cs35l41-lib.c | 733 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41-spi.c | 1 - sound/soc/codecs/cs35l41-tables.c | 723 ------------------------------------- sound/soc/codecs/cs35l41.h | 734 -------------------------------------- 8 files changed, 1476 insertions(+), 1464 deletions(-) create mode 100644 sound/soc/codecs/cs35l41-lib.c delete mode 100644 sound/soc/codecs/cs35l41-tables.c (limited to 'include') diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 1f1e3c6c9be1..aac3ffb9bc89 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -10,6 +10,721 @@ #ifndef __CS35L41_H #define __CS35L41_H +#include <linux/regmap.h> + +#define CS35L41_FIRSTREG 0x00000000 +#define CS35L41_LASTREG 0x03804FE8 +#define CS35L41_DEVID 0x00000000 +#define CS35L41_REVID 0x00000004 +#define CS35L41_FABID 0x00000008 +#define CS35L41_RELID 0x0000000C +#define CS35L41_OTPID 0x00000010 +#define CS35L41_SFT_RESET 0x00000020 +#define CS35L41_TEST_KEY_CTL 0x00000040 +#define CS35L41_USER_KEY_CTL 0x00000044 +#define CS35L41_OTP_MEM0 0x00000400 +#define CS35L41_OTP_MEM31 0x0000047C +#define CS35L41_OTP_CTRL0 0x00000500 +#define CS35L41_OTP_CTRL1 0x00000504 +#define CS35L41_OTP_CTRL3 0x00000508 +#define CS35L41_OTP_CTRL4 0x0000050C +#define CS35L41_OTP_CTRL5 0x00000510 +#define CS35L41_OTP_CTRL6 0x00000514 +#define CS35L41_OTP_CTRL7 0x00000518 +#define CS35L41_OTP_CTRL8 0x0000051C +#define CS35L41_PWR_CTRL1 0x00002014 +#define CS35L41_PWR_CTRL2 0x00002018 +#define CS35L41_PWR_CTRL3 0x0000201C +#define CS35L41_CTRL_OVRRIDE 0x00002020 +#define CS35L41_AMP_OUT_MUTE 0x00002024 +#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 +#define CS35L41_GPIO_PAD_CONTROL 0x0000242C +#define CS35L41_JTAG_CONTROL 0x00002438 +#define CS35L41_PLL_CLK_CTRL 0x00002C04 +#define CS35L41_DSP_CLK_CTRL 0x00002C08 +#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C +#define CS35L41_DATA_FS_SEL 0x00002C10 +#define CS35L41_TST_FS_MON0 0x00002D10 +#define CS35L41_MDSYNC_EN 0x00003400 +#define CS35L41_MDSYNC_TX_ID 0x00003408 +#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C +#define CS35L41_MDSYNC_DATA_TX 0x00003410 +#define CS35L41_MDSYNC_TX_STATUS 0x00003414 +#define CS35L41_MDSYNC_DATA_RX 0x0000341C +#define CS35L41_MDSYNC_RX_STATUS 0x00003420 +#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 +#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 +#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C +#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C +#define CS35L41_BSTCVRT_VCTRL1 0x00003800 +#define CS35L41_BSTCVRT_VCTRL2 0x00003804 +#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 +#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C +#define CS35L41_BSTCVRT_COEFF 0x00003810 +#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 +#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 +#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C +#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 +#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 +#define CS35L41_VI_VOL_POL 0x00004000 +#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 +#define CS35L41_DTEMP_WARN_THLD 0x00004220 +#define CS35L41_DTEMP_CFG 0x00004224 +#define CS35L41_DTEMP_EN 0x00004308 +#define CS35L41_VPVBST_FS_SEL 0x00004400 +#define CS35L41_SP_ENABLES 0x00004800 +#define CS35L41_SP_RATE_CTRL 0x00004804 +#define CS35L41_SP_FORMAT 0x00004808 +#define CS35L41_SP_HIZ_CTRL 0x0000480C +#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 +#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 +#define CS35L41_SP_TX_WL 0x00004830 +#define CS35L41_SP_RX_WL 0x00004840 +#define CS35L41_ASP_CONTROL4 0x00004854 +#define CS35L41_DAC_PCM1_SRC 0x00004C00 +#define CS35L41_ASP_TX1_SRC 0x00004C20 +#define CS35L41_ASP_TX2_SRC 0x00004C24 +#define CS35L41_ASP_TX3_SRC 0x00004C28 +#define CS35L41_ASP_TX4_SRC 0x00004C2C +#define CS35L41_DSP1_RX1_SRC 0x00004C40 +#define CS35L41_DSP1_RX2_SRC 0x00004C44 +#define CS35L41_DSP1_RX3_SRC 0x00004C48 +#define CS35L41_DSP1_RX4_SRC 0x00004C4C +#define CS35L41_DSP1_RX5_SRC 0x00004C50 +#define CS35L41_DSP1_RX6_SRC 0x00004C54 +#define CS35L41_DSP1_RX7_SRC 0x00004C58 +#define CS35L41_DSP1_RX8_SRC 0x00004C5C +#define CS35L41_NGATE1_SRC 0x00004C60 +#define CS35L41_NGATE2_SRC 0x00004C64 +#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 +#define CS35L41_VPBR_CFG 0x00006404 +#define CS35L41_VBBR_CFG 0x00006408 +#define CS35L41_VPBR_STATUS 0x0000640C +#define CS35L41_VBBR_STATUS 0x00006410 +#define CS35L41_OVERTEMP_CFG 0x00006414 +#define CS35L41_AMP_ERR_VOL 0x00006418 +#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 +#define CS35L41_CLASSH_CFG 0x00006800 +#define CS35L41_WKFET_CFG 0x00006804 +#define CS35L41_NG_CFG 0x00006808 +#define CS35L41_AMP_GAIN_CTRL 0x00006C04 +#define CS35L41_DAC_MSM_CFG 0x00007400 +#define CS35L41_IRQ1_CFG 0x00010000 +#define CS35L41_IRQ1_STATUS 0x00010004 +#define CS35L41_IRQ1_STATUS1 0x00010010 +#define CS35L41_IRQ1_STATUS2 0x00010014 +#define CS35L41_IRQ1_STATUS3 0x00010018 +#define CS35L41_IRQ1_STATUS4 0x0001001C +#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 +#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 +#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 +#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C +#define CS35L41_IRQ1_MASK1 0x00010110 +#define CS35L41_IRQ1_MASK2 0x00010114 +#define CS35L41_IRQ1_MASK3 0x00010118 +#define CS35L41_IRQ1_MASK4 0x0001011C +#define CS35L41_IRQ1_FRC1 0x00010190 +#define CS35L41_IRQ1_FRC2 0x00010194 +#define CS35L41_IRQ1_FRC3 0x00010198 +#define CS35L41_IRQ1_FRC4 0x0001019C +#define CS35L41_IRQ1_EDGE1 0x00010210 +#define CS35L41_IRQ1_EDGE4 0x0001021C +#define CS35L41_IRQ1_POL1 0x00010290 +#define CS35L41_IRQ1_POL2 0x00010294 +#define CS35L41_IRQ1_POL3 0x00010298 +#define CS35L41_IRQ1_POL4 0x0001029C +#define CS35L41_IRQ1_DB3 0x00010318 +#define CS35L41_IRQ2_CFG 0x00010800 +#define CS35L41_IRQ2_STATUS 0x00010804 +#define CS35L41_IRQ2_STATUS1 0x00010810 +#define CS35L41_IRQ2_STATUS2 0x00010814 +#define CS35L41_IRQ2_STATUS3 0x00010818 +#define CS35L41_IRQ2_STATUS4 0x0001081C +#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 +#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 +#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 +#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C +#define CS35L41_IRQ2_MASK1 0x00010910 +#define CS35L41_IRQ2_MASK2 0x00010914 +#define CS35L41_IRQ2_MASK3 0x00010918 +#define CS35L41_IRQ2_MASK4 0x0001091C +#define CS35L41_IRQ2_FRC1 0x00010990 +#define CS35L41_IRQ2_FRC2 0x00010994 +#define CS35L41_IRQ2_FRC3 0x00010998 +#define CS35L41_IRQ2_FRC4 0x0001099C +#define CS35L41_IRQ2_EDGE1 0x00010A10 +#define CS35L41_IRQ2_EDGE4 0x00010A1C +#define CS35L41_IRQ2_POL1 0x00010A90 +#define CS35L41_IRQ2_POL2 0x00010A94 +#define CS35L41_IRQ2_POL3 0x00010A98 +#define CS35L41_IRQ2_POL4 0x00010A9C +#define CS35L41_IRQ2_DB3 0x00010B18 +#define CS35L41_GPIO_STATUS1 0x00011000 +#define CS35L41_GPIO1_CTRL1 0x00011008 +#define CS35L41_GPIO2_CTRL1 0x0001100C +#define CS35L41_MIXER_NGATE_CFG 0x00012000 +#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 +#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 +#define CS35L41_DSP_MBOX_1 0x00013000 +#define CS35L41_DSP_MBOX_2 0x00013004 +#define CS35L41_DSP_MBOX_3 0x00013008 +#define CS35L41_DSP_MBOX_4 0x0001300C +#define CS35L41_DSP_MBOX_5 0x00013010 +#define CS35L41_DSP_MBOX_6 0x00013014 +#define CS35L41_DSP_MBOX_7 0x00013018 +#define CS35L41_DSP_MBOX_8 0x0001301C +#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 +#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 +#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 +#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C +#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 +#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 +#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 +#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C +#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 +#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 +#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 +#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C +#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 +#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 +#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 +#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C +#define CS35L41_CLOCK_DETECT_1 0x00014000 +#define CS35L41_TIMER1_CONTROL 0x00015000 +#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 +#define CS35L41_TIMER1_START_STOP 0x0001500C +#define CS35L41_TIMER1_STATUS 0x00015010 +#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 +#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 +#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C +#define CS35L41_TIMER2_CONTROL 0x00015100 +#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 +#define CS35L41_TIMER2_START_STOP 0x0001510C +#define CS35L41_TIMER2_STATUS 0x00015110 +#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 +#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 +#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C +#define CS35L41_DFT_JTAG_CONTROL 0x00016000 +#define CS35L41_DIE_STS1 0x00017040 +#define CS35L41_DIE_STS2 0x00017044 +#define CS35L41_TEMP_CAL1 0x00017048 +#define CS35L41_TEMP_CAL2 0x0001704C +#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 +#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 +#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 +#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 +#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 +#define CS35L41_DSP1_SYS_ID 0x025E0000 +#define CS35L41_DSP1_SYS_VERSION 0x025E0004 +#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 +#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C +#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 +#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 +#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 +#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 +#define CS35L41_DSP1_SYS_FEATURES 0x025E002C +#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 +#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 +#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 +#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C +#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 +#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 +#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 +#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 +#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C +#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 +#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 +#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 +#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C +#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 +#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 +#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 +#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C +#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 +#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 +#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 +#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C +#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 +#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 +#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 +#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 +#define CS35L41_DSP1_CTRL_BASE 0x02B80000 +#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 +#define CS35L41_DSP1_DEBUG 0x02B80040 +#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 +#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 +#define CS35L41_DSP1_RX1_RATE 0x02B80080 +#define CS35L41_DSP1_RX2_RATE 0x02B80088 +#define CS35L41_DSP1_RX3_RATE 0x02B80090 +#define CS35L41_DSP1_RX4_RATE 0x02B80098 +#define CS35L41_DSP1_RX5_RATE 0x02B800A0 +#define CS35L41_DSP1_RX6_RATE 0x02B800A8 +#define CS35L41_DSP1_RX7_RATE 0x02B800B0 +#define CS35L41_DSP1_RX8_RATE 0x02B800B8 +#define CS35L41_DSP1_TX1_RATE 0x02B80280 +#define CS35L41_DSP1_TX2_RATE 0x02B80288 +#define CS35L41_DSP1_TX3_RATE 0x02B80290 +#define CS35L41_DSP1_TX4_RATE 0x02B80298 +#define CS35L41_DSP1_TX5_RATE 0x02B802A0 +#define CS35L41_DSP1_TX6_RATE 0x02B802A8 +#define CS35L41_DSP1_TX7_RATE 0x02B802B0 +#define CS35L41_DSP1_TX8_RATE 0x02B802B8 +#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 +#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 +#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 +#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 +#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 +#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 +#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 +#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 +#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 +#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 +#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 +#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 +#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 +#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 +#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 +#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 +#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 +#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 +#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 +#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 +#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 +#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 +#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 +#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 +#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 +#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 +#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 +#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 +#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 +#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 +#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 +#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 +#define CS35L41_DSP1_SCRATCH1 0x02B805C0 +#define CS35L41_DSP1_SCRATCH2 0x02B805C8 +#define CS35L41_DSP1_SCRATCH3 0x02B805D0 +#define CS35L41_DSP1_SCRATCH4 0x02B805D8 +#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 +#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 +#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 +#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 +#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 +#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 +#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 +#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 +#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 +#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 +#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 +#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 +#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 +#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 +#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 +#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 +#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C +#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 +#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 +#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 +#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C +#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 +#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 +#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 +#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC +#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 +#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 +#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 +#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC +#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 +#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 +#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 +#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC +#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 +#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 +#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 +#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC +#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 +#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 +#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 +#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC +#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 +#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 +#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 +#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC +#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 +#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 +#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 +#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 +#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 +#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C +#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 +#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 +#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C +#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 +#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 +#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C +#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 +#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 +#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 +#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C +#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 +#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 +#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C +#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 +#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 +#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C +#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 +#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 +#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 +#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C +#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 +#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 +#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 +#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 +#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 +#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 +#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 +#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C +#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 +#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 +#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 +#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C +#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 +#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 +#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 +#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C +#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 +#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 +#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 +#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C +#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 +#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 +#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 +#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C +#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 +#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 +#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 +#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C +#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 +#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 +#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 +#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C +#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 +#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 +#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 +#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C +#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 +#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 +#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 +#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 +#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 +#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 +#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 +#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 +#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 +#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 +#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 +#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C +#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 +#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 +#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 +#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C +#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 +#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 +#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 +#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 +#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 +#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 +#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 +#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 +#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 +#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 +#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 +#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 +#define CS35L41_DSP1_PMEM_0 0x03800000 +#define CS35L41_DSP1_PMEM_5114 0x03804FE8 + +/*test regs for emulation bringup*/ +#define CS35L41_PLL_OVR 0x00003018 +#define CS35L41_BST_TEST_DUTY 0x00003900 +#define CS35L41_DIGPWM_IOCTRL 0x0000706C + +/*registers populated by OTP*/ +#define CS35L41_OTP_TRIM_1 0x0000208c +#define CS35L41_OTP_TRIM_2 0x00002090 +#define CS35L41_OTP_TRIM_3 0x00003010 +#define CS35L41_OTP_TRIM_4 0x0000300C +#define CS35L41_OTP_TRIM_5 0x0000394C +#define CS35L41_OTP_TRIM_6 0x00003950 +#define CS35L41_OTP_TRIM_7 0x00003954 +#define CS35L41_OTP_TRIM_8 0x00003958 +#define CS35L41_OTP_TRIM_9 0x0000395C +#define CS35L41_OTP_TRIM_10 0x0000416C +#define CS35L41_OTP_TRIM_11 0x00004160 +#define CS35L41_OTP_TRIM_12 0x00004170 +#define CS35L41_OTP_TRIM_13 0x00004360 +#define CS35L41_OTP_TRIM_14 0x00004448 +#define CS35L41_OTP_TRIM_15 0x0000444C +#define CS35L41_OTP_TRIM_16 0x00006E30 +#define CS35L41_OTP_TRIM_17 0x00006E34 +#define CS35L41_OTP_TRIM_18 0x00006E38 +#define CS35L41_OTP_TRIM_19 0x00006E3C +#define CS35L41_OTP_TRIM_20 0x00006E40 +#define CS35L41_OTP_TRIM_21 0x00006E44 +#define CS35L41_OTP_TRIM_22 0x00006E48 +#define CS35L41_OTP_TRIM_23 0x00006E4C +#define CS35L41_OTP_TRIM_24 0x00006E50 +#define CS35L41_OTP_TRIM_25 0x00006E54 +#define CS35L41_OTP_TRIM_26 0x00006E58 +#define CS35L41_OTP_TRIM_27 0x00006E5C +#define CS35L41_OTP_TRIM_28 0x00006E60 +#define CS35L41_OTP_TRIM_29 0x00006E64 +#define CS35L41_OTP_TRIM_30 0x00007418 +#define CS35L41_OTP_TRIM_31 0x0000741C +#define CS35L41_OTP_TRIM_32 0x00007434 +#define CS35L41_OTP_TRIM_33 0x00007068 +#define CS35L41_OTP_TRIM_34 0x0000410C +#define CS35L41_OTP_TRIM_35 0x0000400C +#define CS35L41_OTP_TRIM_36 0x00002030 + +#define CS35L41_MAX_CACHE_REG 36 +#define CS35L41_OTP_SIZE_WORDS 32 +#define CS35L41_NUM_OTP_ELEM 100 +#define CS35L41_NUM_OTP_MAPS 5 + +#define CS35L41_VALID_PDATA 0x80000000 +#define CS35L41_NUM_SUPPLIES 2 + +#define CS35L41_SCLK_MSTR_MASK 0x10 +#define CS35L41_SCLK_MSTR_SHIFT 4 +#define CS35L41_LRCLK_MSTR_MASK 0x01 +#define CS35L41_LRCLK_MSTR_SHIFT 0 +#define CS35L41_SCLK_INV_MASK 0x40 +#define CS35L41_SCLK_INV_SHIFT 6 +#define CS35L41_LRCLK_INV_MASK 0x04 +#define CS35L41_LRCLK_INV_SHIFT 2 +#define CS35L41_SCLK_FRC_MASK 0x20 +#define CS35L41_SCLK_FRC_SHIFT 5 +#define CS35L41_LRCLK_FRC_MASK 0x02 +#define CS35L41_LRCLK_FRC_SHIFT 1 + +#define CS35L41_AMP_GAIN_PCM_MASK 0x3E0 +#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 +#define CS35L41_AMP_GAIN_ZC_SHIFT 10 + +#define CS35L41_BST_CTL_MASK 0xFF +#define CS35L41_BST_CTL_SEL_MASK 0x03 +#define CS35L41_BST_CTL_SEL_REG 0x00 +#define CS35L41_BST_CTL_SEL_CLASSH 0x01 +#define CS35L41_BST_IPK_MASK 0x7F +#define CS35L41_BST_IPK_SHIFT 0 +#define CS35L41_BST_LIM_MASK 0x4 +#define CS35L41_BST_LIM_SHIFT 2 +#define CS35L41_BST_K1_MASK 0x000000FF +#define CS35L41_BST_K1_SHIFT 0 +#define CS35L41_BST_K2_MASK 0x0000FF00 +#define CS35L41_BST_K2_SHIFT 8 +#define CS35L41_BST_SLOPE_MASK 0x0000FF00 +#define CS35L41_BST_SLOPE_SHIFT 8 +#define CS35L41_BST_LBST_VAL_MASK 0x00000003 +#define CS35L41_BST_LBST_VAL_SHIFT 0 + +#define CS35L41_TEMP_THLD_MASK 0x03 +#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF +#define CS35L41_PDM_MODE_MASK 0x01 +#define CS35L41_PDM_MODE_SHIFT 0 + +#define CS35L41_CH_MEM_DEPTH_MASK 0x07 +#define CS35L41_CH_MEM_DEPTH_SHIFT 0 +#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 +#define CS35L41_CH_HDRM_CTL_SHIFT 16 +#define CS35L41_CH_REL_RATE_MASK 0xFF00 +#define CS35L41_CH_REL_RATE_SHIFT 8 +#define CS35L41_CH_WKFET_DLY_MASK 0x001C +#define CS35L41_CH_WKFET_DLY_SHIFT 2 +#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 +#define CS35L41_CH_WKFET_THLD_SHIFT 8 + +#define CS35L41_HW_NG_SEL_MASK 0x3F00 +#define CS35L41_HW_NG_SEL_SHIFT 8 +#define CS35L41_HW_NG_DLY_MASK 0x0070 +#define CS35L41_HW_NG_DLY_SHIFT 4 +#define CS35L41_HW_NG_THLD_MASK 0x0007 +#define CS35L41_HW_NG_THLD_SHIFT 0 + +#define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 +#define CS35L41_DSP_NG_ENABLE_SHIFT 16 +#define CS35L41_DSP_NG_THLD_MASK 0x7 +#define CS35L41_DSP_NG_THLD_SHIFT 0 +#define CS35L41_DSP_NG_DELAY_MASK 0x0F00 +#define CS35L41_DSP_NG_DELAY_SHIFT 8 + +#define CS35L41_ASP_FMT_MASK 0x0700 +#define CS35L41_ASP_FMT_SHIFT 8 +#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 +#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 +#define CS35L41_ASP_WIDTH_16 0x10 +#define CS35L41_ASP_WIDTH_24 0x18 +#define CS35L41_ASP_WIDTH_32 0x20 +#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 +#define CS35L41_ASP_WIDTH_TX_SHIFT 16 +#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 +#define CS35L41_ASP_WIDTH_RX_SHIFT 24 +#define CS35L41_ASP_RX1_SLOT_MASK 0x3F +#define CS35L41_ASP_RX1_SLOT_SHIFT 0 +#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 +#define CS35L41_ASP_RX2_SLOT_SHIFT 8 +#define CS35L41_ASP_RX_WL_MASK 0x3F +#define CS35L41_ASP_TX_WL_MASK 0x3F +#define CS35L41_ASP_RX_WL_SHIFT 0 +#define CS35L41_ASP_TX_WL_SHIFT 0 +#define CS35L41_ASP_SOURCE_MASK 0x7F + +#define CS35L41_INPUT_SRC_ASPRX1 0x08 +#define CS35L41_INPUT_SRC_ASPRX2 0x09 +#define CS35L41_INPUT_SRC_VMON 0x18 +#define CS35L41_INPUT_SRC_IMON 0x19 +#define CS35L41_INPUT_SRC_CLASSH 0x21 +#define CS35L41_INPUT_SRC_VPMON 0x28 +#define CS35L41_INPUT_SRC_VBSTMON 0x29 +#define CS35L41_INPUT_SRC_TEMPMON 0x3A +#define CS35L41_INPUT_SRC_RSVD 0x3B +#define CS35L41_INPUT_DSP_TX1 0x32 +#define CS35L41_INPUT_DSP_TX2 0x33 + +#define CS35L41_PLL_CLK_SEL_MASK 0x07 +#define CS35L41_PLL_CLK_SEL_SHIFT 0 +#define CS35L41_PLL_CLK_EN_MASK 0x10 +#define CS35L41_PLL_CLK_EN_SHIFT 4 +#define CS35L41_PLL_OPENLOOP_MASK 0x0800 +#define CS35L41_PLL_OPENLOOP_SHIFT 11 +#define CS35L41_PLLSRC_SCLK 0 +#define CS35L41_PLLSRC_LRCLK 1 +#define CS35L41_PLLSRC_SELF 3 +#define CS35L41_PLLSRC_PDMCLK 4 +#define CS35L41_PLLSRC_MCLK 5 +#define CS35L41_PLLSRC_SWIRE 7 +#define CS35L41_REFCLK_FREQ_MASK 0x7E0 +#define CS35L41_REFCLK_FREQ_SHIFT 5 + +#define CS35L41_GLOBAL_FS_MASK 0x1F +#define CS35L41_GLOBAL_FS_SHIFT 0 + +#define CS35L41_GLOBAL_EN_MASK 0x01 +#define CS35L41_GLOBAL_EN_SHIFT 0 +#define CS35L41_BST_EN_MASK 0x0030 +#define CS35L41_BST_EN_SHIFT 4 +#define CS35L41_BST_EN_DEFAULT 0x2 +#define CS35L41_AMP_EN_SHIFT 0 +#define CS35L41_AMP_EN_MASK 1 + +#define CS35L41_PDN_DONE_MASK 0x00800000 +#define CS35L41_PDN_DONE_SHIFT 23 +#define CS35L41_PUP_DONE_MASK 0x01000000 +#define CS35L41_PUP_DONE_SHIFT 24 + +#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F +#define CS35L36_PUP_DONE_IRQ_MASK 0xBF + +#define CS35L41_AMP_SHORT_ERR 0x80000000 +#define CS35L41_BST_SHORT_ERR 0x0100 +#define CS35L41_TEMP_WARN 0x8000 +#define CS35L41_TEMP_ERR 0x00020000 +#define CS35L41_BST_OVP_ERR 0x40 +#define CS35L41_BST_DCM_UVP_ERR 0x80 +#define CS35L41_OTP_BOOT_DONE 0x02 +#define CS35L41_PLL_UNLOCK 0x10 +#define CS35L41_OTP_BOOT_ERR 0x80000000 + +#define CS35L41_AMP_SHORT_ERR_RLS 0x02 +#define CS35L41_BST_SHORT_ERR_RLS 0x04 +#define CS35L41_BST_OVP_ERR_RLS 0x08 +#define CS35L41_BST_UVP_ERR_RLS 0x10 +#define CS35L41_TEMP_WARN_ERR_RLS 0x20 +#define CS35L41_TEMP_ERR_RLS 0x40 + +#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F +#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF +#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF + +#define CS35L41_GPIO_DIR_MASK 0x80000000 +#define CS35L41_GPIO_DIR_SHIFT 31 +#define CS35L41_GPIO1_CTRL_MASK 0x00030000 +#define CS35L41_GPIO1_CTRL_SHIFT 16 +#define CS35L41_GPIO2_CTRL_MASK 0x07000000 +#define CS35L41_GPIO2_CTRL_SHIFT 24 +#define CS35L41_GPIO_CTRL_OPEN_INT 2 +#define CS35L41_GPIO_CTRL_ACTV_LO 4 +#define CS35L41_GPIO_CTRL_ACTV_HI 5 +#define CS35L41_GPIO_POL_MASK 0x1000 +#define CS35L41_GPIO_POL_SHIFT 12 + +#define CS35L41_AMP_INV_PCM_SHIFT 14 +#define CS35L41_AMP_INV_PCM_MASK BIT(CS35L41_AMP_INV_PCM_SHIFT) +#define CS35L41_AMP_PCM_VOL_SHIFT 3 +#define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) +#define CS35L41_AMP_PCM_VOL_MUTE 0x4CF + +#define CS35L41_CHIP_ID 0x35a40 +#define CS35L41R_CHIP_ID 0x35b40 +#define CS35L41_MTLREVID_MASK 0x0F +#define CS35L41_REVID_A0 0xA0 +#define CS35L41_REVID_B0 0xB0 +#define CS35L41_REVID_B2 0xB2 + +#define CS35L41_HALO_CORE_RESET 0x00000200 + +#define CS35L41_FS1_WINDOW_MASK 0x000007FF +#define CS35L41_FS2_WINDOW_MASK 0x00FFF800 +#define CS35L41_FS2_WINDOW_SHIFT 12 + +#define CS35L41_SPI_MAX_FREQ 4000000 +#define CS35L41_REGSTRIDE 4 + enum cs35l41_clk_ids { CS35L41_CLKID_SCLK = 0, CS35L41_CLKID_LRCLK = 1, @@ -31,4 +746,22 @@ struct cs35l41_platform_data { struct cs35l41_irq_cfg irq_config2; }; +struct cs35l41_otp_packed_element_t { + u32 reg; + u8 shift; + u8 size; +}; + +struct cs35l41_otp_map_element_t { + u32 id; + u32 num_elements; + const struct cs35l41_otp_packed_element_t *map; + u32 bit_offset; + u32 word_offset; +}; + +extern const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; +extern struct regmap_config cs35l41_regmap_i2c; +extern struct regmap_config cs35l41_regmap_spi; + #endif /* __CS35L41_H */ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 5fe9ec924864..d3e5ae8310ef 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -624,21 +624,24 @@ config SND_SOC_CS35L36 tristate "Cirrus Logic CS35L36 CODEC" depends on I2C +config SND_SOC_CS35L41_LIB + tristate + config SND_SOC_CS35L41 tristate - default y if SND_SOC_CS35L41_SPI=y - default y if SND_SOC_CS35L41_I2C=y - default m if SND_SOC_CS35L41_SPI=m - default m if SND_SOC_CS35L41_I2C=m config SND_SOC_CS35L41_SPI tristate "Cirrus Logic CS35L41 CODEC (SPI)" depends on SPI_MASTER + select SND_SOC_CS35L41_LIB + select SND_SOC_CS35L41 select REGMAP_SPI config SND_SOC_CS35L41_I2C tristate "Cirrus Logic CS35L41 CODEC (I2C)" depends on I2C + select SND_SOC_CS35L41_LIB + select SND_SOC_CS35L41 select REGMAP_I2C config SND_SOC_CS42L42 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 8dbdf3518bda..ac7f20972470 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -55,7 +55,8 @@ snd-soc-cs35l33-objs := cs35l33.o snd-soc-cs35l34-objs := cs35l34.o snd-soc-cs35l35-objs := cs35l35.o snd-soc-cs35l36-objs := cs35l36.o -snd-soc-cs35l41-objs := cs35l41.o cs35l41-tables.o +snd-soc-cs35l41-lib-objs := cs35l41-lib.o +snd-soc-cs35l41-objs := cs35l41.o snd-soc-cs35l41-spi-objs := cs35l41-spi.o snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o snd-soc-cs42l42-objs := cs42l42.o @@ -396,6 +397,7 @@ obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o obj-$(CONFIG_SND_SOC_CS35L41) += snd-soc-cs35l41.o +obj-$(CONFIG_SND_SOC_CS35L41_LIB) += snd-soc-cs35l41-lib.o obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c index c9b604af6b71..de5c8612f030 100644 --- a/sound/soc/codecs/cs35l41-i2c.c +++ b/sound/soc/codecs/cs35l41-i2c.c @@ -17,7 +17,6 @@ #include <linux/platform_device.h> #include <linux/slab.h> -#include <sound/cs35l41.h> #include "cs35l41.h" static const struct i2c_device_id cs35l41_id_i2c[] = { diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c new file mode 100644 index 000000000000..f19531ebf729 --- /dev/null +++ b/sound/soc/codecs/cs35l41-lib.c @@ -0,0 +1,733 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// cs35l41-lib.c -- CS35L41 Common functions for HDA and ASoC Audio drivers +// +// Copyright 2017-2021 Cirrus Logic, Inc. +// +// Author: David Rhodes <david.rhodes@cirrus.com> +// Author: Lucas Tanure <lucas.tanure@cirrus.com> + +#include <linux/module.h> +#include <linux/regmap.h> + +#include <sound/cs35l41.h> + +static const struct reg_default cs35l41_reg[] = { + { CS35L41_PWR_CTRL1, 0x00000000 }, + { CS35L41_PWR_CTRL3, 0x01000010 }, + { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, + { CS35L41_SP_ENABLES, 0x00000000 }, + { CS35L41_SP_RATE_CTRL, 0x00000028 }, + { CS35L41_SP_FORMAT, 0x18180200 }, + { CS35L41_SP_HIZ_CTRL, 0x00000002 }, + { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, + { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, + { CS35L41_SP_TX_WL, 0x00000018 }, + { CS35L41_SP_RX_WL, 0x00000018 }, + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, + { CS35L41_ASP_TX1_SRC, 0x00000018 }, + { CS35L41_ASP_TX2_SRC, 0x00000019 }, + { CS35L41_ASP_TX3_SRC, 0x00000020 }, + { CS35L41_ASP_TX4_SRC, 0x00000021 }, + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, + { CS35L41_DSP1_RX2_SRC, 0x00000009 }, + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, + { CS35L41_DSP1_RX5_SRC, 0x00000020 }, + { CS35L41_DSP1_RX6_SRC, 0x00000021 }, + { CS35L41_DSP1_RX7_SRC, 0x0000003A }, + { CS35L41_DSP1_RX8_SRC, 0x00000001 }, + { CS35L41_NGATE1_SRC, 0x00000008 }, + { CS35L41_NGATE2_SRC, 0x00000009 }, + { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, + { CS35L41_CLASSH_CFG, 0x000B0405 }, + { CS35L41_WKFET_CFG, 0x00000111 }, + { CS35L41_NG_CFG, 0x00000033 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, + { CS35L41_GPIO1_CTRL1, 0xE1000001 }, + { CS35L41_GPIO2_CTRL1, 0xE1000001 }, + { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, + { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, + { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, +}; + +static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_DEVID: + case CS35L41_REVID: + case CS35L41_FABID: + case CS35L41_RELID: + case CS35L41_OTPID: + case CS35L41_TEST_KEY_CTL: + case CS35L41_USER_KEY_CTL: + case CS35L41_OTP_CTRL0: + case CS35L41_OTP_CTRL3: + case CS35L41_OTP_CTRL4: + case CS35L41_OTP_CTRL5: + case CS35L41_OTP_CTRL6: + case CS35L41_OTP_CTRL7: + case CS35L41_OTP_CTRL8: + case CS35L41_PWR_CTRL1: + case CS35L41_PWR_CTRL2: + case CS35L41_PWR_CTRL3: + case CS35L41_CTRL_OVRRIDE: + case CS35L41_AMP_OUT_MUTE: + case CS35L41_PROTECT_REL_ERR_IGN: + case CS35L41_GPIO_PAD_CONTROL: + case CS35L41_JTAG_CONTROL: + case CS35L41_PLL_CLK_CTRL: + case CS35L41_DSP_CLK_CTRL: + case CS35L41_GLOBAL_CLK_CTRL: + case CS35L41_DATA_FS_SEL: + case CS35L41_MDSYNC_EN: + case CS35L41_MDSYNC_TX_ID: + case CS35L41_MDSYNC_PWR_CTRL: + case CS35L41_MDSYNC_DATA_TX: + case CS35L41_MDSYNC_TX_STATUS: + case CS35L41_MDSYNC_DATA_RX: + case CS35L41_MDSYNC_RX_STATUS: + case CS35L41_MDSYNC_ERR_STATUS: + case CS35L41_MDSYNC_SYNC_PTE2: + case CS35L41_MDSYNC_SYNC_PTE3: + case CS35L41_MDSYNC_SYNC_MSM_STATUS: + case CS35L41_BSTCVRT_VCTRL1: + case CS35L41_BSTCVRT_VCTRL2: + case CS35L41_BSTCVRT_PEAK_CUR: + case CS35L41_BSTCVRT_SFT_RAMP: + case CS35L41_BSTCVRT_COEFF: + case CS35L41_BSTCVRT_SLOPE_LBST: + case CS35L41_BSTCVRT_SW_FREQ: + case CS35L41_BSTCVRT_DCM_CTRL: + case CS35L41_BSTCVRT_DCM_MODE_FORCE: + case CS35L41_BSTCVRT_OVERVOLT_CTRL: + case CS35L41_VI_VOL_POL: + case CS35L41_DTEMP_WARN_THLD: + case CS35L41_DTEMP_CFG: + case CS35L41_DTEMP_EN: + case CS35L41_VPVBST_FS_SEL: + case CS35L41_SP_ENABLES: + case CS35L41_SP_RATE_CTRL: + case CS35L41_SP_FORMAT: + case CS35L41_SP_HIZ_CTRL: + case CS35L41_SP_FRAME_TX_SLOT: + case CS35L41_SP_FRAME_RX_SLOT: + case CS35L41_SP_TX_WL: + case CS35L41_SP_RX_WL: + case CS35L41_DAC_PCM1_SRC: + case CS35L41_ASP_TX1_SRC: + case CS35L41_ASP_TX2_SRC: + case CS35L41_ASP_TX3_SRC: + case CS35L41_ASP_TX4_SRC: + case CS35L41_DSP1_RX1_SRC: + case CS35L41_DSP1_RX2_SRC: + case CS35L41_DSP1_RX3_SRC: + case CS35L41_DSP1_RX4_SRC: + case CS35L41_DSP1_RX5_SRC: + case CS35L41_DSP1_RX6_SRC: + case CS35L41_DSP1_RX7_SRC: + case CS35L41_DSP1_RX8_SRC: + case CS35L41_NGATE1_SRC: + case CS35L41_NGATE2_SRC: + case CS35L41_AMP_DIG_VOL_CTRL: + case CS35L41_VPBR_CFG: + case CS35L41_VBBR_CFG: + case CS35L41_VPBR_STATUS: + case CS35L41_VBBR_STATUS: + case CS35L41_OVERTEMP_CFG: + case CS35L41_AMP_ERR_VOL: + case CS35L41_VOL_STATUS_TO_DSP: + case CS35L41_CLASSH_CFG: + case CS35L41_WKFET_CFG: + case CS35L41_NG_CFG: + case CS35L41_AMP_GAIN_CTRL: + case CS35L41_DAC_MSM_CFG: + case CS35L41_IRQ1_CFG: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: + case CS35L41_IRQ1_STATUS2: + case CS35L41_IRQ1_STATUS3: + case CS35L41_IRQ1_STATUS4: + case CS35L41_IRQ1_RAW_STATUS1: + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: + case CS35L41_IRQ1_MASK1: + case CS35L41_IRQ1_MASK2: + case CS35L41_IRQ1_MASK3: + case CS35L41_IRQ1_MASK4: + case CS35L41_IRQ1_FRC1: + case CS35L41_IRQ1_FRC2: + case CS35L41_IRQ1_FRC3: + case CS35L41_IRQ1_FRC4: + case CS35L41_IRQ1_EDGE1: + case CS35L41_IRQ1_EDGE4: + case CS35L41_IRQ1_POL1: + case CS35L41_IRQ1_POL2: + case CS35L41_IRQ1_POL3: + case CS35L41_IRQ1_POL4: + case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_CFG: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: + case CS35L41_IRQ2_STATUS3: + case CS35L41_IRQ2_STATUS4: + case CS35L41_IRQ2_RAW_STATUS1: + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: + case CS35L41_IRQ2_MASK1: + case CS35L41_IRQ2_MASK2: + case CS35L41_IRQ2_MASK3: + case CS35L41_IRQ2_MASK4: + case CS35L41_IRQ2_FRC1: + case CS35L41_IRQ2_FRC2: + case CS35L41_IRQ2_FRC3: + case CS35L41_IRQ2_FRC4: + case CS35L41_IRQ2_EDGE1: + case CS35L41_IRQ2_EDGE4: + case CS35L41_IRQ2_POL1: + case CS35L41_IRQ2_POL2: + case CS35L41_IRQ2_POL3: + case CS35L41_IRQ2_POL4: + case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: + case CS35L41_GPIO1_CTRL1: + case CS35L41_GPIO2_CTRL1: + case CS35L41_MIXER_NGATE_CFG: + case CS35L41_MIXER_NGATE_CH1_CFG: + case CS35L41_MIXER_NGATE_CH2_CFG: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_CLOCK_DETECT_1: + case CS35L41_DIE_STS1: + case CS35L41_DIE_STS2: + case CS35L41_TEMP_CAL1: + case CS35L41_TEMP_CAL2: + case CS35L41_DSP1_TIMESTAMP_COUNT: + case CS35L41_DSP1_SYS_ID: + case CS35L41_DSP1_SYS_VERSION: + case CS35L41_DSP1_SYS_CORE_ID: + case CS35L41_DSP1_SYS_AHB_ADDR: + case CS35L41_DSP1_SYS_XSRAM_SIZE: + case CS35L41_DSP1_SYS_YSRAM_SIZE: + case CS35L41_DSP1_SYS_PSRAM_SIZE: + case CS35L41_DSP1_SYS_PM_BOOT_SIZE: + case CS35L41_DSP1_SYS_FEATURES: + case CS35L41_DSP1_SYS_FIR_FILTERS: + case CS35L41_DSP1_SYS_LMS_FILTERS: + case CS35L41_DSP1_SYS_XM_BANK_SIZE: + case CS35L41_DSP1_SYS_YM_BANK_SIZE: + case CS35L41_DSP1_SYS_PM_BANK_SIZE: + case CS35L41_DSP1_RX1_RATE: + case CS35L41_DSP1_RX2_RATE: + case CS35L41_DSP1_RX3_RATE: + case CS35L41_DSP1_RX4_RATE: + case CS35L41_DSP1_RX5_RATE: + case CS35L41_DSP1_RX6_RATE: + case CS35L41_DSP1_RX7_RATE: + case CS35L41_DSP1_RX8_RATE: + case CS35L41_DSP1_TX1_RATE: + case CS35L41_DSP1_TX2_RATE: + case CS35L41_DSP1_TX3_RATE: + case CS35L41_DSP1_TX4_RATE: + case CS35L41_DSP1_TX5_RATE: + case CS35L41_DSP1_TX6_RATE: + case CS35L41_DSP1_TX7_RATE: + case CS35L41_DSP1_TX8_RATE: + case CS35L41_DSP1_SCRATCH1: + case CS35L41_DSP1_SCRATCH2: + case CS35L41_DSP1_SCRATCH3: + case CS35L41_DSP1_SCRATCH4: + case CS35L41_DSP1_CCM_CORE_CTRL: + case CS35L41_DSP1_CCM_CLK_OVERRIDE: + case CS35L41_DSP1_XM_MSTR_EN: + case CS35L41_DSP1_XM_CORE_PRI: + case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: + case CS35L41_DSP1_XM_AHB_UP_PL_PRI: + case CS35L41_DSP1_XM_ACCEL_PL0_PRI: + case CS35L41_DSP1_XM_NPL0_PRI: + case CS35L41_DSP1_YM_MSTR_EN: + case CS35L41_DSP1_YM_CORE_PRI: + case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: + case CS35L41_DSP1_YM_AHB_UP_PL_PRI: + case CS35L41_DSP1_YM_ACCEL_PL0_PRI: + case CS35L41_DSP1_YM_NPL0_PRI: + case CS35L41_DSP1_MPU_XM_ACCESS0: + case CS35L41_DSP1_MPU_YM_ACCESS0: + case CS35L41_DSP1_MPU_WNDW_ACCESS0: + case CS35L41_DSP1_MPU_XREG_ACCESS0: + case CS35L41_DSP1_MPU_YREG_ACCESS0: + case CS35L41_DSP1_MPU_XM_ACCESS1: + case CS35L41_DSP1_MPU_YM_ACCESS1: + case CS35L41_DSP1_MPU_WNDW_ACCESS1: + case CS35L41_DSP1_MPU_XREG_ACCESS1: + case CS35L41_DSP1_MPU_YREG_ACCESS1: + case CS35L41_DSP1_MPU_XM_ACCESS2: + case CS35L41_DSP1_MPU_YM_ACCESS2: + case CS35L41_DSP1_MPU_WNDW_ACCESS2: + case CS35L41_DSP1_MPU_XREG_ACCESS2: + case CS35L41_DSP1_MPU_YREG_ACCESS2: + case CS35L41_DSP1_MPU_XM_ACCESS3: + case CS35L41_DSP1_MPU_YM_ACCESS3: + case CS35L41_DSP1_MPU_WNDW_ACCESS3: + case CS35L41_DSP1_MPU_XREG_ACCESS3: + case CS35L41_DSP1_MPU_YREG_ACCESS3: + case CS35L41_DSP1_MPU_XM_VIO_ADDR: + case CS35L41_DSP1_MPU_XM_VIO_STATUS: + case CS35L41_DSP1_MPU_YM_VIO_ADDR: + case CS35L41_DSP1_MPU_YM_VIO_STATUS: + case CS35L41_DSP1_MPU_PM_VIO_ADDR: + case CS35L41_DSP1_MPU_PM_VIO_STATUS: + case CS35L41_DSP1_MPU_LOCK_CONFIG: + case CS35L41_DSP1_MPU_WDT_RST_CTRL: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: + case CS35L41_OTP_TRIM_4: + case CS35L41_OTP_TRIM_5: + case CS35L41_OTP_TRIM_6: + case CS35L41_OTP_TRIM_7: + case CS35L41_OTP_TRIM_8: + case CS35L41_OTP_TRIM_9: + case CS35L41_OTP_TRIM_10: + case CS35L41_OTP_TRIM_11: + case CS35L41_OTP_TRIM_12: + case CS35L41_OTP_TRIM_13: + case CS35L41_OTP_TRIM_14: + case CS35L41_OTP_TRIM_15: + case CS35L41_OTP_TRIM_16: + case CS35L41_OTP_TRIM_17: + case CS35L41_OTP_TRIM_18: + case CS35L41_OTP_TRIM_19: + case CS35L41_OTP_TRIM_20: + case CS35L41_OTP_TRIM_21: + case CS35L41_OTP_TRIM_22: + case CS35L41_OTP_TRIM_23: + case CS35L41_OTP_TRIM_24: + case CS35L41_OTP_TRIM_25: + case CS35L41_OTP_TRIM_26: + case CS35L41_OTP_TRIM_27: + case CS35L41_OTP_TRIM_28: + case CS35L41_OTP_TRIM_29: + case CS35L41_OTP_TRIM_30: + case CS35L41_OTP_TRIM_31: + case CS35L41_OTP_TRIM_32: + case CS35L41_OTP_TRIM_33: + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: + case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + /*test regs*/ + case CS35L41_PLL_OVR: + case CS35L41_BST_TEST_DUTY: + case CS35L41_DIGPWM_IOCTRL: + return true; + default: + return false; + } +} + +static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + return true; + default: + return false; + } +} + +static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_DEVID: + case CS35L41_SFT_RESET: + case CS35L41_FABID: + case CS35L41_REVID: + case CS35L41_DTEMP_EN: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: + case CS35L41_IRQ1_STATUS2: + case CS35L41_IRQ1_STATUS3: + case CS35L41_IRQ1_STATUS4: + case CS35L41_IRQ1_RAW_STATUS1: + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: + case CS35L41_IRQ1_FRC1: + case CS35L41_IRQ1_FRC2: + case CS35L41_IRQ1_FRC3: + case CS35L41_IRQ1_FRC4: + case CS35L41_IRQ1_EDGE1: + case CS35L41_IRQ1_EDGE4: + case CS35L41_IRQ1_POL1: + case CS35L41_IRQ1_POL2: + case CS35L41_IRQ1_POL3: + case CS35L41_IRQ1_POL4: + case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: + case CS35L41_IRQ2_STATUS3: + case CS35L41_IRQ2_STATUS4: + case CS35L41_IRQ2_RAW_STATUS1: + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: + case CS35L41_IRQ2_FRC1: + case CS35L41_IRQ2_FRC2: + case CS35L41_IRQ2_FRC3: + case CS35L41_IRQ2_FRC4: + case CS35L41_IRQ2_EDGE1: + case CS35L41_IRQ2_EDGE4: + case CS35L41_IRQ2_POL1: + case CS35L41_IRQ2_POL2: + case CS35L41_IRQ2_POL3: + case CS35L41_IRQ2_POL4: + case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: + case CS35L41_OTP_TRIM_4: + case CS35L41_OTP_TRIM_5: + case CS35L41_OTP_TRIM_6: + case CS35L41_OTP_TRIM_7: + case CS35L41_OTP_TRIM_8: + case CS35L41_OTP_TRIM_9: + case CS35L41_OTP_TRIM_10: + case CS35L41_OTP_TRIM_11: + case CS35L41_OTP_TRIM_12: + case CS35L41_OTP_TRIM_13: + case CS35L41_OTP_TRIM_14: + case CS35L41_OTP_TRIM_15: + case CS35L41_OTP_TRIM_16: + case CS35L41_OTP_TRIM_17: + case CS35L41_OTP_TRIM_18: + case CS35L41_OTP_TRIM_19: + case CS35L41_OTP_TRIM_20: + case CS35L41_OTP_TRIM_21: + case CS35L41_OTP_TRIM_22: + case CS35L41_OTP_TRIM_23: + case CS35L41_OTP_TRIM_24: + case CS35L41_OTP_TRIM_25: + case CS35L41_OTP_TRIM_26: + case CS35L41_OTP_TRIM_27: + case CS35L41_OTP_TRIM_28: + case CS35L41_OTP_TRIM_29: + case CS35L41_OTP_TRIM_30: + case CS35L41_OTP_TRIM_31: + case CS35L41_OTP_TRIM_32: + case CS35L41_OTP_TRIM_33: + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: + case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: + return false; + } +} + +static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ + { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ + { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ + { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ + { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ + { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ + { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ + { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ + { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ + { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ + { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ + { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ + { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ + { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ + { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ + { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ + { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ + { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ + { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ + { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ + { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ + { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ + { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ + { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ + { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ + { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ + { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ + { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ + { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ + { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ + { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ + { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ + { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ + { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ + { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ + { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ + { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ + { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ + { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ + { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ + { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ + { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ + { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ + { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ + { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ + { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ + { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ + { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ + { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ + { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ + { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ + { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ + { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ + { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ + { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ + { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ + { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ + { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ + { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ + { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ + { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ + { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ + { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ + { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ + { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ + { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ + { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ + { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ + { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ + { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ + { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ + { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ + { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ + { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ + { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ + { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ + { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ + { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ + { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ + { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ + { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ + { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ + { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ + { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ + { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ + { 0x00007434, 17, 1 }, /*FORCE_CAL*/ + { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ + { 0x00007068, 0, 9 }, /*MODIX*/ + { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ + { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ + { 0x00000000, 0, 1 }, /*extra bit*/ + { 0x00017040, 0, 8 }, /*X_COORDINATE*/ + { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ + { 0x00017040, 16, 8 }, /*WAFER_ID*/ + { 0x00017040, 24, 8 }, /*DVS*/ + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ +}; + +static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ + { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ + { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ + { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ + { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ + { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ + { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ + { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ + { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ + { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ + { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ + { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ + { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ + { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ + { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ + { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ + { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ + { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ + { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ + { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ + { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ + { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ + { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ + { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ + { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ + { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ + { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ + { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ + { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ + { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ + { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ + { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ + { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ + { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ + { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ + { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ + { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ + { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ + { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ + { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ + { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ + { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ + { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ + { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ + { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ + { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ + { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ + { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ + { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ + { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ + { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ + { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ + { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ + { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ + { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ + { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ + { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ + { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ + { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ + { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ + { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ + { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ + { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ + { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ + { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ + { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ + { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ + { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ + { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ + { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ + { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ + { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ + { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ + { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ + { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ + { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ + { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ + { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ + { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ + { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ + { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ + { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ + { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ + { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ + { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ + { 0x00007434, 17, 1 }, /*FORCE_CAL*/ + { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ + { 0x00007068, 0, 9 }, /*MODIX*/ + { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ + { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ + { 0x00004000, 11, 1 }, /*VMON_POL*/ + { 0x00017040, 0, 8 }, /*X_COORDINATE*/ + { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ + { 0x00017040, 16, 8 }, /*WAFER_ID*/ + { 0x00017040, 24, 8 }, /*DVS*/ + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ +}; + +const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { + { + .id = 0x01, + .map = otp_map_1, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x02, + .map = otp_map_2, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x03, + .map = otp_map_2, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x06, + .map = otp_map_2, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x08, + .map = otp_map_1, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, +}; +EXPORT_SYMBOL_GPL(cs35l41_otp_map_map); + +struct regmap_config cs35l41_regmap_i2c = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = CS35L41_REGSTRIDE, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .precious_reg = cs35l41_precious_reg, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c); + +struct regmap_config cs35l41_regmap_spi = { + .reg_bits = 32, + .val_bits = 32, + .pad_bits = 16, + .reg_stride = CS35L41_REGSTRIDE, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .precious_reg = cs35l41_precious_reg, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); + +MODULE_DESCRIPTION("CS35L41 library"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); +MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c index c202d9df70ee..c157153f28d8 100644 --- a/sound/soc/codecs/cs35l41-spi.c +++ b/sound/soc/codecs/cs35l41-spi.c @@ -15,7 +15,6 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> -#include <sound/cs35l41.h> #include "cs35l41.h" static const struct spi_device_id cs35l41_id_spi[] = { diff --git a/sound/soc/codecs/cs35l41-tables.c b/sound/soc/codecs/cs35l41-tables.c deleted file mode 100644 index 3eb18b17a7b0..000000000000 --- a/sound/soc/codecs/cs35l41-tables.c +++ /dev/null @@ -1,723 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// cs35l41-tables.c -- CS35L41 ALSA SoC audio driver -// -// Copyright 2017-2021 Cirrus Logic, Inc. -// -// Author: David Rhodes <david.rhodes@cirrus.com> - -#include "cs35l41.h" - -static const struct reg_default cs35l41_reg[] = { - { CS35L41_PWR_CTRL1, 0x00000000 }, - { CS35L41_PWR_CTRL3, 0x01000010 }, - { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, - { CS35L41_SP_ENABLES, 0x00000000 }, - { CS35L41_SP_RATE_CTRL, 0x00000028 }, - { CS35L41_SP_FORMAT, 0x18180200 }, - { CS35L41_SP_HIZ_CTRL, 0x00000002 }, - { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, - { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, - { CS35L41_SP_TX_WL, 0x00000018 }, - { CS35L41_SP_RX_WL, 0x00000018 }, - { CS35L41_DAC_PCM1_SRC, 0x00000008 }, - { CS35L41_ASP_TX1_SRC, 0x00000018 }, - { CS35L41_ASP_TX2_SRC, 0x00000019 }, - { CS35L41_ASP_TX3_SRC, 0x00000020 }, - { CS35L41_ASP_TX4_SRC, 0x00000021 }, - { CS35L41_DSP1_RX1_SRC, 0x00000008 }, - { CS35L41_DSP1_RX2_SRC, 0x00000009 }, - { CS35L41_DSP1_RX3_SRC, 0x00000018 }, - { CS35L41_DSP1_RX4_SRC, 0x00000019 }, - { CS35L41_DSP1_RX5_SRC, 0x00000020 }, - { CS35L41_DSP1_RX6_SRC, 0x00000021 }, - { CS35L41_DSP1_RX7_SRC, 0x0000003A }, - { CS35L41_DSP1_RX8_SRC, 0x00000001 }, - { CS35L41_NGATE1_SRC, 0x00000008 }, - { CS35L41_NGATE2_SRC, 0x00000009 }, - { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, - { CS35L41_CLASSH_CFG, 0x000B0405 }, - { CS35L41_WKFET_CFG, 0x00000111 }, - { CS35L41_NG_CFG, 0x00000033 }, - { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, - { CS35L41_GPIO1_CTRL1, 0xE1000001 }, - { CS35L41_GPIO2_CTRL1, 0xE1000001 }, - { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, - { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, - { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, -}; - -static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case CS35L41_DEVID: - case CS35L41_REVID: - case CS35L41_FABID: - case CS35L41_RELID: - case CS35L41_OTPID: - case CS35L41_TEST_KEY_CTL: - case CS35L41_USER_KEY_CTL: - case CS35L41_OTP_CTRL0: - case CS35L41_OTP_CTRL3: - case CS35L41_OTP_CTRL4: - case CS35L41_OTP_CTRL5: - case CS35L41_OTP_CTRL6: - case CS35L41_OTP_CTRL7: - case CS35L41_OTP_CTRL8: - case CS35L41_PWR_CTRL1: - case CS35L41_PWR_CTRL2: - case CS35L41_PWR_CTRL3: - case CS35L41_CTRL_OVRRIDE: - case CS35L41_AMP_OUT_MUTE: - case CS35L41_PROTECT_REL_ERR_IGN: - case CS35L41_GPIO_PAD_CONTROL: - case CS35L41_JTAG_CONTROL: - case CS35L41_PLL_CLK_CTRL: - case CS35L41_DSP_CLK_CTRL: - case CS35L41_GLOBAL_CLK_CTRL: - case CS35L41_DATA_FS_SEL: - case CS35L41_MDSYNC_EN: - case CS35L41_MDSYNC_TX_ID: - case CS35L41_MDSYNC_PWR_CTRL: - case CS35L41_MDSYNC_DATA_TX: - case CS35L41_MDSYNC_TX_STATUS: - case CS35L41_MDSYNC_DATA_RX: - case CS35L41_MDSYNC_RX_STATUS: - case CS35L41_MDSYNC_ERR_STATUS: - case CS35L41_MDSYNC_SYNC_PTE2: - case CS35L41_MDSYNC_SYNC_PTE3: - case CS35L41_MDSYNC_SYNC_MSM_STATUS: - case CS35L41_BSTCVRT_VCTRL1: - case CS35L41_BSTCVRT_VCTRL2: - case CS35L41_BSTCVRT_PEAK_CUR: - case CS35L41_BSTCVRT_SFT_RAMP: - case CS35L41_BSTCVRT_COEFF: - case CS35L41_BSTCVRT_SLOPE_LBST: - case CS35L41_BSTCVRT_SW_FREQ: - case CS35L41_BSTCVRT_DCM_CTRL: - case CS35L41_BSTCVRT_DCM_MODE_FORCE: - case CS35L41_BSTCVRT_OVERVOLT_CTRL: - case CS35L41_VI_VOL_POL: - case CS35L41_DTEMP_WARN_THLD: - case CS35L41_DTEMP_CFG: - case CS35L41_DTEMP_EN: - case CS35L41_VPVBST_FS_SEL: - case CS35L41_SP_ENABLES: - case CS35L41_SP_RATE_CTRL: - case CS35L41_SP_FORMAT: - case CS35L41_SP_HIZ_CTRL: - case CS35L41_SP_FRAME_TX_SLOT: - case CS35L41_SP_FRAME_RX_SLOT: - case CS35L41_SP_TX_WL: - case CS35L41_SP_RX_WL: - case CS35L41_DAC_PCM1_SRC: - case CS35L41_ASP_TX1_SRC: - case CS35L41_ASP_TX2_SRC: - case CS35L41_ASP_TX3_SRC: - case CS35L41_ASP_TX4_SRC: - case CS35L41_DSP1_RX1_SRC: - case CS35L41_DSP1_RX2_SRC: - case CS35L41_DSP1_RX3_SRC: - case CS35L41_DSP1_RX4_SRC: - case CS35L41_DSP1_RX5_SRC: - case CS35L41_DSP1_RX6_SRC: - case CS35L41_DSP1_RX7_SRC: - case CS35L41_DSP1_RX8_SRC: - case CS35L41_NGATE1_SRC: - case CS35L41_NGATE2_SRC: - case CS35L41_AMP_DIG_VOL_CTRL: - case CS35L41_VPBR_CFG: - case CS35L41_VBBR_CFG: - case CS35L41_VPBR_STATUS: - case CS35L41_VBBR_STATUS: - case CS35L41_OVERTEMP_CFG: - case CS35L41_AMP_ERR_VOL: - case CS35L41_VOL_STATUS_TO_DSP: - case CS35L41_CLASSH_CFG: - case CS35L41_WKFET_CFG: - case CS35L41_NG_CFG: - case CS35L41_AMP_GAIN_CTRL: - case CS35L41_DAC_MSM_CFG: - case CS35L41_IRQ1_CFG: - case CS35L41_IRQ1_STATUS: - case CS35L41_IRQ1_STATUS1: - case CS35L41_IRQ1_STATUS2: - case CS35L41_IRQ1_STATUS3: - case CS35L41_IRQ1_STATUS4: - case CS35L41_IRQ1_RAW_STATUS1: - case CS35L41_IRQ1_RAW_STATUS2: - case CS35L41_IRQ1_RAW_STATUS3: - case CS35L41_IRQ1_RAW_STATUS4: - case CS35L41_IRQ1_MASK1: - case CS35L41_IRQ1_MASK2: - case CS35L41_IRQ1_MASK3: - case CS35L41_IRQ1_MASK4: - case CS35L41_IRQ1_FRC1: - case CS35L41_IRQ1_FRC2: - case CS35L41_IRQ1_FRC3: - case CS35L41_IRQ1_FRC4: - case CS35L41_IRQ1_EDGE1: - case CS35L41_IRQ1_EDGE4: - case CS35L41_IRQ1_POL1: - case CS35L41_IRQ1_POL2: - case CS35L41_IRQ1_POL3: - case CS35L41_IRQ1_POL4: - case CS35L41_IRQ1_DB3: - case CS35L41_IRQ2_CFG: - case CS35L41_IRQ2_STATUS: - case CS35L41_IRQ2_STATUS1: - case CS35L41_IRQ2_STATUS2: - case CS35L41_IRQ2_STATUS3: - case CS35L41_IRQ2_STATUS4: - case CS35L41_IRQ2_RAW_STATUS1: - case CS35L41_IRQ2_RAW_STATUS2: - case CS35L41_IRQ2_RAW_STATUS3: - case CS35L41_IRQ2_RAW_STATUS4: - case CS35L41_IRQ2_MASK1: - case CS35L41_IRQ2_MASK2: - case CS35L41_IRQ2_MASK3: - case CS35L41_IRQ2_MASK4: - case CS35L41_IRQ2_FRC1: - case CS35L41_IRQ2_FRC2: - case CS35L41_IRQ2_FRC3: - case CS35L41_IRQ2_FRC4: - case CS35L41_IRQ2_EDGE1: - case CS35L41_IRQ2_EDGE4: - case CS35L41_IRQ2_POL1: - case CS35L41_IRQ2_POL2: - case CS35L41_IRQ2_POL3: - case CS35L41_IRQ2_POL4: - case CS35L41_IRQ2_DB3: - case CS35L41_GPIO_STATUS1: - case CS35L41_GPIO1_CTRL1: - case CS35L41_GPIO2_CTRL1: - case CS35L41_MIXER_NGATE_CFG: - case CS35L41_MIXER_NGATE_CH1_CFG: - case CS35L41_MIXER_NGATE_CH2_CFG: - case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: - case CS35L41_CLOCK_DETECT_1: - case CS35L41_DIE_STS1: - case CS35L41_DIE_STS2: - case CS35L41_TEMP_CAL1: - case CS35L41_TEMP_CAL2: - case CS35L41_DSP1_TIMESTAMP_COUNT: - case CS35L41_DSP1_SYS_ID: - case CS35L41_DSP1_SYS_VERSION: - case CS35L41_DSP1_SYS_CORE_ID: - case CS35L41_DSP1_SYS_AHB_ADDR: - case CS35L41_DSP1_SYS_XSRAM_SIZE: - case CS35L41_DSP1_SYS_YSRAM_SIZE: - case CS35L41_DSP1_SYS_PSRAM_SIZE: - case CS35L41_DSP1_SYS_PM_BOOT_SIZE: - case CS35L41_DSP1_SYS_FEATURES: - case CS35L41_DSP1_SYS_FIR_FILTERS: - case CS35L41_DSP1_SYS_LMS_FILTERS: - case CS35L41_DSP1_SYS_XM_BANK_SIZE: - case CS35L41_DSP1_SYS_YM_BANK_SIZE: - case CS35L41_DSP1_SYS_PM_BANK_SIZE: - case CS35L41_DSP1_RX1_RATE: - case CS35L41_DSP1_RX2_RATE: - case CS35L41_DSP1_RX3_RATE: - case CS35L41_DSP1_RX4_RATE: - case CS35L41_DSP1_RX5_RATE: - case CS35L41_DSP1_RX6_RATE: - case CS35L41_DSP1_RX7_RATE: - case CS35L41_DSP1_RX8_RATE: - case CS35L41_DSP1_TX1_RATE: - case CS35L41_DSP1_TX2_RATE: - case CS35L41_DSP1_TX3_RATE: - case CS35L41_DSP1_TX4_RATE: - case CS35L41_DSP1_TX5_RATE: - case CS35L41_DSP1_TX6_RATE: - case CS35L41_DSP1_TX7_RATE: - case CS35L41_DSP1_TX8_RATE: - case CS35L41_DSP1_SCRATCH1: - case CS35L41_DSP1_SCRATCH2: - case CS35L41_DSP1_SCRATCH3: - case CS35L41_DSP1_SCRATCH4: - case CS35L41_DSP1_CCM_CORE_CTRL: - case CS35L41_DSP1_CCM_CLK_OVERRIDE: - case CS35L41_DSP1_XM_MSTR_EN: - case CS35L41_DSP1_XM_CORE_PRI: - case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: - case CS35L41_DSP1_XM_AHB_UP_PL_PRI: - case CS35L41_DSP1_XM_ACCEL_PL0_PRI: - case CS35L41_DSP1_XM_NPL0_PRI: - case CS35L41_DSP1_YM_MSTR_EN: - case CS35L41_DSP1_YM_CORE_PRI: - case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: - case CS35L41_DSP1_YM_AHB_UP_PL_PRI: - case CS35L41_DSP1_YM_ACCEL_PL0_PRI: - case CS35L41_DSP1_YM_NPL0_PRI: - case CS35L41_DSP1_MPU_XM_ACCESS0: - case CS35L41_DSP1_MPU_YM_ACCESS0: - case CS35L41_DSP1_MPU_WNDW_ACCESS0: - case CS35L41_DSP1_MPU_XREG_ACCESS0: - case CS35L41_DSP1_MPU_YREG_ACCESS0: - case CS35L41_DSP1_MPU_XM_ACCESS1: - case CS35L41_DSP1_MPU_YM_ACCESS1: - case CS35L41_DSP1_MPU_WNDW_ACCESS1: - case CS35L41_DSP1_MPU_XREG_ACCESS1: - case CS35L41_DSP1_MPU_YREG_ACCESS1: - case CS35L41_DSP1_MPU_XM_ACCESS2: - case CS35L41_DSP1_MPU_YM_ACCESS2: - case CS35L41_DSP1_MPU_WNDW_ACCESS2: - case CS35L41_DSP1_MPU_XREG_ACCESS2: - case CS35L41_DSP1_MPU_YREG_ACCESS2: - case CS35L41_DSP1_MPU_XM_ACCESS3: - case CS35L41_DSP1_MPU_YM_ACCESS3: - case CS35L41_DSP1_MPU_WNDW_ACCESS3: - case CS35L41_DSP1_MPU_XREG_ACCESS3: - case CS35L41_DSP1_MPU_YREG_ACCESS3: - case CS35L41_DSP1_MPU_XM_VIO_ADDR: - case CS35L41_DSP1_MPU_XM_VIO_STATUS: - case CS35L41_DSP1_MPU_YM_VIO_ADDR: - case CS35L41_DSP1_MPU_YM_VIO_STATUS: - case CS35L41_DSP1_MPU_PM_VIO_ADDR: - case CS35L41_DSP1_MPU_PM_VIO_STATUS: - case CS35L41_DSP1_MPU_LOCK_CONFIG: - case CS35L41_DSP1_MPU_WDT_RST_CTRL: - case CS35L41_OTP_TRIM_1: - case CS35L41_OTP_TRIM_2: - case CS35L41_OTP_TRIM_3: - case CS35L41_OTP_TRIM_4: - case CS35L41_OTP_TRIM_5: - case CS35L41_OTP_TRIM_6: - case CS35L41_OTP_TRIM_7: - case CS35L41_OTP_TRIM_8: - case CS35L41_OTP_TRIM_9: - case CS35L41_OTP_TRIM_10: - case CS35L41_OTP_TRIM_11: - case CS35L41_OTP_TRIM_12: - case CS35L41_OTP_TRIM_13: - case CS35L41_OTP_TRIM_14: - case CS35L41_OTP_TRIM_15: - case CS35L41_OTP_TRIM_16: - case CS35L41_OTP_TRIM_17: - case CS35L41_OTP_TRIM_18: - case CS35L41_OTP_TRIM_19: - case CS35L41_OTP_TRIM_20: - case CS35L41_OTP_TRIM_21: - case CS35L41_OTP_TRIM_22: - case CS35L41_OTP_TRIM_23: - case CS35L41_OTP_TRIM_24: - case CS35L41_OTP_TRIM_25: - case CS35L41_OTP_TRIM_26: - case CS35L41_OTP_TRIM_27: - case CS35L41_OTP_TRIM_28: - case CS35L41_OTP_TRIM_29: - case CS35L41_OTP_TRIM_30: - case CS35L41_OTP_TRIM_31: - case CS35L41_OTP_TRIM_32: - case CS35L41_OTP_TRIM_33: - case CS35L41_OTP_TRIM_34: - case CS35L41_OTP_TRIM_35: - case CS35L41_OTP_TRIM_36: - case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: - case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: - case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: - case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: - case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: - case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: - case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: - case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: - /*test regs*/ - case CS35L41_PLL_OVR: - case CS35L41_BST_TEST_DUTY: - case CS35L41_DIGPWM_IOCTRL: - return true; - default: - return false; - } -} - -static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: - case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: - case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: - case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: - return true; - default: - return false; - } -} - -static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case CS35L41_DEVID: - case CS35L41_SFT_RESET: - case CS35L41_FABID: - case CS35L41_REVID: - case CS35L41_DTEMP_EN: - case CS35L41_IRQ1_STATUS: - case CS35L41_IRQ1_STATUS1: - case CS35L41_IRQ1_STATUS2: - case CS35L41_IRQ1_STATUS3: - case CS35L41_IRQ1_STATUS4: - case CS35L41_IRQ1_RAW_STATUS1: - case CS35L41_IRQ1_RAW_STATUS2: - case CS35L41_IRQ1_RAW_STATUS3: - case CS35L41_IRQ1_RAW_STATUS4: - case CS35L41_IRQ1_FRC1: - case CS35L41_IRQ1_FRC2: - case CS35L41_IRQ1_FRC3: - case CS35L41_IRQ1_FRC4: - case CS35L41_IRQ1_EDGE1: - case CS35L41_IRQ1_EDGE4: - case CS35L41_IRQ1_POL1: - case CS35L41_IRQ1_POL2: - case CS35L41_IRQ1_POL3: - case CS35L41_IRQ1_POL4: - case CS35L41_IRQ1_DB3: - case CS35L41_IRQ2_STATUS: - case CS35L41_IRQ2_STATUS1: - case CS35L41_IRQ2_STATUS2: - case CS35L41_IRQ2_STATUS3: - case CS35L41_IRQ2_STATUS4: - case CS35L41_IRQ2_RAW_STATUS1: - case CS35L41_IRQ2_RAW_STATUS2: - case CS35L41_IRQ2_RAW_STATUS3: - case CS35L41_IRQ2_RAW_STATUS4: - case CS35L41_IRQ2_FRC1: - case CS35L41_IRQ2_FRC2: - case CS35L41_IRQ2_FRC3: - case CS35L41_IRQ2_FRC4: - case CS35L41_IRQ2_EDGE1: - case CS35L41_IRQ2_EDGE4: - case CS35L41_IRQ2_POL1: - case CS35L41_IRQ2_POL2: - case CS35L41_IRQ2_POL3: - case CS35L41_IRQ2_POL4: - case CS35L41_IRQ2_DB3: - case CS35L41_GPIO_STATUS1: - case CS35L41_OTP_TRIM_1: - case CS35L41_OTP_TRIM_2: - case CS35L41_OTP_TRIM_3: - case CS35L41_OTP_TRIM_4: - case CS35L41_OTP_TRIM_5: - case CS35L41_OTP_TRIM_6: - case CS35L41_OTP_TRIM_7: - case CS35L41_OTP_TRIM_8: - case CS35L41_OTP_TRIM_9: - case CS35L41_OTP_TRIM_10: - case CS35L41_OTP_TRIM_11: - case CS35L41_OTP_TRIM_12: - case CS35L41_OTP_TRIM_13: - case CS35L41_OTP_TRIM_14: - case CS35L41_OTP_TRIM_15: - case CS35L41_OTP_TRIM_16: - case CS35L41_OTP_TRIM_17: - case CS35L41_OTP_TRIM_18: - case CS35L41_OTP_TRIM_19: - case CS35L41_OTP_TRIM_20: - case CS35L41_OTP_TRIM_21: - case CS35L41_OTP_TRIM_22: - case CS35L41_OTP_TRIM_23: - case CS35L41_OTP_TRIM_24: - case CS35L41_OTP_TRIM_25: - case CS35L41_OTP_TRIM_26: - case CS35L41_OTP_TRIM_27: - case CS35L41_OTP_TRIM_28: - case CS35L41_OTP_TRIM_29: - case CS35L41_OTP_TRIM_30: - case CS35L41_OTP_TRIM_31: - case CS35L41_OTP_TRIM_32: - case CS35L41_OTP_TRIM_33: - case CS35L41_OTP_TRIM_34: - case CS35L41_OTP_TRIM_35: - case CS35L41_OTP_TRIM_36: - case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: - case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: - case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: - case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: - case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: - case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: - case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: - case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: - case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: - case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: - return true; - default: - return false; - } -} - -static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { - /* addr shift size */ - { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ - { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ - { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ - { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ - { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ - { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ - { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ - { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ - { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ - { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ - { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ - { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ - { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ - { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ - { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ - { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ - { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ - { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ - { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ - { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ - { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ - { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ - { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ - { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ - { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ - { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ - { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ - { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ - { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ - { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ - { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ - { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ - { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ - { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ - { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ - { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ - { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ - { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ - { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ - { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ - { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ - { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ - { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ - { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ - { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ - { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ - { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ - { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ - { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ - { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ - { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ - { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ - { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ - { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ - { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ - { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ - { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ - { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ - { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ - { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ - { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ - { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ - { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ - { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ - { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ - { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ - { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ - { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ - { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ - { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ - { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ - { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ - { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ - { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ - { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ - { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ - { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ - { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ - { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ - { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ - { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ - { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ - { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ - { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ - { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ - { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ - { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ - { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ - { 0x00007434, 17, 1 }, /*FORCE_CAL*/ - { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ - { 0x00007068, 0, 9 }, /*MODIX*/ - { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ - { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ - { 0x00000000, 0, 1 }, /*extra bit*/ - { 0x00017040, 0, 8 }, /*X_COORDINATE*/ - { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ - { 0x00017040, 16, 8 }, /*WAFER_ID*/ - { 0x00017040, 24, 8 }, /*DVS*/ - { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ -}; - -static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { - /* addr shift size */ - { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ - { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ - { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ - { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ - { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ - { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ - { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ - { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ - { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ - { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ - { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ - { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ - { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ - { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ - { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ - { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ - { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ - { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ - { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ - { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ - { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ - { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ - { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ - { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ - { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ - { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ - { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ - { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ - { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ - { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ - { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ - { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ - { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ - { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ - { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ - { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ - { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ - { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ - { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ - { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ - { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ - { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ - { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ - { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ - { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ - { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ - { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ - { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ - { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ - { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ - { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ - { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ - { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ - { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ - { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ - { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ - { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ - { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ - { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ - { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ - { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ - { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ - { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ - { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ - { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ - { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ - { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ - { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ - { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ - { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ - { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ - { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ - { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ - { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ - { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ - { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ - { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ - { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ - { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ - { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ - { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ - { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ - { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ - { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ - { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ - { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ - { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ - { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ - { 0x00007434, 17, 1 }, /*FORCE_CAL*/ - { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ - { 0x00007068, 0, 9 }, /*MODIX*/ - { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ - { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ - { 0x00004000, 11, 1 }, /*VMON_POL*/ - { 0x00017040, 0, 8 }, /*X_COORDINATE*/ - { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ - { 0x00017040, 16, 8 }, /*WAFER_ID*/ - { 0x00017040, 24, 8 }, /*DVS*/ - { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ -}; - -const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { - { - .id = 0x01, - .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, - .bit_offset = 16, - .word_offset = 2, - }, - { - .id = 0x02, - .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, - .bit_offset = 16, - .word_offset = 2, - }, - { - .id = 0x03, - .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, - .bit_offset = 16, - .word_offset = 2, - }, - { - .id = 0x06, - .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, - .bit_offset = 16, - .word_offset = 2, - }, - { - .id = 0x08, - .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, - .bit_offset = 16, - .word_offset = 2, - }, -}; - -struct regmap_config cs35l41_regmap_i2c = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = CS35L41_REGSTRIDE, - .reg_format_endian = REGMAP_ENDIAN_BIG, - .val_format_endian = REGMAP_ENDIAN_BIG, - .max_register = CS35L41_LASTREG, - .reg_defaults = cs35l41_reg, - .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), - .volatile_reg = cs35l41_volatile_reg, - .readable_reg = cs35l41_readable_reg, - .precious_reg = cs35l41_precious_reg, - .cache_type = REGCACHE_RBTREE, -}; -EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c); - -struct regmap_config cs35l41_regmap_spi = { - .reg_bits = 32, - .val_bits = 32, - .pad_bits = 16, - .reg_stride = CS35L41_REGSTRIDE, - .reg_format_endian = REGMAP_ENDIAN_BIG, - .val_format_endian = REGMAP_ENDIAN_BIG, - .max_register = CS35L41_LASTREG, - .reg_defaults = cs35l41_reg, - .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), - .volatile_reg = cs35l41_volatile_reg, - .readable_reg = cs35l41_readable_reg, - .precious_reg = cs35l41_precious_reg, - .cache_type = REGCACHE_RBTREE, -}; -EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h index c7c45f19754b..26a08d58a8c3 100644 --- a/sound/soc/codecs/cs35l41.h +++ b/sound/soc/codecs/cs35l41.h @@ -11,7 +11,6 @@ #define __CS35L41_H__ #include <linux/gpio/consumer.h> -#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/firmware.h> #include <sound/core.h> @@ -19,742 +18,9 @@ #include "wm_adsp.h" -#define CS35L41_FIRSTREG 0x00000000 -#define CS35L41_LASTREG 0x03804FE8 -#define CS35L41_DEVID 0x00000000 -#define CS35L41_REVID 0x00000004 -#define CS35L41_FABID 0x00000008 -#define CS35L41_RELID 0x0000000C -#define CS35L41_OTPID 0x00000010 -#define CS35L41_SFT_RESET 0x00000020 -#define CS35L41_TEST_KEY_CTL 0x00000040 -#define CS35L41_USER_KEY_CTL 0x00000044 -#define CS35L41_OTP_MEM0 0x00000400 -#define CS35L41_OTP_MEM31 0x0000047C -#define CS35L41_OTP_CTRL0 0x00000500 -#define CS35L41_OTP_CTRL1 0x00000504 -#define CS35L41_OTP_CTRL3 0x00000508 -#define CS35L41_OTP_CTRL4 0x0000050C -#define CS35L41_OTP_CTRL5 0x00000510 -#define CS35L41_OTP_CTRL6 0x00000514 -#define CS35L41_OTP_CTRL7 0x00000518 -#define CS35L41_OTP_CTRL8 0x0000051C -#define CS35L41_PWR_CTRL1 0x00002014 -#define CS35L41_PWR_CTRL2 0x00002018 -#define CS35L41_PWR_CTRL3 0x0000201C -#define CS35L41_CTRL_OVRRIDE 0x00002020 -#define CS35L41_AMP_OUT_MUTE 0x00002024 -#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 -#define CS35L41_GPIO_PAD_CONTROL 0x0000242C -#define CS35L41_JTAG_CONTROL 0x00002438 -#define CS35L41_PLL_CLK_CTRL 0x00002C04 -#define CS35L41_DSP_CLK_CTRL 0x00002C08 -#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C -#define CS35L41_DATA_FS_SEL 0x00002C10 -#define CS35L41_TST_FS_MON0 0x00002D10 -#define CS35L41_MDSYNC_EN 0x00003400 -#define CS35L41_MDSYNC_TX_ID 0x00003408 -#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C -#define CS35L41_MDSYNC_DATA_TX 0x00003410 -#define CS35L41_MDSYNC_TX_STATUS 0x00003414 -#define CS35L41_MDSYNC_DATA_RX 0x0000341C -#define CS35L41_MDSYNC_RX_STATUS 0x00003420 -#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 -#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 -#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C -#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C -#define CS35L41_BSTCVRT_VCTRL1 0x00003800 -#define CS35L41_BSTCVRT_VCTRL2 0x00003804 -#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 -#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C -#define CS35L41_BSTCVRT_COEFF 0x00003810 -#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 -#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 -#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C -#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 -#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 -#define CS35L41_VI_VOL_POL 0x00004000 -#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 -#define CS35L41_DTEMP_WARN_THLD 0x00004220 -#define CS35L41_DTEMP_CFG 0x00004224 -#define CS35L41_DTEMP_EN 0x00004308 -#define CS35L41_VPVBST_FS_SEL 0x00004400 -#define CS35L41_SP_ENABLES 0x00004800 -#define CS35L41_SP_RATE_CTRL 0x00004804 -#define CS35L41_SP_FORMAT 0x00004808 -#define CS35L41_SP_HIZ_CTRL 0x0000480C -#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 -#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 -#define CS35L41_SP_TX_WL 0x00004830 -#define CS35L41_SP_RX_WL 0x00004840 -#define CS35L41_ASP_CONTROL4 0x00004854 -#define CS35L41_DAC_PCM1_SRC 0x00004C00 -#define CS35L41_ASP_TX1_SRC 0x00004C20 -#define CS35L41_ASP_TX2_SRC 0x00004C24 -#define CS35L41_ASP_TX3_SRC 0x00004C28 -#define CS35L41_ASP_TX4_SRC 0x00004C2C -#define CS35L41_DSP1_RX1_SRC 0x00004C40 -#define CS35L41_DSP1_RX2_SRC 0x00004C44 -#define CS35L41_DSP1_RX3_SRC 0x00004C48 -#define CS35L41_DSP1_RX4_SRC 0x00004C4C -#define CS35L41_DSP1_RX5_SRC 0x00004C50 -#define CS35L41_DSP1_RX6_SRC 0x00004C54 -#define CS35L41_DSP1_RX7_SRC 0x00004C58 -#define CS35L41_DSP1_RX8_SRC 0x00004C5C -#define CS35L41_NGATE1_SRC 0x00004C60 -#define CS35L41_NGATE2_SRC 0x00004C64 -#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 -#define CS35L41_VPBR_CFG 0x00006404 -#define CS35L41_VBBR_CFG 0x00006408 -#define CS35L41_VPBR_STATUS 0x0000640C -#define CS35L41_VBBR_STATUS 0x00006410 -#define CS35L41_OVERTEMP_CFG 0x00006414 -#define CS35L41_AMP_ERR_VOL 0x00006418 -#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 -#define CS35L41_CLASSH_CFG 0x00006800 -#define CS35L41_WKFET_CFG 0x00006804 -#define CS35L41_NG_CFG 0x00006808 -#define CS35L41_AMP_GAIN_CTRL 0x00006C04 -#define CS35L41_DAC_MSM_CFG 0x00007400 -#define CS35L41_IRQ1_CFG 0x00010000 -#define CS35L41_IRQ1_STATUS 0x00010004 -#define CS35L41_IRQ1_STATUS1 0x00010010 -#define CS35L41_IRQ1_STATUS2 0x00010014 -#define CS35L41_IRQ1_STATUS3 0x00010018 -#define CS35L41_IRQ1_STATUS4 0x0001001C -#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 -#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 -#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 -#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C -#define CS35L41_IRQ1_MASK1 0x00010110 -#define CS35L41_IRQ1_MASK2 0x00010114 -#define CS35L41_IRQ1_MASK3 0x00010118 -#define CS35L41_IRQ1_MASK4 0x0001011C -#define CS35L41_IRQ1_FRC1 0x00010190 -#define CS35L41_IRQ1_FRC2 0x00010194 -#define CS35L41_IRQ1_FRC3 0x00010198 -#define CS35L41_IRQ1_FRC4 0x0001019C -#define CS35L41_IRQ1_EDGE1 0x00010210 -#define CS35L41_IRQ1_EDGE4 0x0001021C -#define CS35L41_IRQ1_POL1 0x00010290 -#define CS35L41_IRQ1_POL2 0x00010294 -#define CS35L41_IRQ1_POL3 0x00010298 -#define CS35L41_IRQ1_POL4 0x0001029C -#define CS35L41_IRQ1_DB3 0x00010318 -#define CS35L41_IRQ2_CFG 0x00010800 -#define CS35L41_IRQ2_STATUS 0x00010804 -#define CS35L41_IRQ2_STATUS1 0x00010810 -#define CS35L41_IRQ2_STATUS2 0x00010814 -#define CS35L41_IRQ2_STATUS3 0x00010818 -#define CS35L41_IRQ2_STATUS4 0x0001081C -#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 -#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 -#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 -#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C -#define CS35L41_IRQ2_MASK1 0x00010910 -#define CS35L41_IRQ2_MASK2 0x00010914 -#define CS35L41_IRQ2_MASK3 0x00010918 -#define CS35L41_IRQ2_MASK4 0x0001091C -#define CS35L41_IRQ2_FRC1 0x00010990 -#define CS35L41_IRQ2_FRC2 0x00010994 -#define CS35L41_IRQ2_FRC3 0x00010998 -#define CS35L41_IRQ2_FRC4 0x0001099C -#define CS35L41_IRQ2_EDGE1 0x00010A10 -#define CS35L41_IRQ2_EDGE4 0x00010A1C -#define CS35L41_IRQ2_POL1 0x00010A90 -#define CS35L41_IRQ2_POL2 0x00010A94 -#define CS35L41_IRQ2_POL3 0x00010A98 -#define CS35L41_IRQ2_POL4 0x00010A9C -#define CS35L41_IRQ2_DB3 0x00010B18 -#define CS35L41_GPIO_STATUS1 0x00011000 -#define CS35L41_GPIO1_CTRL1 0x00011008 -#define CS35L41_GPIO2_CTRL1 0x0001100C -#define CS35L41_MIXER_NGATE_CFG 0x00012000 -#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 -#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 -#define CS35L41_DSP_MBOX_1 0x00013000 -#define CS35L41_DSP_MBOX_2 0x00013004 -#define CS35L41_DSP_MBOX_3 0x00013008 -#define CS35L41_DSP_MBOX_4 0x0001300C -#define CS35L41_DSP_MBOX_5 0x00013010 -#define CS35L41_DSP_MBOX_6 0x00013014 -#define CS35L41_DSP_MBOX_7 0x00013018 -#define CS35L41_DSP_MBOX_8 0x0001301C -#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 -#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 -#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 -#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C -#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 -#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 -#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 -#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C -#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 -#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 -#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 -#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C -#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 -#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 -#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 -#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C -#define CS35L41_CLOCK_DETECT_1 0x00014000 -#define CS35L41_TIMER1_CONTROL 0x00015000 -#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 -#define CS35L41_TIMER1_START_STOP 0x0001500C -#define CS35L41_TIMER1_STATUS 0x00015010 -#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 -#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 -#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C -#define CS35L41_TIMER2_CONTROL 0x00015100 -#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 -#define CS35L41_TIMER2_START_STOP 0x0001510C -#define CS35L41_TIMER2_STATUS 0x00015110 -#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 -#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 -#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C -#define CS35L41_DFT_JTAG_CONTROL 0x00016000 -#define CS35L41_DIE_STS1 0x00017040 -#define CS35L41_DIE_STS2 0x00017044 -#define CS35L41_TEMP_CAL1 0x00017048 -#define CS35L41_TEMP_CAL2 0x0001704C -#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 -#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 -#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 -#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 -#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 -#define CS35L41_DSP1_SYS_ID 0x025E0000 -#define CS35L41_DSP1_SYS_VERSION 0x025E0004 -#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 -#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C -#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 -#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 -#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 -#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 -#define CS35L41_DSP1_SYS_FEATURES 0x025E002C -#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 -#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 -#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 -#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C -#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 -#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 -#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 -#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 -#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C -#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 -#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 -#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 -#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C -#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 -#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 -#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 -#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C -#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 -#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 -#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 -#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C -#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 -#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 -#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 -#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 -#define CS35L41_DSP1_CTRL_BASE 0x02B80000 -#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 -#define CS35L41_DSP1_DEBUG 0x02B80040 -#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 -#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 -#define CS35L41_DSP1_RX1_RATE 0x02B80080 -#define CS35L41_DSP1_RX2_RATE 0x02B80088 -#define CS35L41_DSP1_RX3_RATE 0x02B80090 -#define CS35L41_DSP1_RX4_RATE 0x02B80098 -#define CS35L41_DSP1_RX5_RATE 0x02B800A0 -#define CS35L41_DSP1_RX6_RATE 0x02B800A8 -#define CS35L41_DSP1_RX7_RATE 0x02B800B0 -#define CS35L41_DSP1_RX8_RATE 0x02B800B8 -#define CS35L41_DSP1_TX1_RATE 0x02B80280 -#define CS35L41_DSP1_TX2_RATE 0x02B80288 -#define CS35L41_DSP1_TX3_RATE 0x02B80290 -#define CS35L41_DSP1_TX4_RATE 0x02B80298 -#define CS35L41_DSP1_TX5_RATE 0x02B802A0 -#define CS35L41_DSP1_TX6_RATE 0x02B802A8 -#define CS35L41_DSP1_TX7_RATE 0x02B802B0 -#define CS35L41_DSP1_TX8_RATE 0x02B802B8 -#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 -#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 -#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 -#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 -#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 -#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 -#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 -#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 -#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 -#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 -#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 -#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 -#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 -#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 -#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 -#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 -#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 -#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 -#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 -#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 -#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 -#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 -#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 -#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 -#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 -#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 -#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 -#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 -#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 -#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 -#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 -#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 -#define CS35L41_DSP1_SCRATCH1 0x02B805C0 -#define CS35L41_DSP1_SCRATCH2 0x02B805C8 -#define CS35L41_DSP1_SCRATCH3 0x02B805D0 -#define CS35L41_DSP1_SCRATCH4 0x02B805D8 -#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 -#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 -#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 -#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 -#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 -#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 -#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 -#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 -#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 -#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 -#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 -#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 -#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 -#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 -#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 -#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 -#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C -#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 -#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 -#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 -#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C -#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 -#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 -#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 -#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC -#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 -#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 -#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 -#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC -#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 -#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 -#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 -#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC -#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 -#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 -#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 -#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC -#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 -#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 -#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 -#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC -#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 -#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 -#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 -#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC -#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 -#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 -#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 -#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 -#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 -#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C -#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 -#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 -#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C -#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 -#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 -#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C -#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 -#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 -#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 -#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C -#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 -#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 -#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C -#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 -#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 -#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C -#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 -#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 -#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 -#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C -#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 -#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 -#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 -#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 -#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 -#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 -#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 -#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 -#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 -#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 -#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 -#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 -#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 -#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 -#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 -#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 -#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 -#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 -#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 -#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 -#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 -#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 -#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 -#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 -#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 -#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 -#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 -#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 -#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 -#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 -#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 -#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C -#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 -#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 -#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 -#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C -#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 -#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 -#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 -#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C -#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 -#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 -#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 -#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C -#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 -#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 -#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 -#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C -#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 -#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 -#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 -#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C -#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 -#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 -#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 -#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C -#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 -#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 -#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 -#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C -#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 -#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 -#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 -#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 -#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 -#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 -#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 -#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 -#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 -#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 -#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 -#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 -#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 -#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 -#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 -#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 -#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 -#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 -#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 -#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 -#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 -#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 -#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 -#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 -#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 -#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 -#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 -#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 -#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 -#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 -#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 -#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 -#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C -#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 -#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 -#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 -#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C -#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 -#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 -#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 -#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 -#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 -#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 -#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 -#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 -#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 -#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 -#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 -#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 -#define CS35L41_DSP1_PMEM_0 0x03800000 -#define CS35L41_DSP1_PMEM_5114 0x03804FE8 - -/*test regs for emulation bringup*/ -#define CS35L41_PLL_OVR 0x00003018 -#define CS35L41_BST_TEST_DUTY 0x00003900 -#define CS35L41_DIGPWM_IOCTRL 0x0000706C - -/*registers populated by OTP*/ -#define CS35L41_OTP_TRIM_1 0x0000208c -#define CS35L41_OTP_TRIM_2 0x00002090 -#define CS35L41_OTP_TRIM_3 0x00003010 -#define CS35L41_OTP_TRIM_4 0x0000300C -#define CS35L41_OTP_TRIM_5 0x0000394C -#define CS35L41_OTP_TRIM_6 0x00003950 -#define CS35L41_OTP_TRIM_7 0x00003954 -#define CS35L41_OTP_TRIM_8 0x00003958 -#define CS35L41_OTP_TRIM_9 0x0000395C -#define CS35L41_OTP_TRIM_10 0x0000416C -#define CS35L41_OTP_TRIM_11 0x00004160 -#define CS35L41_OTP_TRIM_12 0x00004170 -#define CS35L41_OTP_TRIM_13 0x00004360 -#define CS35L41_OTP_TRIM_14 0x00004448 -#define CS35L41_OTP_TRIM_15 0x0000444C -#define CS35L41_OTP_TRIM_16 0x00006E30 -#define CS35L41_OTP_TRIM_17 0x00006E34 -#define CS35L41_OTP_TRIM_18 0x00006E38 -#define CS35L41_OTP_TRIM_19 0x00006E3C -#define CS35L41_OTP_TRIM_20 0x00006E40 -#define CS35L41_OTP_TRIM_21 0x00006E44 -#define CS35L41_OTP_TRIM_22 0x00006E48 -#define CS35L41_OTP_TRIM_23 0x00006E4C -#define CS35L41_OTP_TRIM_24 0x00006E50 -#define CS35L41_OTP_TRIM_25 0x00006E54 -#define CS35L41_OTP_TRIM_26 0x00006E58 -#define CS35L41_OTP_TRIM_27 0x00006E5C -#define CS35L41_OTP_TRIM_28 0x00006E60 -#define CS35L41_OTP_TRIM_29 0x00006E64 -#define CS35L41_OTP_TRIM_30 0x00007418 -#define CS35L41_OTP_TRIM_31 0x0000741C -#define CS35L41_OTP_TRIM_32 0x00007434 -#define CS35L41_OTP_TRIM_33 0x00007068 -#define CS35L41_OTP_TRIM_34 0x0000410C -#define CS35L41_OTP_TRIM_35 0x0000400C -#define CS35L41_OTP_TRIM_36 0x00002030 - -#define CS35L41_OTP_SIZE_WORDS 32 -#define CS35L41_NUM_OTP_ELEM 100 -#define CS35L41_NUM_OTP_MAPS 5 - -#define CS35L41_VALID_PDATA 0x80000000 -#define CS35L41_NUM_SUPPLIES 2 - -#define CS35L41_SCLK_MSTR_MASK 0x10 -#define CS35L41_SCLK_MSTR_SHIFT 4 -#define CS35L41_LRCLK_MSTR_MASK 0x01 -#define CS35L41_LRCLK_MSTR_SHIFT 0 -#define CS35L41_SCLK_INV_MASK 0x40 -#define CS35L41_SCLK_INV_SHIFT 6 -#define CS35L41_LRCLK_INV_MASK 0x04 -#define CS35L41_LRCLK_INV_SHIFT 2 -#define CS35L41_SCLK_FRC_MASK 0x20 -#define CS35L41_SCLK_FRC_SHIFT 5 -#define CS35L41_LRCLK_FRC_MASK 0x02 -#define CS35L41_LRCLK_FRC_SHIFT 1 - -#define CS35L41_AMP_GAIN_PCM_MASK 0x3E0 -#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 -#define CS35L41_AMP_GAIN_ZC_SHIFT 10 - -#define CS35L41_BST_CTL_MASK 0xFF -#define CS35L41_BST_CTL_SEL_MASK 0x03 -#define CS35L41_BST_CTL_SEL_REG 0x00 -#define CS35L41_BST_CTL_SEL_CLASSH 0x01 -#define CS35L41_BST_IPK_MASK 0x7F -#define CS35L41_BST_IPK_SHIFT 0 -#define CS35L41_BST_LIM_MASK 0x4 -#define CS35L41_BST_LIM_SHIFT 2 -#define CS35L41_BST_K1_MASK 0x000000FF -#define CS35L41_BST_K1_SHIFT 0 -#define CS35L41_BST_K2_MASK 0x0000FF00 -#define CS35L41_BST_K2_SHIFT 8 -#define CS35L41_BST_SLOPE_MASK 0x0000FF00 -#define CS35L41_BST_SLOPE_SHIFT 8 -#define CS35L41_BST_LBST_VAL_MASK 0x00000003 -#define CS35L41_BST_LBST_VAL_SHIFT 0 - -#define CS35L41_TEMP_THLD_MASK 0x03 -#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF -#define CS35L41_PDM_MODE_MASK 0x01 -#define CS35L41_PDM_MODE_SHIFT 0 - -#define CS35L41_CH_MEM_DEPTH_MASK 0x07 -#define CS35L41_CH_MEM_DEPTH_SHIFT 0 -#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 -#define CS35L41_CH_HDRM_CTL_SHIFT 16 -#define CS35L41_CH_REL_RATE_MASK 0xFF00 -#define CS35L41_CH_REL_RATE_SHIFT 8 -#define CS35L41_CH_WKFET_DLY_MASK 0x001C -#define CS35L41_CH_WKFET_DLY_SHIFT 2 -#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 -#define CS35L41_CH_WKFET_THLD_SHIFT 8 - -#define CS35L41_HW_NG_SEL_MASK 0x3F00 -#define CS35L41_HW_NG_SEL_SHIFT 8 -#define CS35L41_HW_NG_DLY_MASK 0x0070 -#define CS35L41_HW_NG_DLY_SHIFT 4 -#define CS35L41_HW_NG_THLD_MASK 0x0007 -#define CS35L41_HW_NG_THLD_SHIFT 0 - -#define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 -#define CS35L41_DSP_NG_ENABLE_SHIFT 16 -#define CS35L41_DSP_NG_THLD_MASK 0x7 -#define CS35L41_DSP_NG_THLD_SHIFT 0 -#define CS35L41_DSP_NG_DELAY_MASK 0x0F00 -#define CS35L41_DSP_NG_DELAY_SHIFT 8 - -#define CS35L41_ASP_FMT_MASK 0x0700 -#define CS35L41_ASP_FMT_SHIFT 8 -#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 -#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 -#define CS35L41_ASP_WIDTH_16 0x10 -#define CS35L41_ASP_WIDTH_24 0x18 -#define CS35L41_ASP_WIDTH_32 0x20 -#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 -#define CS35L41_ASP_WIDTH_TX_SHIFT 16 -#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 -#define CS35L41_ASP_WIDTH_RX_SHIFT 24 -#define CS35L41_ASP_RX1_SLOT_MASK 0x3F -#define CS35L41_ASP_RX1_SLOT_SHIFT 0 -#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 -#define CS35L41_ASP_RX2_SLOT_SHIFT 8 -#define CS35L41_ASP_RX_WL_MASK 0x3F -#define CS35L41_ASP_TX_WL_MASK 0x3F -#define CS35L41_ASP_RX_WL_SHIFT 0 -#define CS35L41_ASP_TX_WL_SHIFT 0 -#define CS35L41_ASP_SOURCE_MASK 0x7F - -#define CS35L41_INPUT_SRC_ASPRX1 0x08 -#define CS35L41_INPUT_SRC_ASPRX2 0x09 -#define CS35L41_INPUT_SRC_VMON 0x18 -#define CS35L41_INPUT_SRC_IMON 0x19 -#define CS35L41_INPUT_SRC_CLASSH 0x21 -#define CS35L41_INPUT_SRC_VPMON 0x28 -#define CS35L41_INPUT_SRC_VBSTMON 0x29 -#define CS35L41_INPUT_SRC_TEMPMON 0x3A -#define CS35L41_INPUT_SRC_RSVD 0x3B -#define CS35L41_INPUT_DSP_TX1 0x32 -#define CS35L41_INPUT_DSP_TX2 0x33 - -#define CS35L41_PLL_CLK_SEL_MASK 0x07 -#define CS35L41_PLL_CLK_SEL_SHIFT 0 -#define CS35L41_PLL_CLK_EN_MASK 0x10 -#define CS35L41_PLL_CLK_EN_SHIFT 4 -#define CS35L41_PLL_OPENLOOP_MASK 0x0800 -#define CS35L41_PLL_OPENLOOP_SHIFT 11 -#define CS35L41_PLLSRC_SCLK 0 -#define CS35L41_PLLSRC_LRCLK 1 -#define CS35L41_PLLSRC_SELF 3 -#define CS35L41_PLLSRC_PDMCLK 4 -#define CS35L41_PLLSRC_MCLK 5 -#define CS35L41_PLLSRC_SWIRE 7 -#define CS35L41_REFCLK_FREQ_MASK 0x7E0 -#define CS35L41_REFCLK_FREQ_SHIFT 5 - -#define CS35L41_GLOBAL_FS_MASK 0x1F -#define CS35L41_GLOBAL_FS_SHIFT 0 - -#define CS35L41_GLOBAL_EN_MASK 0x01 -#define CS35L41_GLOBAL_EN_SHIFT 0 -#define CS35L41_BST_EN_MASK 0x0030 -#define CS35L41_BST_EN_SHIFT 4 -#define CS35L41_BST_EN_DEFAULT 0x2 -#define CS35L41_AMP_EN_SHIFT 0 -#define CS35L41_AMP_EN_MASK 1 - -#define CS35L41_PDN_DONE_MASK 0x00800000 -#define CS35L41_PDN_DONE_SHIFT 23 -#define CS35L41_PUP_DONE_MASK 0x01000000 -#define CS35L41_PUP_DONE_SHIFT 24 - -#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F -#define CS35L36_PUP_DONE_IRQ_MASK 0xBF - -#define CS35L41_AMP_SHORT_ERR 0x80000000 -#define CS35L41_BST_SHORT_ERR 0x0100 -#define CS35L41_TEMP_WARN 0x8000 -#define CS35L41_TEMP_ERR 0x00020000 -#define CS35L41_BST_OVP_ERR 0x40 -#define CS35L41_BST_DCM_UVP_ERR 0x80 -#define CS35L41_OTP_BOOT_DONE 0x02 -#define CS35L41_PLL_UNLOCK 0x10 -#define CS35L41_OTP_BOOT_ERR 0x80000000 - -#define CS35L41_AMP_SHORT_ERR_RLS 0x02 -#define CS35L41_BST_SHORT_ERR_RLS 0x04 -#define CS35L41_BST_OVP_ERR_RLS 0x08 -#define CS35L41_BST_UVP_ERR_RLS 0x10 -#define CS35L41_TEMP_WARN_ERR_RLS 0x20 -#define CS35L41_TEMP_ERR_RLS 0x40 - -#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F -#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF -#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF - -#define CS35L41_GPIO_DIR_MASK 0x80000000 -#define CS35L41_GPIO_DIR_SHIFT 31 -#define CS35L41_GPIO1_CTRL_MASK 0x00030000 -#define CS35L41_GPIO1_CTRL_SHIFT 16 -#define CS35L41_GPIO2_CTRL_MASK 0x07000000 -#define CS35L41_GPIO2_CTRL_SHIFT 24 -#define CS35L41_GPIO_CTRL_OPEN_INT 2 -#define CS35L41_GPIO_CTRL_ACTV_LO 4 -#define CS35L41_GPIO_CTRL_ACTV_HI 5 -#define CS35L41_GPIO_POL_MASK 0x1000 -#define CS35L41_GPIO_POL_SHIFT 12 - -#define CS35L41_AMP_INV_PCM_SHIFT 14 -#define CS35L41_AMP_INV_PCM_MASK BIT(CS35L41_AMP_INV_PCM_SHIFT) -#define CS35L41_AMP_PCM_VOL_SHIFT 3 -#define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) -#define CS35L41_AMP_PCM_VOL_MUTE 0x4CF - -#define CS35L41_CHIP_ID 0x35a40 -#define CS35L41R_CHIP_ID 0x35b40 -#define CS35L41_MTLREVID_MASK 0x0F -#define CS35L41_REVID_A0 0xA0 -#define CS35L41_REVID_B0 0xB0 -#define CS35L41_REVID_B2 0xB2 - -#define CS35L41_HALO_CORE_RESET 0x00000200 - -#define CS35L41_FS1_WINDOW_MASK 0x000007FF -#define CS35L41_FS2_WINDOW_MASK 0x00FFF800 -#define CS35L41_FS2_WINDOW_SHIFT 12 - -#define CS35L41_SPI_MAX_FREQ 4000000 - #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) -extern struct regmap_config cs35l41_regmap_i2c; -extern struct regmap_config cs35l41_regmap_spi; - -struct cs35l41_otp_packed_element_t { - u32 reg; - u8 shift; - u8 size; -}; - -struct cs35l41_otp_map_element_t { - u32 id; - u32 num_elements; - const struct cs35l41_otp_packed_element_t *map; - u32 bit_offset; - u32 word_offset; -}; - -extern const struct cs35l41_otp_map_element_t - cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; - -#define CS35L41_REGSTRIDE 4 - enum cs35l41_cspl_mbox_status { CSPL_MBOX_STS_RUNNING = 0, CSPL_MBOX_STS_PAUSED = 1, -- cgit v1.2.3-70-g09d2 From fe120d4cb6f6cd03007239e7c578b8703fe6d336 Mon Sep 17 00:00:00 2001 From: Lucas Tanure <tanureal@opensource.cirrus.com> Date: Fri, 17 Dec 2021 11:57:00 +0000 Subject: ASoC: cs35l41: Move cs35l41_otp_unpack to shared code ASoC and HDA will do the same cs35l41_otp_unpack, so move it to shared code Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211217115708.882525-3-tanureal@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/cs35l41.h | 4 +- sound/soc/codecs/cs35l41-lib.c | 121 ++++++++++++++++++++++++++++++++++++++- sound/soc/codecs/cs35l41.c | 125 +---------------------------------------- 3 files changed, 122 insertions(+), 128 deletions(-) (limited to 'include') diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index aac3ffb9bc89..6cf3ef02b26a 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -534,7 +534,6 @@ #define CS35L41_MAX_CACHE_REG 36 #define CS35L41_OTP_SIZE_WORDS 32 #define CS35L41_NUM_OTP_ELEM 100 -#define CS35L41_NUM_OTP_MAPS 5 #define CS35L41_VALID_PDATA 0x80000000 #define CS35L41_NUM_SUPPLIES 2 @@ -760,8 +759,9 @@ struct cs35l41_otp_map_element_t { u32 word_offset; }; -extern const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; extern struct regmap_config cs35l41_regmap_i2c; extern struct regmap_config cs35l41_regmap_spi; +int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); + #endif /* __CS35L41_H */ diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index f19531ebf729..dc5f502447a2 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -7,8 +7,11 @@ // Author: David Rhodes <david.rhodes@cirrus.com> // Author: Lucas Tanure <lucas.tanure@cirrus.com> +#include <linux/dev_printk.h> #include <linux/module.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/cs35l41.h> @@ -655,7 +658,7 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ }; -const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { +static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { { .id = 0x01, .map = otp_map_1, @@ -692,7 +695,6 @@ const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] .word_offset = 2, }, }; -EXPORT_SYMBOL_GPL(cs35l41_otp_map_map); struct regmap_config cs35l41_regmap_i2c = { .reg_bits = 32, @@ -727,6 +729,121 @@ struct regmap_config cs35l41_regmap_spi = { }; EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); +static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { + if (cs35l41_otp_map_map[i].id == otp_id) + return &cs35l41_otp_map_map[i]; + } + + return NULL; +} + +int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) +{ + const struct cs35l41_otp_map_element_t *otp_map_match; + const struct cs35l41_otp_packed_element_t *otp_map; + int bit_offset, word_offset, ret, i; + unsigned int bit_sum = 8; + u32 otp_val, otp_id_reg; + u32 *otp_mem; + + otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL); + if (!otp_mem) + return -ENOMEM; + + ret = regmap_read(regmap, CS35L41_OTPID, &otp_id_reg); + if (ret) { + dev_err(dev, "Read OTP ID failed: %d\n", ret); + goto err_otp_unpack; + } + + otp_map_match = cs35l41_find_otp_map(otp_id_reg); + + if (!otp_map_match) { + dev_err(dev, "OTP Map matching ID %d not found\n", otp_id_reg); + ret = -EINVAL; + goto err_otp_unpack; + } + + ret = regmap_bulk_read(regmap, CS35L41_OTP_MEM0, otp_mem, CS35L41_OTP_SIZE_WORDS); + if (ret) { + dev_err(dev, "Read OTP Mem failed: %d\n", ret); + goto err_otp_unpack; + } + + otp_map = otp_map_match->map; + + bit_offset = otp_map_match->bit_offset; + word_offset = otp_map_match->word_offset; + + ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + if (ret) { + dev_err(dev, "Write Unlock key failed 1/2: %d\n", ret); + goto err_otp_unpack; + } + ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + if (ret) { + dev_err(dev, "Write Unlock key failed 2/2: %d\n", ret); + goto err_otp_unpack; + } + + for (i = 0; i < otp_map_match->num_elements; i++) { + dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", + bit_offset, word_offset, bit_sum % 32); + if (bit_offset + otp_map[i].size - 1 >= 32) { + otp_val = (otp_mem[word_offset] & + GENMASK(31, bit_offset)) >> bit_offset; + otp_val |= (otp_mem[++word_offset] & + GENMASK(bit_offset + otp_map[i].size - 33, 0)) << + (32 - bit_offset); + bit_offset += otp_map[i].size - 32; + } else { + otp_val = (otp_mem[word_offset] & + GENMASK(bit_offset + otp_map[i].size - 1, bit_offset) + ) >> bit_offset; + bit_offset += otp_map[i].size; + } + bit_sum += otp_map[i].size; + + if (bit_offset == 32) { + bit_offset = 0; + word_offset++; + } + + if (otp_map[i].reg != 0) { + ret = regmap_update_bits(regmap, otp_map[i].reg, + GENMASK(otp_map[i].shift + otp_map[i].size - 1, + otp_map[i].shift), + otp_val << otp_map[i].shift); + if (ret < 0) { + dev_err(dev, "Write OTP val failed: %d\n", ret); + goto err_otp_unpack; + } + } + } + + ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + if (ret) { + dev_err(dev, "Write Lock key failed 1/2: %d\n", ret); + goto err_otp_unpack; + } + ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + if (ret) { + dev_err(dev, "Write Lock key failed 2/2: %d\n", ret); + goto err_otp_unpack; + } + ret = 0; + +err_otp_unpack: + kfree(otp_mem); + + return ret; +} +EXPORT_SYMBOL_GPL(cs35l41_otp_unpack); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 60332eae1162..aa57c59b334d 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -14,7 +14,6 @@ #include <linux/moduleparam.h> #include <linux/of_device.h> #include <linux/property.h> -#include <linux/slab.h> #include <sound/initval.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -420,128 +419,6 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { WM_ADSP_FW_CONTROL("DSP1", 0), }; -static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { - if (cs35l41_otp_map_map[i].id == otp_id) - return &cs35l41_otp_map_map[i]; - } - - return NULL; -} - -static int cs35l41_otp_unpack(void *data) -{ - const struct cs35l41_otp_map_element_t *otp_map_match; - const struct cs35l41_otp_packed_element_t *otp_map; - struct cs35l41_private *cs35l41 = data; - int bit_offset, word_offset, ret, i; - unsigned int bit_sum = 8; - u32 otp_val, otp_id_reg; - u32 *otp_mem; - - otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL); - if (!otp_mem) - return -ENOMEM; - - ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); - if (ret < 0) { - dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret); - goto err_otp_unpack; - } - - otp_map_match = cs35l41_find_otp_map(otp_id_reg); - - if (!otp_map_match) { - dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", - otp_id_reg); - ret = -EINVAL; - goto err_otp_unpack; - } - - ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, - CS35L41_OTP_SIZE_WORDS); - if (ret < 0) { - dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret); - goto err_otp_unpack; - } - - otp_map = otp_map_match->map; - - bit_offset = otp_map_match->bit_offset; - word_offset = otp_map_match->word_offset; - - ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); - if (ret < 0) { - dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret); - goto err_otp_unpack; - } - ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); - if (ret < 0) { - dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret); - goto err_otp_unpack; - } - - for (i = 0; i < otp_map_match->num_elements; i++) { - dev_dbg(cs35l41->dev, - "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", - bit_offset, word_offset, bit_sum % 32); - if (bit_offset + otp_map[i].size - 1 >= 32) { - otp_val = (otp_mem[word_offset] & - GENMASK(31, bit_offset)) >> - bit_offset; - otp_val |= (otp_mem[++word_offset] & - GENMASK(bit_offset + - otp_map[i].size - 33, 0)) << - (32 - bit_offset); - bit_offset += otp_map[i].size - 32; - } else { - otp_val = (otp_mem[word_offset] & - GENMASK(bit_offset + otp_map[i].size - 1, - bit_offset)) >> bit_offset; - bit_offset += otp_map[i].size; - } - bit_sum += otp_map[i].size; - - if (bit_offset == 32) { - bit_offset = 0; - word_offset++; - } - - if (otp_map[i].reg != 0) { - ret = regmap_update_bits(cs35l41->regmap, - otp_map[i].reg, - GENMASK(otp_map[i].shift + - otp_map[i].size - 1, - otp_map[i].shift), - otp_val << otp_map[i].shift); - if (ret < 0) { - dev_err(cs35l41->dev, "Write OTP val failed: %d\n", - ret); - goto err_otp_unpack; - } - } - } - - ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); - if (ret < 0) { - dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret); - goto err_otp_unpack; - } - ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); - if (ret < 0) { - dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret); - goto err_otp_unpack; - } - ret = 0; - -err_otp_unpack: - kfree(otp_mem); - return ret; -} - static irqreturn_t cs35l41_irq(int irq, void *data) { struct cs35l41_private *cs35l41 = data; @@ -1667,7 +1544,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, goto err; } - ret = cs35l41_otp_unpack(cs35l41); + ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); if (ret < 0) { dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); goto err; -- cgit v1.2.3-70-g09d2 From 8b2278604b6de27329ec7ed82ca696c4751111b6 Mon Sep 17 00:00:00 2001 From: Lucas Tanure <tanureal@opensource.cirrus.com> Date: Fri, 17 Dec 2021 11:57:02 +0000 Subject: ASoC: cs35l41: Create shared function for errata patches ASoC and HDA systems require the same errata patches, so move it to the shared code using a function the correctly applies the patches by revision Also, move CS35L41_DSP1_CCM_CORE_CTRL write to errata patch function as is required to be written at boot, but not in regmap_register_patch sequence as will affect waking up from hibernation Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211217115708.882525-5-tanureal@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/cs35l41.h | 1 + sound/soc/codecs/cs35l41-lib.c | 89 ++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41.c | 92 ++---------------------------------------- 3 files changed, 93 insertions(+), 89 deletions(-) (limited to 'include') diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 6cf3ef02b26a..ad2e32a12b8c 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -763,5 +763,6 @@ extern struct regmap_config cs35l41_regmap_i2c; extern struct regmap_config cs35l41_regmap_spi; int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); +int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid); #endif /* __CS35L41_H */ diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index b3567e10adc4..5e382eaea340 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -659,6 +659,57 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ }; +static const struct reg_sequence cs35l41_reva0_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { 0x00003854, 0x05180240 }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, + { 0x00003014, 0x0200EE0E }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { 0x00000054, 0x00000004 }, + { CS35L41_IRQ1_DB3, 0x00000000 }, + { CS35L41_IRQ2_DB3, 0x00000000 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, +}; + +static const struct reg_sequence cs35l41_revb0_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, +}; + +static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, +}; + static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { { .id = 0x01, @@ -845,6 +896,44 @@ err_otp_unpack: } EXPORT_SYMBOL_GPL(cs35l41_otp_unpack); +int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid) +{ + char *rev; + int ret; + + switch (reg_revid) { + case CS35L41_REVID_A0: + ret = regmap_register_patch(reg, cs35l41_reva0_errata_patch, + ARRAY_SIZE(cs35l41_reva0_errata_patch)); + rev = "A0"; + break; + case CS35L41_REVID_B0: + ret = regmap_register_patch(reg, cs35l41_revb0_errata_patch, + ARRAY_SIZE(cs35l41_revb0_errata_patch)); + rev = "B0"; + break; + case CS35L41_REVID_B2: + ret = regmap_register_patch(reg, cs35l41_revb2_errata_patch, + ARRAY_SIZE(cs35l41_revb2_errata_patch)); + rev = "B2"; + break; + default: + ret = -EINVAL; + rev = "XX"; + break; + } + + if (ret) + dev_err(dev, "Failed to apply %s errata patch: %d\n", rev, ret); + + ret = regmap_write(reg, CS35L41_DSP1_CCM_CORE_CTRL, 0); + if (ret < 0) + dev_err(dev, "Write CCM_CORE_CTRL failed: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(cs35l41_register_errata_patch); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 7494710ae6e6..afc10f7ca65e 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -1271,57 +1271,6 @@ static int cs35l41_handle_pdata(struct device *dev, return 0; } -static const struct reg_sequence cs35l41_reva0_errata_patch[] = { - { 0x00000040, 0x00005555 }, - { 0x00000040, 0x0000AAAA }, - { 0x00003854, 0x05180240 }, - { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, - { 0x00004310, 0x00000000 }, - { CS35L41_VPVBST_FS_SEL, 0x00000000 }, - { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, - { 0x00003014, 0x0200EE0E }, - { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, - { 0x00000054, 0x00000004 }, - { CS35L41_IRQ1_DB3, 0x00000000 }, - { CS35L41_IRQ2_DB3, 0x00000000 }, - { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, - { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, - { 0x00000040, 0x0000CCCC }, - { 0x00000040, 0x00003333 }, - { CS35L41_PWR_CTRL2, 0x00000000 }, - { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, -}; - -static const struct reg_sequence cs35l41_revb0_errata_patch[] = { - { 0x00000040, 0x00005555 }, - { 0x00000040, 0x0000AAAA }, - { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, - { 0x00004310, 0x00000000 }, - { CS35L41_VPVBST_FS_SEL, 0x00000000 }, - { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, - { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, - { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, - { 0x00000040, 0x0000CCCC }, - { 0x00000040, 0x00003333 }, - { CS35L41_PWR_CTRL2, 0x00000000 }, - { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, -}; - -static const struct reg_sequence cs35l41_revb2_errata_patch[] = { - { 0x00000040, 0x00005555 }, - { 0x00000040, 0x0000AAAA }, - { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, - { 0x00004310, 0x00000000 }, - { CS35L41_VPVBST_FS_SEL, 0x00000000 }, - { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, - { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, - { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, - { 0x00000040, 0x0000CCCC }, - { 0x00000040, 0x00003333 }, - { CS35L41_PWR_CTRL2, 0x00000000 }, - { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, -}; - static const struct reg_sequence cs35l41_fs_errata_patch[] = { { CS35L41_DSP1_RX1_RATE, 0x00000001 }, { CS35L41_DSP1_RX2_RATE, 0x00000001 }, @@ -1501,38 +1450,9 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, goto err; } - switch (reg_revid) { - case CS35L41_REVID_A0: - ret = regmap_register_patch(cs35l41->regmap, - cs35l41_reva0_errata_patch, - ARRAY_SIZE(cs35l41_reva0_errata_patch)); - if (ret < 0) { - dev_err(cs35l41->dev, - "Failed to apply A0 errata patch: %d\n", ret); - goto err; - } - break; - case CS35L41_REVID_B0: - ret = regmap_register_patch(cs35l41->regmap, - cs35l41_revb0_errata_patch, - ARRAY_SIZE(cs35l41_revb0_errata_patch)); - if (ret < 0) { - dev_err(cs35l41->dev, - "Failed to apply B0 errata patch: %d\n", ret); - goto err; - } - break; - case CS35L41_REVID_B2: - ret = regmap_register_patch(cs35l41->regmap, - cs35l41_revb2_errata_patch, - ARRAY_SIZE(cs35l41_revb2_errata_patch)); - if (ret < 0) { - dev_err(cs35l41->dev, - "Failed to apply B2 errata patch: %d\n", ret); - goto err; - } - break; - } + ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); + if (ret) + goto err; irq_pol = cs35l41_irq_gpio_config(cs35l41); @@ -1556,12 +1476,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, goto err; } - ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0); - if (ret < 0) { - dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret); - goto err; - } - ret = cs35l41_set_pdata(cs35l41); if (ret < 0) { dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret); -- cgit v1.2.3-70-g09d2 From 3bc3e3da657f17c14df8ae8fab58183407bd7521 Mon Sep 17 00:00:00 2001 From: Lucas Tanure <tanureal@opensource.cirrus.com> Date: Fri, 17 Dec 2021 11:57:03 +0000 Subject: ASoC: cs35l41: Create shared function for setting channels ASoC and HDA will use the same register to set channels for the device Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211217115708.882525-6-tanureal@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/cs35l41.h | 3 +++ sound/soc/codecs/cs35l41-lib.c | 32 ++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41.c | 30 +++--------------------------- 3 files changed, 38 insertions(+), 27 deletions(-) (limited to 'include') diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index ad2e32a12b8c..39d150f61382 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -764,5 +764,8 @@ extern struct regmap_config cs35l41_regmap_spi; int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid); +int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); #endif /* __CS35L41_H */ diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 5e382eaea340..afcec715374d 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -934,6 +934,38 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign } EXPORT_SYMBOL_GPL(cs35l41_register_errata_patch); +int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + unsigned int val, mask; + int i; + + if (tx_num > 4 || rx_num > 2) + return -EINVAL; + + val = 0; + mask = 0; + for (i = 0; i < rx_num; i++) { + dev_dbg(dev, "rx slot %d position = %d\n", i, rx_slot[i]); + val |= rx_slot[i] << (i * 8); + mask |= 0x3F << (i * 8); + } + regmap_update_bits(reg, CS35L41_SP_FRAME_RX_SLOT, mask, val); + + val = 0; + mask = 0; + for (i = 0; i < tx_num; i++) { + dev_dbg(dev, "tx slot %d position = %d\n", i, tx_slot[i]); + val |= tx_slot[i] << (i * 8); + mask |= 0x3F << (i * 8); + } + regmap_update_bits(reg, CS35L41_SP_FRAME_TX_SLOT, mask, val); + + return 0; +} +EXPORT_SYMBOL_GPL(cs35l41_set_channels); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index afc10f7ca65e..88d6e77fdb50 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -751,36 +751,12 @@ static const struct cs_dsp_region cs35l41_dsp1_regions[] = { {. type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0}, }; -static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, - unsigned int *tx_slot, unsigned int rx_num, - unsigned int *rx_slot) +static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_n, + unsigned int *tx_slot, unsigned int rx_n, unsigned int *rx_slot) { struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); - unsigned int val, mask; - int i; - - if (tx_num > 4 || rx_num > 2) - return -EINVAL; - val = 0; - mask = 0; - for (i = 0; i < rx_num; i++) { - dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]); - val |= rx_slot[i] << (i * 8); - mask |= 0x3F << (i * 8); - } - regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val); - - val = 0; - mask = 0; - for (i = 0; i < tx_num; i++) { - dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]); - val |= tx_slot[i] << (i * 8); - mask |= 0x3F << (i * 8); - } - regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val); - - return 0; + return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_n, tx_slot, rx_n, rx_slot); } static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) -- cgit v1.2.3-70-g09d2 From e8e4fcc047c6e0c5411faeb8cc29aed2e5036a00 Mon Sep 17 00:00:00 2001 From: Lucas Tanure <tanureal@opensource.cirrus.com> Date: Fri, 17 Dec 2021 11:57:04 +0000 Subject: ASoC: cs35l41: Create shared function for boost configuration ASoC and HDA will use the same registers to configure internal boost for the device Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211217115708.882525-7-tanureal@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- include/sound/cs35l41.h | 2 + sound/soc/codecs/cs35l41-lib.c | 98 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41.c | 105 +---------------------------------------- 3 files changed, 102 insertions(+), 103 deletions(-) (limited to 'include') diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 39d150f61382..29a527457b48 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -767,5 +767,7 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign int cs35l41_set_channels(struct device *dev, struct regmap *reg, unsigned int tx_num, unsigned int *tx_slot, unsigned int rx_num, unsigned int *rx_slot); +int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, + int boost_ipk); #endif /* __CS35L41_H */ diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index afcec715374d..d026c5e3a378 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -966,6 +966,104 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, } EXPORT_SYMBOL_GPL(cs35l41_set_channels); +static const unsigned char cs35l41_bst_k1_table[4][5] = { + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, + { 0x40, 0x32, 0x32, 0x4F, 0x57 }, + { 0x40, 0x32, 0x32, 0x4F, 0x57 } +}; + +static const unsigned char cs35l41_bst_k2_table[4][5] = { + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, + { 0x48, 0x49, 0x66, 0xA3, 0xEA }, + { 0x48, 0x49, 0x66, 0xA3, 0xEA } +}; + +static const unsigned char cs35l41_bst_slope_table[4] = { + 0x75, 0x6B, 0x3B, 0x28 +}; + + +int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, + int boost_ipk) +{ + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; + int ret; + + switch (boost_ind) { + case 1000: /* 1.0 uH */ + bst_lbst_val = 0; + break; + case 1200: /* 1.2 uH */ + bst_lbst_val = 1; + break; + case 1500: /* 1.5 uH */ + bst_lbst_val = 2; + break; + case 2200: /* 2.2 uH */ + bst_lbst_val = 3; + break; + default: + dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind); + return -EINVAL; + } + + switch (boost_cap) { + case 0 ... 19: + bst_cbst_range = 0; + break; + case 20 ... 50: + bst_cbst_range = 1; + break; + case 51 ... 100: + bst_cbst_range = 2; + break; + case 101 ... 200: + bst_cbst_range = 3; + break; + default: /* 201 uF and greater */ + bst_cbst_range = 4; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, + CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK, + cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] + << CS35L41_BST_K1_SHIFT | + cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] + << CS35L41_BST_K2_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost coefficients: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, + CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK, + cs35l41_bst_slope_table[bst_lbst_val] + << CS35L41_BST_SLOPE_SHIFT | + bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret); + return ret; + } + + if (boost_ipk < 1600 || boost_ipk > 4500) { + dev_err(dev, "Invalid boost inductor peak current: %d mA\n", boost_ipk); + return -EINVAL; + } + bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, CS35L41_BST_IPK_MASK, + bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(cs35l41_boost_config); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 88d6e77fdb50..d9e6e84e64d0 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -150,24 +150,6 @@ static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = { { 6144000, 16, 24 }, }; -static const unsigned char cs35l41_bst_k1_table[4][5] = { - { 0x24, 0x32, 0x32, 0x4F, 0x57 }, - { 0x24, 0x32, 0x32, 0x4F, 0x57 }, - { 0x40, 0x32, 0x32, 0x4F, 0x57 }, - { 0x40, 0x32, 0x32, 0x4F, 0x57 } -}; - -static const unsigned char cs35l41_bst_k2_table[4][5] = { - { 0x24, 0x49, 0x66, 0xA3, 0xEA }, - { 0x24, 0x49, 0x66, 0xA3, 0xEA }, - { 0x48, 0x49, 0x66, 0xA3, 0xEA }, - { 0x48, 0x49, 0x66, 0xA3, 0xEA } -}; - -static const unsigned char cs35l41_bst_slope_table[4] = { - 0x75, 0x6B, 0x3B, 0x28 -}; - static int cs35l41_get_fs_mon_config_index(int freq) { int i; @@ -992,88 +974,6 @@ static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, return 0; } -static int cs35l41_boost_config(struct cs35l41_private *cs35l41, - int boost_ind, int boost_cap, int boost_ipk) -{ - unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; - struct regmap *regmap = cs35l41->regmap; - struct device *dev = cs35l41->dev; - int ret; - - switch (boost_ind) { - case 1000: /* 1.0 uH */ - bst_lbst_val = 0; - break; - case 1200: /* 1.2 uH */ - bst_lbst_val = 1; - break; - case 1500: /* 1.5 uH */ - bst_lbst_val = 2; - break; - case 2200: /* 2.2 uH */ - bst_lbst_val = 3; - break; - default: - dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind); - return -EINVAL; - } - - switch (boost_cap) { - case 0 ... 19: - bst_cbst_range = 0; - break; - case 20 ... 50: - bst_cbst_range = 1; - break; - case 51 ... 100: - bst_cbst_range = 2; - break; - case 101 ... 200: - bst_cbst_range = 3; - break; - default: /* 201 uF and greater */ - bst_cbst_range = 4; - } - - ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, - CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK, - cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] - << CS35L41_BST_K1_SHIFT | - cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] - << CS35L41_BST_K2_SHIFT); - if (ret) { - dev_err(dev, "Failed to write boost coefficients: %d\n", ret); - return ret; - } - - ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, - CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK, - cs35l41_bst_slope_table[bst_lbst_val] - << CS35L41_BST_SLOPE_SHIFT | - bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); - if (ret) { - dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret); - return ret; - } - - if (boost_ipk < 1600 || boost_ipk > 4500) { - dev_err(dev, "Invalid boost inductor peak current: %d mA\n", - boost_ipk); - return -EINVAL; - } - bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; - - ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, - CS35L41_BST_IPK_MASK, - bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); - if (ret) { - dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret); - return ret; - } - - return 0; -} - static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) { int ret; @@ -1082,9 +982,8 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) /* Required */ if (cs35l41->pdata.bst_ipk && cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { - ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, - cs35l41->pdata.bst_cap, - cs35l41->pdata.bst_ipk); + ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->pdata.bst_ind, + cs35l41->pdata.bst_cap, cs35l41->pdata.bst_ipk); if (ret) { dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); return ret; -- cgit v1.2.3-70-g09d2