Merge existing fixes from asoc/for-5.11
This commit is contained in:
commit
984fcd3f4e
|
@ -1,4 +1,6 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2020 Texas Instruments Incorporated
|
||||
# Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/ti,j721e-cpb-audio.yaml#
|
||||
|
@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Texas Instruments J721e Common Processor Board Audio Support
|
||||
|
||||
maintainers:
|
||||
- Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
- Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
|
||||
description: |
|
||||
The audio support on the board is using pcm3168a codec connected to McASP10
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2020 Texas Instruments Incorporated
|
||||
# Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/ti,j721e-cpb-ivi-audio.yaml#
|
||||
|
@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Texas Instruments J721e Common Processor Board Audio Support
|
||||
|
||||
maintainers:
|
||||
- Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
- Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
|
||||
description: |
|
||||
The Infotainment board plugs into the Common Processor Board, the support of the
|
||||
|
|
|
@ -12850,7 +12850,7 @@ F: include/misc/ocxl*
|
|||
F: include/uapi/misc/ocxl.h
|
||||
|
||||
OMAP AUDIO SUPPORT
|
||||
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
M: Jarkko Nikula <jarkko.nikula@bitmer.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: linux-omap@vger.kernel.org
|
||||
|
@ -17541,7 +17541,7 @@ F: arch/xtensa/
|
|||
F: drivers/irqchip/irq-xtensa-*
|
||||
|
||||
TEXAS INSTRUMENTS ASoC DRIVERS
|
||||
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: sound/soc/ti/
|
||||
|
@ -17838,7 +17838,7 @@ F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt
|
|||
F: drivers/nfc/trf7970a.c
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/twl4030*
|
||||
|
|
|
@ -143,7 +143,7 @@ config SND_MCHP_SOC_SPDIFTX
|
|||
- sama7g5
|
||||
|
||||
This S/PDIF TX driver is compliant with IEC-60958 standard and
|
||||
includes programable User Data and Channel Status fields.
|
||||
includes programmable User Data and Channel Status fields.
|
||||
|
||||
config SND_MCHP_SOC_SPDIFRX
|
||||
tristate "Microchip ASoC driver for boards using S/PDIF RX"
|
||||
|
@ -157,5 +157,5 @@ config SND_MCHP_SOC_SPDIFRX
|
|||
- sama7g5
|
||||
|
||||
This S/PDIF RX driver is compliant with IEC-60958 standard and
|
||||
includes programable User Data and Channel Status fields.
|
||||
includes programmable User Data and Channel Status fields.
|
||||
endif
|
||||
|
|
|
@ -457,7 +457,7 @@ config SND_SOC_ADAU7118_HW
|
|||
help
|
||||
Enable support for the Analog Devices ADAU7118 8 Channel PDM-to-I2S/TDM
|
||||
Converter. In this mode, the device works in standalone mode which
|
||||
means that there is no bus to comunicate with it. Stereo mode is not
|
||||
means that there is no bus to communicate with it. Stereo mode is not
|
||||
supported in this mode.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
#include <sound/tlv.h>
|
||||
#include "max98373.h"
|
||||
|
||||
static const u32 max98373_i2c_cache_reg[] = {
|
||||
MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK,
|
||||
MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK,
|
||||
MAX98373_R20B6_BDE_CUR_STATE_READBACK,
|
||||
};
|
||||
|
||||
static struct reg_default max98373_reg[] = {
|
||||
{MAX98373_R2000_SW_RESET, 0x00},
|
||||
{MAX98373_R2001_INT_RAW1, 0x00},
|
||||
|
@ -472,6 +478,11 @@ static struct snd_soc_dai_driver max98373_dai[] = {
|
|||
static int max98373_suspend(struct device *dev)
|
||||
{
|
||||
struct max98373_priv *max98373 = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
||||
/* cache feedback register values before suspend */
|
||||
for (i = 0; i < max98373->cache_num; i++)
|
||||
regmap_read(max98373->regmap, max98373->cache[i].reg, &max98373->cache[i].val);
|
||||
|
||||
regcache_cache_only(max98373->regmap, true);
|
||||
regcache_mark_dirty(max98373->regmap);
|
||||
|
@ -509,6 +520,7 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
|
|||
{
|
||||
int ret = 0;
|
||||
int reg = 0;
|
||||
int i;
|
||||
struct max98373_priv *max98373 = NULL;
|
||||
|
||||
max98373 = devm_kzalloc(&i2c->dev, sizeof(*max98373), GFP_KERNEL);
|
||||
|
@ -534,6 +546,14 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
max98373->cache_num = ARRAY_SIZE(max98373_i2c_cache_reg);
|
||||
max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num,
|
||||
sizeof(*max98373->cache),
|
||||
GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < max98373->cache_num; i++)
|
||||
max98373->cache[i].reg = max98373_i2c_cache_reg[i];
|
||||
|
||||
/* voltage/current slot & gpio configuration */
|
||||
max98373_slot_config(&i2c->dev, max98373);
|
||||
|
||||
|
|
|
@ -23,6 +23,12 @@ struct sdw_stream_data {
|
|||
struct sdw_stream_runtime *sdw_stream;
|
||||
};
|
||||
|
||||
static const u32 max98373_sdw_cache_reg[] = {
|
||||
MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK,
|
||||
MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK,
|
||||
MAX98373_R20B6_BDE_CUR_STATE_READBACK,
|
||||
};
|
||||
|
||||
static struct reg_default max98373_reg[] = {
|
||||
{MAX98373_R0040_SCP_INIT_STAT_1, 0x00},
|
||||
{MAX98373_R0041_SCP_INIT_MASK_1, 0x00},
|
||||
|
@ -245,6 +251,11 @@ static const struct regmap_config max98373_sdw_regmap = {
|
|||
static __maybe_unused int max98373_suspend(struct device *dev)
|
||||
{
|
||||
struct max98373_priv *max98373 = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
||||
/* cache feedback register values before suspend */
|
||||
for (i = 0; i < max98373->cache_num; i++)
|
||||
regmap_read(max98373->regmap, max98373->cache[i].reg, &max98373->cache[i].val);
|
||||
|
||||
regcache_cache_only(max98373->regmap, true);
|
||||
|
||||
|
@ -757,6 +768,7 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
|
|||
{
|
||||
struct max98373_priv *max98373;
|
||||
int ret;
|
||||
int i;
|
||||
struct device *dev = &slave->dev;
|
||||
|
||||
/* Allocate and assign private driver data structure */
|
||||
|
@ -768,6 +780,14 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
|
|||
max98373->regmap = regmap;
|
||||
max98373->slave = slave;
|
||||
|
||||
max98373->cache_num = ARRAY_SIZE(max98373_sdw_cache_reg);
|
||||
max98373->cache = devm_kcalloc(dev, max98373->cache_num,
|
||||
sizeof(*max98373->cache),
|
||||
GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < max98373->cache_num; i++)
|
||||
max98373->cache[i].reg = max98373_sdw_cache_reg[i];
|
||||
|
||||
/* Read voltage and slot configuration */
|
||||
max98373_slot_config(dev, max98373);
|
||||
|
||||
|
|
|
@ -168,6 +168,31 @@ static SOC_ENUM_SINGLE_DECL(max98373_adc_samplerate_enum,
|
|||
MAX98373_R2051_MEAS_ADC_SAMPLING_RATE, 0,
|
||||
max98373_ADC_samplerate_text);
|
||||
|
||||
static int max98373_feedback_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
|
||||
int i;
|
||||
|
||||
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
|
||||
/*
|
||||
* Register values will be cached before suspend. The cached value
|
||||
* will be a valid value and userspace will happy with that.
|
||||
*/
|
||||
for (i = 0; i < max98373->cache_num; i++) {
|
||||
if (mc->reg == max98373->cache[i].reg) {
|
||||
ucontrol->value.integer.value[0] = max98373->cache[i].val;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return snd_soc_put_volsw(kcontrol, ucontrol);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new max98373_snd_controls[] = {
|
||||
SOC_SINGLE("Digital Vol Sel Switch", MAX98373_R203F_AMP_DSP_CFG,
|
||||
MAX98373_AMP_VOL_SEL_SHIFT, 1, 0),
|
||||
|
@ -209,8 +234,10 @@ SOC_SINGLE("ADC PVDD FLT Switch", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG,
|
|||
MAX98373_FLT_EN_SHIFT, 1, 0),
|
||||
SOC_SINGLE("ADC TEMP FLT Switch", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG,
|
||||
MAX98373_FLT_EN_SHIFT, 1, 0),
|
||||
SOC_SINGLE("ADC PVDD", MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0, 0xFF, 0),
|
||||
SOC_SINGLE("ADC TEMP", MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0, 0xFF, 0),
|
||||
SOC_SINGLE_EXT("ADC PVDD", MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0, 0xFF, 0,
|
||||
max98373_feedback_get, NULL),
|
||||
SOC_SINGLE_EXT("ADC TEMP", MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0, 0xFF, 0,
|
||||
max98373_feedback_get, NULL),
|
||||
SOC_SINGLE("ADC PVDD FLT Coeff", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG,
|
||||
0, 0x3, 0),
|
||||
SOC_SINGLE("ADC TEMP FLT Coeff", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG,
|
||||
|
@ -226,7 +253,8 @@ SOC_SINGLE("BDE LVL1 Thresh", MAX98373_R2097_BDE_L1_THRESH, 0, 0xFF, 0),
|
|||
SOC_SINGLE("BDE LVL2 Thresh", MAX98373_R2098_BDE_L2_THRESH, 0, 0xFF, 0),
|
||||
SOC_SINGLE("BDE LVL3 Thresh", MAX98373_R2099_BDE_L3_THRESH, 0, 0xFF, 0),
|
||||
SOC_SINGLE("BDE LVL4 Thresh", MAX98373_R209A_BDE_L4_THRESH, 0, 0xFF, 0),
|
||||
SOC_SINGLE("BDE Active Level", MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0, 8, 0),
|
||||
SOC_SINGLE_EXT("BDE Active Level", MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0, 8, 0,
|
||||
max98373_feedback_get, NULL),
|
||||
SOC_SINGLE("BDE Clip Mode Switch", MAX98373_R2092_BDE_CLIPPER_MODE, 0, 1, 0),
|
||||
SOC_SINGLE("BDE Thresh Hysteresis", MAX98373_R209B_BDE_THRESH_HYST, 0, 0xFF, 0),
|
||||
SOC_SINGLE("BDE Hold Time", MAX98373_R2090_BDE_LVL_HOLD, 0, 0xFF, 0),
|
||||
|
|
|
@ -203,6 +203,11 @@
|
|||
/* MAX98373_R2000_SW_RESET */
|
||||
#define MAX98373_SOFT_RESET (0x1 << 0)
|
||||
|
||||
struct max98373_cache {
|
||||
u32 reg;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
struct max98373_priv {
|
||||
struct regmap *regmap;
|
||||
int reset_gpio;
|
||||
|
@ -212,6 +217,9 @@ struct max98373_priv {
|
|||
bool interleave_mode;
|
||||
unsigned int ch_size;
|
||||
bool tdm_mode;
|
||||
/* cache for reading a valid fake feedback value */
|
||||
struct max98373_cache *cache;
|
||||
int cache_num;
|
||||
/* variables to support soundwire */
|
||||
struct sdw_slave *slave;
|
||||
bool hw_init;
|
||||
|
|
|
@ -462,6 +462,8 @@ static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol,
|
|||
unsigned int read_ll, read_rl;
|
||||
int i;
|
||||
|
||||
mutex_lock(&rt711->calibrate_mutex);
|
||||
|
||||
/* Can't use update bit function, so read the original value first */
|
||||
addr_h = mc->reg;
|
||||
addr_l = mc->rreg;
|
||||
|
@ -547,6 +549,8 @@ static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol,
|
|||
if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
|
||||
regmap_write(rt711->regmap,
|
||||
RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
|
||||
|
||||
mutex_unlock(&rt711->calibrate_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -859,9 +863,11 @@ static int rt711_set_bias_level(struct snd_soc_component *component,
|
|||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
mutex_lock(&rt711->calibrate_mutex);
|
||||
regmap_write(rt711->regmap,
|
||||
RT711_SET_AUDIO_POWER_STATE,
|
||||
AC_PWRST_D3);
|
||||
mutex_unlock(&rt711->calibrate_mutex);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -164,6 +164,7 @@ static int imx_hdmi_probe(struct platform_device *pdev)
|
|||
|
||||
if ((hdmi_out && hdmi_in) || (!hdmi_out && !hdmi_in)) {
|
||||
dev_err(&pdev->dev, "Invalid HDMI DAI link\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ static struct platform_driver haswell_audio = {
|
|||
.probe = haswell_audio_probe,
|
||||
.driver = {
|
||||
.name = "haswell-audio",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -224,6 +224,7 @@ static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
|
|||
"dsp boot timeout, status=%#x error=%#x\n",
|
||||
sst_dsp_shim_read(ctx, CNL_ADSP_FW_STATUS),
|
||||
sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE));
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -467,8 +467,20 @@ static int axg_tdm_iface_set_bias_level(struct snd_soc_component *component,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget axg_tdm_iface_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SIGGEN("Playback Signal"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route axg_tdm_iface_dapm_routes[] = {
|
||||
{ "Loopback", NULL, "Playback Signal" },
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver axg_tdm_iface_component_drv = {
|
||||
.set_bias_level = axg_tdm_iface_set_bias_level,
|
||||
.dapm_widgets = axg_tdm_iface_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(axg_tdm_iface_dapm_widgets),
|
||||
.dapm_routes = axg_tdm_iface_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(axg_tdm_iface_dapm_routes),
|
||||
.set_bias_level = axg_tdm_iface_set_bias_level,
|
||||
};
|
||||
|
||||
static const struct of_device_id axg_tdm_iface_of_match[] = {
|
||||
|
|
|
@ -224,15 +224,6 @@ static const struct axg_tdm_formatter_ops axg_tdmin_ops = {
|
|||
};
|
||||
|
||||
static const struct axg_tdm_formatter_driver axg_tdmin_drv = {
|
||||
.component_drv = &axg_tdmin_component_drv,
|
||||
.regmap_cfg = &axg_tdmin_regmap_cfg,
|
||||
.ops = &axg_tdmin_ops,
|
||||
.quirks = &(const struct axg_tdm_formatter_hw) {
|
||||
.skew_offset = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct axg_tdm_formatter_driver g12a_tdmin_drv = {
|
||||
.component_drv = &axg_tdmin_component_drv,
|
||||
.regmap_cfg = &axg_tdmin_regmap_cfg,
|
||||
.ops = &axg_tdmin_ops,
|
||||
|
@ -247,10 +238,10 @@ static const struct of_device_id axg_tdmin_of_match[] = {
|
|||
.data = &axg_tdmin_drv,
|
||||
}, {
|
||||
.compatible = "amlogic,g12a-tdmin",
|
||||
.data = &g12a_tdmin_drv,
|
||||
.data = &axg_tdmin_drv,
|
||||
}, {
|
||||
.compatible = "amlogic,sm1-tdmin",
|
||||
.data = &g12a_tdmin_drv,
|
||||
.data = &axg_tdmin_drv,
|
||||
}, {}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axg_tdmin_of_match);
|
||||
|
|
|
@ -270,18 +270,6 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
|
|||
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
|
||||
unsigned int id = dai->driver->id;
|
||||
int ret = -EINVAL;
|
||||
unsigned int val = 0;
|
||||
|
||||
ret = regmap_read(drvdata->lpaif_map,
|
||||
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), &val);
|
||||
if (ret) {
|
||||
dev_err(dai->dev, "error reading from i2sctl reg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (val == LPAIF_I2SCTL_RESET_STATE) {
|
||||
dev_err(dai->dev, "error in i2sctl register state\n");
|
||||
return -ENOTRECOVERABLE;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
|
@ -454,20 +442,16 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
|
|||
struct lpass_variant *v = drvdata->variant;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < v->i2s_ports; ++i)
|
||||
if (reg == LPAIF_I2SCTL_REG(v, i))
|
||||
return true;
|
||||
for (i = 0; i < v->irq_ports; ++i)
|
||||
if (reg == LPAIF_IRQSTAT_REG(v, i))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < v->rdma_channels; ++i)
|
||||
if (reg == LPAIF_RDMACURR_REG(v, i) || reg == LPAIF_RDMACTL_REG(v, i))
|
||||
if (reg == LPAIF_RDMACURR_REG(v, i))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < v->wrdma_channels; ++i)
|
||||
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start) ||
|
||||
reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
|
||||
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -452,7 +452,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
unsigned int reg_irqclr = 0, val_irqclr = 0;
|
||||
unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0;
|
||||
unsigned int dai_id = cpu_dai->driver->id;
|
||||
unsigned int dma_ctrl_reg = 0;
|
||||
|
||||
ch = pcm_data->dma_ch;
|
||||
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
|
@ -469,17 +468,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
id = pcm_data->dma_ch - v->wrdma_channel_start;
|
||||
map = drvdata->lpaif_map;
|
||||
}
|
||||
ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
|
||||
if (ret) {
|
||||
dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
|
||||
dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
|
||||
dev_err(soc_runtime->dev, "error in rdmactl register state\n");
|
||||
return -ENOTRECOVERABLE;
|
||||
}
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
|
@ -500,7 +489,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
"error writing to rdmactl reg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
map = drvdata->hdmiif_map;
|
||||
reg_irqclr = LPASS_HDMITX_APP_IRQCLEAR_REG(v);
|
||||
val_irqclr = (LPAIF_IRQ_ALL(ch) |
|
||||
LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
|
||||
|
@ -519,7 +507,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
break;
|
||||
case MI2S_PRIMARY:
|
||||
case MI2S_SECONDARY:
|
||||
map = drvdata->lpaif_map;
|
||||
reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
|
||||
val_irqclr = LPAIF_IRQ_ALL(ch);
|
||||
|
||||
|
@ -563,7 +550,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
"error writing to rdmactl reg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
map = drvdata->hdmiif_map;
|
||||
reg_irqen = LPASS_HDMITX_APP_IRQEN_REG(v);
|
||||
val_mask = (LPAIF_IRQ_ALL(ch) |
|
||||
LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
|
||||
|
@ -573,7 +559,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
break;
|
||||
case MI2S_PRIMARY:
|
||||
case MI2S_SECONDARY:
|
||||
map = drvdata->lpaif_map;
|
||||
reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
|
||||
val_mask = LPAIF_IRQ_ALL(ch);
|
||||
val_irqen = 0;
|
||||
|
@ -838,6 +823,39 @@ static void lpass_platform_pcm_free(struct snd_soc_component *component,
|
|||
}
|
||||
}
|
||||
|
||||
static int lpass_platform_pcmops_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
|
||||
struct regmap *map;
|
||||
unsigned int dai_id = component->id;
|
||||
|
||||
if (dai_id == LPASS_DP_RX)
|
||||
map = drvdata->hdmiif_map;
|
||||
else
|
||||
map = drvdata->lpaif_map;
|
||||
|
||||
regcache_cache_only(map, true);
|
||||
regcache_mark_dirty(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpass_platform_pcmops_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
|
||||
struct regmap *map;
|
||||
unsigned int dai_id = component->id;
|
||||
|
||||
if (dai_id == LPASS_DP_RX)
|
||||
map = drvdata->hdmiif_map;
|
||||
else
|
||||
map = drvdata->lpaif_map;
|
||||
|
||||
regcache_cache_only(map, false);
|
||||
return regcache_sync(map);
|
||||
}
|
||||
|
||||
|
||||
static const struct snd_soc_component_driver lpass_component_driver = {
|
||||
.name = DRV_NAME,
|
||||
.open = lpass_platform_pcmops_open,
|
||||
|
@ -850,6 +868,8 @@ static const struct snd_soc_component_driver lpass_component_driver = {
|
|||
.mmap = lpass_platform_pcmops_mmap,
|
||||
.pcm_construct = lpass_platform_pcm_new,
|
||||
.pcm_destruct = lpass_platform_pcm_free,
|
||||
.suspend = lpass_platform_pcmops_suspend,
|
||||
.resume = lpass_platform_pcmops_resume,
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -366,25 +366,27 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
|
|||
struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct clk *clk;
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
for_each_rsnd_clk(clk, adg, i) {
|
||||
ret = 0;
|
||||
if (enable) {
|
||||
ret = clk_prepare_enable(clk);
|
||||
int ret = clk_prepare_enable(clk);
|
||||
|
||||
/*
|
||||
* We shouldn't use clk_get_rate() under
|
||||
* atomic context. Let's keep it when
|
||||
* rsnd_adg_clk_enable() was called
|
||||
*/
|
||||
adg->clk_rate[i] = clk_get_rate(adg->clk[i]);
|
||||
adg->clk_rate[i] = 0;
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "can't use clk %d\n", i);
|
||||
else
|
||||
adg->clk_rate[i] = clk_get_rate(clk);
|
||||
} else {
|
||||
clk_disable_unprepare(clk);
|
||||
if (adg->clk_rate[i])
|
||||
clk_disable_unprepare(clk);
|
||||
adg->clk_rate[i] = 0;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "can't use clk %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2486,6 +2486,7 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w)
|
|||
enum snd_soc_dapm_direction dir;
|
||||
|
||||
list_del(&w->list);
|
||||
list_del(&w->dirty);
|
||||
/*
|
||||
* remove source and sink paths associated to this widget.
|
||||
* While removing the path, remove reference to it from both
|
||||
|
|
|
@ -122,7 +122,7 @@ config SND_SOC_SOF_DEBUG_XRUN_STOP
|
|||
bool "SOF stop on XRUN"
|
||||
help
|
||||
This option forces PCMs to stop on any XRUN event. This is useful to
|
||||
preserve any trace data ond pipeline status prior to the XRUN.
|
||||
preserve any trace data and pipeline status prior to the XRUN.
|
||||
Say Y if you are debugging SOF FW pipeline XRUNs.
|
||||
If unsure select "N".
|
||||
|
||||
|
|
Loading…
Reference in New Issue