ASoC: Fixes for v5.9
Most of this is various driver specific fixes, none of which are terribly exciting in themselves, plus one core fix adding and using a new DAI lookup function to deal with a lockdep warning. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl9bX1gTHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0F04B/44DFfhh3KELcZkIiG4CLfoLRl1g3iw EEjFHJRJkpVjKJmTGeVgUTYI6UOH4U9abMGey6s4uCZW2AEb5CGODiWlcKAfy7l2 i7XHbbJacsiJKU6ezR66azpuF+Hb5z/Z9AKfVuCDHHItXuj09A4H7V45AAd1IbEU KWdPSAcex18OgEKhYZNxBkMapsTJQl04cDUWiel7PYT7nJYxLAz46JMI2y4IJ3S8 tXed+T1IDflruk819Mn1XAxYzvOVPcNRD6hHuSUEECV/BZcLJFEHPkvnLKEjKwNe so66doBMcAGkuGoYlURh2otZWgoX56e7IYrqX5m2N1fIskSRkOeNl5J4 =WLI9 -----END PGP SIGNATURE----- Merge tag 'asoc-fix-v5.9-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Fixes for v5.9 Most of this is various driver specific fixes, none of which are terribly exciting in themselves, plus one core fix adding and using a new DAI lookup function to deal with a lockdep warning.
This commit is contained in:
commit
8949b6660c
@ -1193,6 +1193,8 @@ struct snd_soc_pcm_runtime {
|
||||
((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \
|
||||
((dai) = (rtd)->dais[i]); \
|
||||
(i)++)
|
||||
#define for_each_rtd_dais_rollback(rtd, i, dai) \
|
||||
for (; (--(i) >= 0) && ((dai) = (rtd)->dais[i]);)
|
||||
|
||||
void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd);
|
||||
|
||||
@ -1361,6 +1363,8 @@ void snd_soc_unregister_dai(struct snd_soc_dai *dai);
|
||||
|
||||
struct snd_soc_dai *snd_soc_find_dai(
|
||||
const struct snd_soc_dai_link_component *dlc);
|
||||
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
|
||||
const struct snd_soc_dai_link_component *dlc);
|
||||
|
||||
#include <sound/soc-dai.h>
|
||||
|
||||
|
@ -838,8 +838,8 @@ static int max98373_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
/* Regmap Initialization */
|
||||
regmap = devm_regmap_init_sdw(slave, &max98373_sdw_regmap);
|
||||
if (!regmap)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
return max98373_init(slave, regmap);
|
||||
}
|
||||
|
@ -306,6 +306,13 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Some sound card sets 0 Hz as reset,
|
||||
* but it is impossible to set. Ignore it here
|
||||
*/
|
||||
if (freq == 0)
|
||||
return 0;
|
||||
|
||||
if (freq > PCM3168A_MAX_SYSCLK)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -684,8 +684,8 @@ static int rt1308_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
/* Regmap Initialization */
|
||||
regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap);
|
||||
if (!regmap)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
rt1308_sdw_init(&slave->dev, regmap, slave);
|
||||
|
||||
|
@ -452,8 +452,8 @@ static int rt700_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
/* Regmap Initialization */
|
||||
sdw_regmap = devm_regmap_init_sdw(slave, &rt700_sdw_regmap);
|
||||
if (!sdw_regmap)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(sdw_regmap))
|
||||
return PTR_ERR(sdw_regmap);
|
||||
|
||||
regmap = devm_regmap_init(&slave->dev, NULL,
|
||||
&slave->dev, &rt700_regmap);
|
||||
|
@ -452,8 +452,8 @@ static int rt711_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
/* Regmap Initialization */
|
||||
sdw_regmap = devm_regmap_init_sdw(slave, &rt711_sdw_regmap);
|
||||
if (!sdw_regmap)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(sdw_regmap))
|
||||
return PTR_ERR(sdw_regmap);
|
||||
|
||||
regmap = devm_regmap_init(&slave->dev, NULL,
|
||||
&slave->dev, &rt711_regmap);
|
||||
|
@ -527,8 +527,8 @@ static int rt715_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
/* Regmap Initialization */
|
||||
sdw_regmap = devm_regmap_init_sdw(slave, &rt715_sdw_regmap);
|
||||
if (!sdw_regmap)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(sdw_regmap))
|
||||
return PTR_ERR(sdw_regmap);
|
||||
|
||||
regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev,
|
||||
&rt715_regmap);
|
||||
|
@ -842,6 +842,18 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (adcx140->supply_areg == NULL)
|
||||
sleep_cfg_val |= ADCX140_AREG_INTERNAL;
|
||||
|
||||
ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val);
|
||||
if (ret) {
|
||||
dev_err(adcx140->dev, "setting sleep config failed %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 8.4.3: Wait >= 1ms after entering active mode. */
|
||||
usleep_range(1000, 100000);
|
||||
|
||||
pdm_count = device_property_count_u32(adcx140->dev,
|
||||
"ti,pdm-edge-select");
|
||||
if (pdm_count <= ADCX140_NUM_PDM_EDGES && pdm_count > 0) {
|
||||
@ -889,18 +901,6 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (adcx140->supply_areg == NULL)
|
||||
sleep_cfg_val |= ADCX140_AREG_INTERNAL;
|
||||
|
||||
ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val);
|
||||
if (ret) {
|
||||
dev_err(adcx140->dev, "setting sleep config failed %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 8.4.3: Wait >= 1ms after entering active mode. */
|
||||
usleep_range(1000, 100000);
|
||||
|
||||
ret = regmap_update_bits(adcx140->regmap, ADCX140_BIAS_CFG,
|
||||
ADCX140_MIC_BIAS_VAL_MSK |
|
||||
ADCX140_MIC_BIAS_VREF_MSK, bias_cfg);
|
||||
@ -980,6 +980,8 @@ static int adcx140_i2c_probe(struct i2c_client *i2c,
|
||||
if (!adcx140)
|
||||
return -ENOMEM;
|
||||
|
||||
adcx140->dev = &i2c->dev;
|
||||
|
||||
adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev,
|
||||
"reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(adcx140->gpio_reset))
|
||||
@ -1007,7 +1009,7 @@ static int adcx140_i2c_probe(struct i2c_client *i2c,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
adcx140->dev = &i2c->dev;
|
||||
|
||||
i2c_set_clientdata(i2c, adcx140);
|
||||
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
|
@ -3514,6 +3514,8 @@ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(component->dev);
|
||||
|
||||
switch (micbias) {
|
||||
case 1:
|
||||
micdet = &wm8994->micdet[0];
|
||||
@ -3561,6 +3563,8 @@ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *
|
||||
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
pm_runtime_put(component->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wm8994_mic_detect);
|
||||
@ -3932,6 +3936,8 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(component->dev);
|
||||
|
||||
if (jack) {
|
||||
snd_soc_dapm_force_enable_pin(dapm, "CLK_SYS");
|
||||
snd_soc_dapm_sync(dapm);
|
||||
@ -4000,6 +4006,8 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *
|
||||
snd_soc_dapm_sync(dapm);
|
||||
}
|
||||
|
||||
pm_runtime_put(component->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wm8958_mic_detect);
|
||||
@ -4193,11 +4201,13 @@ static int wm8994_component_probe(struct snd_soc_component *component)
|
||||
wm8994->hubs.dcs_readback_mode = 2;
|
||||
break;
|
||||
}
|
||||
wm8994->hubs.micd_scthr = true;
|
||||
break;
|
||||
|
||||
case WM8958:
|
||||
wm8994->hubs.dcs_readback_mode = 1;
|
||||
wm8994->hubs.hp_startup_mode = 1;
|
||||
wm8994->hubs.micd_scthr = true;
|
||||
|
||||
switch (control->revision) {
|
||||
case 0:
|
||||
|
@ -1223,6 +1223,9 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_component *component,
|
||||
snd_soc_component_update_bits(component, WM8993_ADDITIONAL_CONTROL,
|
||||
WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
|
||||
|
||||
if (!hubs->micd_scthr)
|
||||
return 0;
|
||||
|
||||
snd_soc_component_update_bits(component, WM8993_MICBIAS,
|
||||
WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
|
||||
WM8993_MICB1_LVL | WM8993_MICB2_LVL,
|
||||
|
@ -27,6 +27,7 @@ struct wm_hubs_data {
|
||||
int hp_startup_mode;
|
||||
int series_startup;
|
||||
int no_series_update;
|
||||
bool micd_scthr;
|
||||
|
||||
bool no_cache_dac_hp_direct;
|
||||
struct list_head dcs_cache;
|
||||
|
@ -333,6 +333,17 @@ static int sst_media_open(struct snd_pcm_substream *substream,
|
||||
if (ret_val < 0)
|
||||
goto out_power_up;
|
||||
|
||||
/*
|
||||
* Make sure the period to be multiple of 1ms to align the
|
||||
* design of firmware. Apply same rule to buffer size to make
|
||||
* sure alsa could always find a value for period size
|
||||
* regardless the buffer size given by user space.
|
||||
*/
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 48);
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 48);
|
||||
|
||||
/* Make sure, that the period size is always even */
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIODS, 2);
|
||||
|
@ -591,6 +591,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
||||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"),
|
||||
},
|
||||
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
|
||||
BYT_RT5640_MONO_SPEAKER |
|
||||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{
|
||||
/* MPMAN MPWIN895CL */
|
||||
.matches = {
|
||||
|
@ -181,7 +181,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card)
|
||||
struct snd_soc_dai *dai;
|
||||
|
||||
for_each_card_rtds(card, rtd) {
|
||||
if (!strstr(rtd->dai_link->codecs->name, "ehdaudio"))
|
||||
if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0"))
|
||||
continue;
|
||||
dai = asoc_rtd_to_codec(rtd, 0);
|
||||
hda_pvt = snd_soc_component_get_drvdata(dai->component);
|
||||
|
@ -66,6 +66,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
int j;
|
||||
int ret = 0;
|
||||
|
||||
/* set spk pin by playback only */
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
return 0;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, j, codec_dai) {
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
struct snd_soc_dapm_context *dapm =
|
||||
@ -86,9 +90,6 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
/* Make sure no streams are active before disable pin */
|
||||
if (snd_soc_dai_active(codec_dai) != 1)
|
||||
break;
|
||||
ret = snd_soc_dapm_disable_pin(dapm, pin_name);
|
||||
if (!ret)
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
@ -243,92 +243,45 @@ static irqreturn_t hsw_irq(int irq, void *context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define CSR_DEFAULT_VALUE 0x8480040E
|
||||
#define ISC_DEFAULT_VALUE 0x0
|
||||
#define ISD_DEFAULT_VALUE 0x0
|
||||
#define IMC_DEFAULT_VALUE 0x7FFF0003
|
||||
#define IMD_DEFAULT_VALUE 0x7FFF0003
|
||||
#define IPCC_DEFAULT_VALUE 0x0
|
||||
#define IPCD_DEFAULT_VALUE 0x0
|
||||
#define CLKCTL_DEFAULT_VALUE 0x7FF
|
||||
#define CSR2_DEFAULT_VALUE 0x0
|
||||
#define LTR_CTRL_DEFAULT_VALUE 0x0
|
||||
#define HMD_CTRL_DEFAULT_VALUE 0x0
|
||||
|
||||
static void hsw_set_shim_defaults(struct sst_dsp *sst)
|
||||
{
|
||||
sst_dsp_shim_write_unlocked(sst, SST_CSR, CSR_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_ISRX, ISC_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_ISRD, ISD_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IMRX, IMC_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IMRD, IMD_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IPCX, IPCC_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IPCD, IPCD_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_CLKCTL, CLKCTL_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_CSR2, CSR2_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_LTRC, LTR_CTRL_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_HMDC, HMD_CTRL_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
/* all clock-gating minus DCLCGE and DTCGE */
|
||||
#define SST_VDRTCL2_CG_OTHER 0xB7D
|
||||
|
||||
static void hsw_set_dsp_D3(struct sst_dsp *sst)
|
||||
{
|
||||
u32 val;
|
||||
u32 reg;
|
||||
|
||||
/* disable clock core gating */
|
||||
/* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* stall, reset and set 24MHz XOSC */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
|
||||
SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST,
|
||||
SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST);
|
||||
/* enable power gating and switch off DRAM & IRAM blocks */
|
||||
val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
val |= SST_VDRTCL0_DSRAMPGE_MASK |
|
||||
SST_VDRTCL0_ISRAMPGE_MASK;
|
||||
val &= ~(SST_VDRTCL0_D3PGD | SST_VDRTCL0_D3SRAMPGD);
|
||||
writel(val, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
|
||||
/* DRAM power gating all */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
reg |= SST_VDRTCL0_ISRAMPGE_MASK |
|
||||
SST_VDRTCL0_DSRAMPGE_MASK;
|
||||
reg &= ~(SST_VDRTCL0_D3SRAMPGD);
|
||||
reg |= SST_VDRTCL0_D3PGD;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
udelay(50);
|
||||
/* switch off audio PLL */
|
||||
val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
val |= SST_VDRTCL2_APLLSE_MASK;
|
||||
writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* PLL shutdown enable */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_APLLSE_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* disable MCLK */
|
||||
/* disable MCLK(clkctl.smos = 0) */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
|
||||
SST_CLKCTL_MASK, 0);
|
||||
SST_CLKCTL_MASK, 0);
|
||||
|
||||
/* switch clock gating */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_CG_OTHER;
|
||||
reg &= ~(SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
/* enable DTCGE separatelly */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_DTCGE;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* set shim defaults */
|
||||
hsw_set_shim_defaults(sst);
|
||||
|
||||
/* set D3 */
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
reg |= SST_PMCS_PS_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_PMCS);
|
||||
/* Set D3 state, delay 50 us */
|
||||
val = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
val |= SST_PMCS_PS_MASK;
|
||||
writel(val, sst->addr.pci_cfg + SST_PMCS);
|
||||
udelay(50);
|
||||
|
||||
/* enable clock core gating */
|
||||
/* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_DCLCGE;
|
||||
reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
udelay(50);
|
||||
|
||||
}
|
||||
|
||||
static void hsw_reset(struct sst_dsp *sst)
|
||||
@ -346,62 +299,75 @@ static void hsw_reset(struct sst_dsp *sst)
|
||||
SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL);
|
||||
}
|
||||
|
||||
/* recommended CSR state for power-up */
|
||||
#define SST_CSR_D0_MASK (0x18A09C0C | SST_CSR_DCS_MASK)
|
||||
|
||||
static int hsw_set_dsp_D0(struct sst_dsp *sst)
|
||||
{
|
||||
u32 reg;
|
||||
int tries = 10;
|
||||
u32 reg, fw_dump_bit;
|
||||
|
||||
/* disable clock core gating */
|
||||
/* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* switch clock gating */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_CG_OTHER;
|
||||
reg &= ~(SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* set D0 */
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
reg &= ~(SST_PMCS_PS_MASK);
|
||||
writel(reg, sst->addr.pci_cfg + SST_PMCS);
|
||||
|
||||
/* DRAM power gating none */
|
||||
/* Disable D3PG (VDRTCTL0.D3PGD = 1) */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
reg &= ~(SST_VDRTCL0_ISRAMPGE_MASK |
|
||||
SST_VDRTCL0_DSRAMPGE_MASK);
|
||||
reg |= SST_VDRTCL0_D3SRAMPGD;
|
||||
reg |= SST_VDRTCL0_D3PGD;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
mdelay(10);
|
||||
|
||||
/* set shim defaults */
|
||||
hsw_set_shim_defaults(sst);
|
||||
/* Set D0 state */
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
reg &= ~SST_PMCS_PS_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_PMCS);
|
||||
|
||||
/* restore MCLK */
|
||||
/* check that ADSP shim is enabled */
|
||||
while (tries--) {
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK;
|
||||
if (reg == 0)
|
||||
goto finish;
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
|
||||
finish:
|
||||
/* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
|
||||
SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0);
|
||||
|
||||
/* stall DSP core, set clk to 192/96Mhz */
|
||||
sst_dsp_shim_update_bits_unlocked(sst,
|
||||
SST_CSR, SST_CSR_STALL | SST_CSR_DCS_MASK,
|
||||
SST_CSR_STALL | SST_CSR_DCS(4));
|
||||
|
||||
/* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
|
||||
SST_CLKCTL_MASK, SST_CLKCTL_MASK);
|
||||
SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0,
|
||||
SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0);
|
||||
|
||||
/* PLL shutdown disable */
|
||||
/* Stall and reset core, set CSR */
|
||||
hsw_reset(sst);
|
||||
|
||||
/* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg &= ~(SST_VDRTCL2_APLLSE_MASK);
|
||||
reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
|
||||
SST_CSR_D0_MASK, SST_CSR_SBCS0 | SST_CSR_SBCS1 |
|
||||
SST_CSR_STALL | SST_CSR_DCS(4));
|
||||
udelay(50);
|
||||
|
||||
/* enable clock core gating */
|
||||
/* switch on audio PLL */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_DCLCGE;
|
||||
reg &= ~SST_VDRTCL2_APLLSE_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* clear reset */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_RST, 0);
|
||||
/* set default power gating control, enable power gating control for all blocks. that is,
|
||||
can't be accessed, please enable each block before accessing. */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
|
||||
/* for D0, always enable the block(DSRAM[0]) used for FW dump */
|
||||
fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
|
||||
writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
|
||||
|
||||
/* disable DMA finish function for SSP0 & SSP1 */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1,
|
||||
@ -418,6 +384,12 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst)
|
||||
sst_dsp_shim_update_bits(sst, SST_IMRD, (SST_IMRD_DONE | SST_IMRD_BUSY |
|
||||
SST_IMRD_SSP0 | SST_IMRD_DMAC), 0x0);
|
||||
|
||||
/* clear IPC registers */
|
||||
sst_dsp_shim_write(sst, SST_IPCX, 0x0);
|
||||
sst_dsp_shim_write(sst, SST_IPCD, 0x0);
|
||||
sst_dsp_shim_write(sst, 0x80, 0x6);
|
||||
sst_dsp_shim_write(sst, 0xe0, 0x300a);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -443,6 +415,11 @@ static void hsw_sleep(struct sst_dsp *sst)
|
||||
{
|
||||
dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n");
|
||||
|
||||
/* put DSP into reset and stall */
|
||||
sst_dsp_shim_update_bits(sst, SST_CSR,
|
||||
SST_CSR_24MHZ_LPCS | SST_CSR_RST | SST_CSR_STALL,
|
||||
SST_CSR_RST | SST_CSR_STALL | SST_CSR_24MHZ_LPCS);
|
||||
|
||||
hsw_set_dsp_D3(sst);
|
||||
dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n");
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define CTRL0_TODDR_SEL_RESAMPLE BIT(30)
|
||||
#define CTRL0_TODDR_EXT_SIGNED BIT(29)
|
||||
#define CTRL0_TODDR_PP_MODE BIT(28)
|
||||
#define CTRL0_TODDR_SYNC_CH BIT(27)
|
||||
#define CTRL0_TODDR_TYPE_MASK GENMASK(15, 13)
|
||||
#define CTRL0_TODDR_TYPE(x) ((x) << 13)
|
||||
#define CTRL0_TODDR_MSB_POS_MASK GENMASK(12, 8)
|
||||
@ -189,10 +190,31 @@ static const struct axg_fifo_match_data axg_toddr_match_data = {
|
||||
.dai_drv = &axg_toddr_dai_drv
|
||||
};
|
||||
|
||||
static int g12a_toddr_dai_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
|
||||
int ret;
|
||||
|
||||
ret = axg_toddr_dai_startup(substream, dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Make sure the first channel ends up in the at beginning of the output
|
||||
* As weird as it looks, without this the first channel may be misplaced
|
||||
* in memory, with a random shift of 2 channels.
|
||||
*/
|
||||
regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SYNC_CH,
|
||||
CTRL0_TODDR_SYNC_CH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops g12a_toddr_ops = {
|
||||
.prepare = g12a_toddr_dai_prepare,
|
||||
.hw_params = axg_toddr_dai_hw_params,
|
||||
.startup = axg_toddr_dai_startup,
|
||||
.startup = g12a_toddr_dai_startup,
|
||||
.shutdown = axg_toddr_dai_shutdown,
|
||||
};
|
||||
|
||||
|
@ -143,6 +143,7 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev)
|
||||
|
||||
card = &data->card;
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
card->dapm_widgets = apq8016_sbc_dapm_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets);
|
||||
|
||||
|
@ -114,6 +114,7 @@ static int apq8096_platform_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
dev_set_drvdata(dev, card);
|
||||
ret = qcom_snd_parse_of(card);
|
||||
if (ret)
|
||||
|
@ -52,8 +52,10 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
|
||||
|
||||
for_each_child_of_node(dev->of_node, np) {
|
||||
dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
|
||||
if (!dlc)
|
||||
return -ENOMEM;
|
||||
if (!dlc) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
link->cpus = &dlc[0];
|
||||
link->platforms = &dlc[1];
|
||||
|
@ -555,6 +555,7 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
|
||||
card->dapm_widgets = sdm845_snd_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
dev_set_drvdata(dev, card);
|
||||
ret = qcom_snd_parse_of(card);
|
||||
if (ret)
|
||||
|
@ -96,6 +96,7 @@ static int storm_platform_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
card->owner = THIS_MODULE;
|
||||
|
||||
ret = snd_soc_of_parse_card_name(card, "qcom,model");
|
||||
if (ret) {
|
||||
|
@ -834,6 +834,19 @@ struct snd_soc_dai *snd_soc_find_dai(
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_find_dai);
|
||||
|
||||
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
|
||||
const struct snd_soc_dai_link_component *dlc)
|
||||
{
|
||||
struct snd_soc_dai *dai;
|
||||
|
||||
mutex_lock(&client_mutex);
|
||||
dai = snd_soc_find_dai(dlc);
|
||||
mutex_unlock(&client_mutex);
|
||||
|
||||
return dai;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_find_dai_with_mutex);
|
||||
|
||||
static int soc_dai_link_sanity_check(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *link)
|
||||
{
|
||||
|
@ -412,14 +412,14 @@ void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
|
||||
supported_codec = false;
|
||||
|
||||
for_each_link_cpus(dai_link, i, cpu) {
|
||||
dai = snd_soc_find_dai(cpu);
|
||||
dai = snd_soc_find_dai_with_mutex(cpu);
|
||||
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
|
||||
supported_cpu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for_each_link_codecs(dai_link, i, codec) {
|
||||
dai = snd_soc_find_dai(codec);
|
||||
dai = snd_soc_find_dai_with_mutex(codec);
|
||||
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
|
||||
supported_codec = true;
|
||||
break;
|
||||
|
@ -812,7 +812,7 @@ dynamic:
|
||||
return 0;
|
||||
|
||||
config_err:
|
||||
for_each_rtd_dais(rtd, i, dai)
|
||||
for_each_rtd_dais_rollback(rtd, i, dai)
|
||||
snd_soc_dai_shutdown(dai, substream);
|
||||
|
||||
snd_soc_link_shutdown(substream);
|
||||
|
@ -446,12 +446,12 @@ static const struct snd_soc_dai_ops ams_delta_dai_ops = {
|
||||
/* Will be used if the codec ever has its own digital_mute function */
|
||||
static int ams_delta_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
return ams_delta_digital_mute(NULL, 0, substream->stream);
|
||||
return ams_delta_mute(NULL, 0, substream->stream);
|
||||
}
|
||||
|
||||
static void ams_delta_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
ams_delta_digital_mute(NULL, 1, substream->stream);
|
||||
ams_delta_mute(NULL, 1, substream->stream);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user