sound fixes for 4.10-rc4

This time we got a few more fixes than the previous rc's, and the most
 of commits were about ASoC.  The only significant change in the core
 side is the regression fix wrt the aux device list handling, and all
 the rest are driver-specific small / trivial fixes.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABAgAGBQJYd+juAAoJEGwxgFQ9KSmkdpkQALA1JjQSHYyPybvwJNAjTUnB
 +VaG+tTK0Q6TRS9KFUte41a8/FVazXwK9xBsEsOjaYFfd/nJj7WRoZsmbwMALY+S
 6S7FBPBxuvrhzFSWCHBFL9E0aaxeHo81tHiZQoaSj4TAQJvIH9amDCNLgMM+kdIf
 nRp5CgXZT4Xco462Ge+dpnz6KL7mRtv3f9EpjAHT/ptEWRIDQb7KOj3cmq7F5Jpk
 SFigCWfHdthH6ldwVKnl3ZRGPYqmdVwq+Wq+jOKByDNK4yPKb0s3JFtldvDkszWI
 IxblPwVbjnOPGvWY4dI1FT20Xuqjhgbm1HoZQMQsNGHwqZsUxdNtQTO7V3nlE57I
 Kf+l6FC0f4aveIPo9Qt6J6T6kkPIYNhIhEaVhFXX3LFU91/f8fcDpyzunPP1pbA0
 TyCbDsc6boPfrCh0qYeOZdfsJpfomL1hTyGpPkQiGGqKzw+uO3Jv+lsTeq/Qd0Ud
 RvOhcW+UrP/gBIb7Q1zQpK7vbJna00WpmqBjYClENGuLWUCdPOOpkcLHVXOKsy/0
 bxKsGt9rWzz6LtLX4bWgwHdu0tn9iXNggbcshp5LjyoChVCXaTh36uQHRyIXk8Bw
 VhbMFW1ZIMac9pHj47EkpSTRsGPHZYwCnK5utWqf8RRgV86DpUrR9rrX2wVUxGYF
 pGOR8RzEoM5i7PRWJyJE
 =gGt3
 -----END PGP SIGNATURE-----

Merge tag 'sound-4.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "This time we got a few more fixes than the previous rc's, and most of
  commits were about ASoC.

  The only significant change in the core side is the regression fix wrt
  the aux device list handling, and all the rest are driver-specific
  small / trivial fixes"

* tag 'sound-4.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: usb-audio: Add a quirk for Plantronics BT600
  ASoC: rt5645: set sel_i2s_pre_div1 to 2
  ASoC: dpcm: Avoid putting stream state to STOP when FE stream is paused
  ASoC: Intel: Skylake: Release FW ctx in cleanup
  ASoC: Intel: bytcr-rt5640: fix settings in internal clock mode
  ASoC: fsl_ssi: set fifo watermark to more reliable value
  ASoC: nau8825: fix invalid configuration in Pre-Scalar of FLL
  ASoC: nau8825: correct the function name of register
  ASoC: Intel: Skylake: Fix to fail safely if module not available in path
  ASoC: tlv320aic3x: Mark the RESET register as volatile
  ASoC: Fix binding and probing of auxiliary components
  ASoC: wm_adsp: Don't overrun firmware file buffer when reading region data
  ASoC: Intel: bytcr_rt5640: fallback mechanism if MCLK is not enabled
  ASoC: hdmi-codec: use unsigned type to structure members with bit-field
  ASoC: topology: kfree kcontrol->private_value before freeing kcontrol
  ASoC: rsnd: don't double free kctrl
  ASoC: dwc: Fix PIO mode initialization
This commit is contained in:
Linus Torvalds 2017-01-12 14:45:59 -08:00
commit 557ed56cc7
17 changed files with 151 additions and 62 deletions

View File

@ -36,10 +36,10 @@ struct hdmi_codec_daifmt {
HDMI_AC97, HDMI_AC97,
HDMI_SPDIF, HDMI_SPDIF,
} fmt; } fmt;
int bit_clk_inv:1; unsigned int bit_clk_inv:1;
int frame_clk_inv:1; unsigned int frame_clk_inv:1;
int bit_clk_master:1; unsigned int bit_clk_master:1;
int frame_clk_master:1; unsigned int frame_clk_master:1;
}; };
/* /*

View File

@ -813,6 +813,7 @@ struct snd_soc_component {
unsigned int suspended:1; /* is in suspend PM state */ unsigned int suspended:1; /* is in suspend PM state */
struct list_head list; struct list_head list;
struct list_head card_aux_list; /* for auxiliary bound components */
struct list_head card_list; struct list_head card_list;
struct snd_soc_dai_driver *dai_drv; struct snd_soc_dai_driver *dai_drv;
@ -1152,6 +1153,7 @@ struct snd_soc_card {
*/ */
struct snd_soc_aux_dev *aux_dev; struct snd_soc_aux_dev *aux_dev;
int num_aux_devs; int num_aux_devs;
struct list_head aux_comp_list;
const struct snd_kcontrol_new *controls; const struct snd_kcontrol_new *controls;
int num_controls; int num_controls;
@ -1547,6 +1549,7 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
INIT_LIST_HEAD(&card->widgets); INIT_LIST_HEAD(&card->widgets);
INIT_LIST_HEAD(&card->paths); INIT_LIST_HEAD(&card->paths);
INIT_LIST_HEAD(&card->dapm_list); INIT_LIST_HEAD(&card->dapm_list);
INIT_LIST_HEAD(&card->aux_comp_list);
INIT_LIST_HEAD(&card->component_dev_list); INIT_LIST_HEAD(&card->component_dev_list);
} }

View File

@ -561,9 +561,9 @@ static void nau8825_xtalk_prepare(struct nau8825 *nau8825)
nau8825_xtalk_backup(nau8825); nau8825_xtalk_backup(nau8825);
/* Config IIS as master to output signal by codec */ /* Config IIS as master to output signal by codec */
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_MS_MASK | NAU8825_I2S_DRV_MASK | NAU8825_I2S_MS_MASK | NAU8825_I2S_LRC_DIV_MASK |
NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_MASTER | NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_MASTER |
(0x2 << NAU8825_I2S_DRV_SFT) | 0x1); (0x2 << NAU8825_I2S_LRC_DIV_SFT) | 0x1);
/* Ramp up headphone volume to 0dB to get better performance and /* Ramp up headphone volume to 0dB to get better performance and
* avoid pop noise in headphone. * avoid pop noise in headphone.
*/ */
@ -657,7 +657,7 @@ static void nau8825_xtalk_clean(struct nau8825 *nau8825)
NAU8825_IRQ_RMS_EN, NAU8825_IRQ_RMS_EN); NAU8825_IRQ_RMS_EN, NAU8825_IRQ_RMS_EN);
/* Recover default value for IIS */ /* Recover default value for IIS */
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_MS_MASK | NAU8825_I2S_DRV_MASK | NAU8825_I2S_MS_MASK | NAU8825_I2S_LRC_DIV_MASK |
NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_SLAVE); NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_SLAVE);
/* Restore value of specific register for cross talk */ /* Restore value of specific register for cross talk */
nau8825_xtalk_restore(nau8825); nau8825_xtalk_restore(nau8825);
@ -2006,7 +2006,8 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
NAU8825_FLL_INTEGER_MASK, fll_param->fll_int); NAU8825_FLL_INTEGER_MASK, fll_param->fll_int);
/* FLL pre-scaler */ /* FLL pre-scaler */
regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL4, regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL4,
NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div); NAU8825_FLL_REF_DIV_MASK,
fll_param->clk_ref_div << NAU8825_FLL_REF_DIV_SFT);
/* select divided VCO input */ /* select divided VCO input */
regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5, regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
NAU8825_FLL_CLK_SW_MASK, NAU8825_FLL_CLK_SW_REF); NAU8825_FLL_CLK_SW_MASK, NAU8825_FLL_CLK_SW_REF);

View File

@ -137,7 +137,8 @@
#define NAU8825_FLL_CLK_SRC_FS (0x3 << NAU8825_FLL_CLK_SRC_SFT) #define NAU8825_FLL_CLK_SRC_FS (0x3 << NAU8825_FLL_CLK_SRC_SFT)
/* FLL4 (0x07) */ /* FLL4 (0x07) */
#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10) #define NAU8825_FLL_REF_DIV_SFT 10
#define NAU8825_FLL_REF_DIV_MASK (0x3 << NAU8825_FLL_REF_DIV_SFT)
/* FLL5 (0x08) */ /* FLL5 (0x08) */
#define NAU8825_FLL_PDB_DAC_EN (0x1 << 15) #define NAU8825_FLL_PDB_DAC_EN (0x1 << 15)
@ -247,8 +248,8 @@
/* I2S_PCM_CTRL2 (0x1d) */ /* I2S_PCM_CTRL2 (0x1d) */
#define NAU8825_I2S_TRISTATE (1 << 15) /* 0 - normal mode, 1 - Hi-Z output */ #define NAU8825_I2S_TRISTATE (1 << 15) /* 0 - normal mode, 1 - Hi-Z output */
#define NAU8825_I2S_DRV_SFT 12 #define NAU8825_I2S_LRC_DIV_SFT 12
#define NAU8825_I2S_DRV_MASK (0x3 << NAU8825_I2S_DRV_SFT) #define NAU8825_I2S_LRC_DIV_MASK (0x3 << NAU8825_I2S_LRC_DIV_SFT)
#define NAU8825_I2S_MS_SFT 3 #define NAU8825_I2S_MS_SFT 3
#define NAU8825_I2S_MS_MASK (1 << NAU8825_I2S_MS_SFT) #define NAU8825_I2S_MS_MASK (1 << NAU8825_I2S_MS_SFT)
#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT) #define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT)

View File

@ -3833,6 +3833,9 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
} }
} }
regmap_update_bits(rt5645->regmap, RT5645_ADDA_CLK1,
RT5645_I2S_PD1_MASK, RT5645_I2S_PD1_2);
if (rt5645->pdata.jd_invert) { if (rt5645->pdata.jd_invert) {
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV); RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);

View File

@ -126,6 +126,16 @@ static const struct reg_default aic3x_reg[] = {
{ 108, 0x00 }, { 109, 0x00 }, { 108, 0x00 }, { 109, 0x00 },
}; };
static bool aic3x_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case AIC3X_RESET:
return true;
default:
return false;
}
}
static const struct regmap_config aic3x_regmap = { static const struct regmap_config aic3x_regmap = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
@ -133,6 +143,9 @@ static const struct regmap_config aic3x_regmap = {
.max_register = DAC_ICC_ADJ, .max_register = DAC_ICC_ADJ,
.reg_defaults = aic3x_reg, .reg_defaults = aic3x_reg,
.num_reg_defaults = ARRAY_SIZE(aic3x_reg), .num_reg_defaults = ARRAY_SIZE(aic3x_reg),
.volatile_reg = aic3x_volatile_reg,
.cache_type = REGCACHE_RBTREE, .cache_type = REGCACHE_RBTREE,
}; };

View File

@ -1551,7 +1551,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
const struct wmfw_region *region; const struct wmfw_region *region;
const struct wm_adsp_region *mem; const struct wm_adsp_region *mem;
const char *region_name; const char *region_name;
char *file, *text; char *file, *text = NULL;
struct wm_adsp_buf *buf; struct wm_adsp_buf *buf;
unsigned int reg; unsigned int reg;
int regions = 0; int regions = 0;
@ -1700,10 +1700,21 @@ static int wm_adsp_load(struct wm_adsp *dsp)
regions, le32_to_cpu(region->len), offset, regions, le32_to_cpu(region->len), offset,
region_name); region_name);
if ((pos + le32_to_cpu(region->len) + sizeof(*region)) >
firmware->size) {
adsp_err(dsp,
"%s.%d: %s region len %d bytes exceeds file length %zu\n",
file, regions, region_name,
le32_to_cpu(region->len), firmware->size);
ret = -EINVAL;
goto out_fw;
}
if (text) { if (text) {
memcpy(text, region->data, le32_to_cpu(region->len)); memcpy(text, region->data, le32_to_cpu(region->len));
adsp_info(dsp, "%s: %s\n", file, text); adsp_info(dsp, "%s: %s\n", file, text);
kfree(text); kfree(text);
text = NULL;
} }
if (reg) { if (reg) {
@ -1748,6 +1759,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
regmap_async_complete(regmap); regmap_async_complete(regmap);
wm_adsp_buf_free(&buf_list); wm_adsp_buf_free(&buf_list);
release_firmware(firmware); release_firmware(firmware);
kfree(text);
out: out:
kfree(file); kfree(file);
@ -2233,6 +2245,17 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
} }
if (reg) { if (reg) {
if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) >
firmware->size) {
adsp_err(dsp,
"%s.%d: %s region len %d bytes exceeds file length %zu\n",
file, blocks, region_name,
le32_to_cpu(blk->len),
firmware->size);
ret = -EINVAL;
goto out_fw;
}
buf = wm_adsp_buf_alloc(blk->data, buf = wm_adsp_buf_alloc(blk->data,
le32_to_cpu(blk->len), le32_to_cpu(blk->len),
&buf_list); &buf_list);

View File

@ -681,22 +681,19 @@ static int dw_i2s_probe(struct platform_device *pdev)
} }
if (!pdata) { if (!pdata) {
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); if (irq >= 0) {
if (ret == -EPROBE_DEFER) {
dev_err(&pdev->dev,
"failed to register PCM, deferring probe\n");
return ret;
} else if (ret) {
dev_err(&pdev->dev,
"Could not register DMA PCM: %d\n"
"falling back to PIO mode\n", ret);
ret = dw_pcm_register(pdev); ret = dw_pcm_register(pdev);
if (ret) { dev->use_pio = true;
dev_err(&pdev->dev, } else {
"Could not register PIO PCM: %d\n", ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
0);
dev->use_pio = false;
}
if (ret) {
dev_err(&pdev->dev, "could not register pcm: %d\n",
ret); ret);
goto err_clk_disable; goto err_clk_disable;
}
} }
} }

View File

@ -224,6 +224,12 @@ struct fsl_ssi_soc_data {
* @dbg_stats: Debugging statistics * @dbg_stats: Debugging statistics
* *
* @soc: SoC specific data * @soc: SoC specific data
*
* @fifo_watermark: the FIFO watermark setting. Notifies DMA when
* there are @fifo_watermark or fewer words in TX fifo or
* @fifo_watermark or more empty words in RX fifo.
* @dma_maxburst: max number of words to transfer in one go. So far,
* this is always the same as fifo_watermark.
*/ */
struct fsl_ssi_private { struct fsl_ssi_private {
struct regmap *regs; struct regmap *regs;
@ -263,6 +269,9 @@ struct fsl_ssi_private {
const struct fsl_ssi_soc_data *soc; const struct fsl_ssi_soc_data *soc;
struct device *dev; struct device *dev;
u32 fifo_watermark;
u32 dma_maxburst;
}; };
/* /*
@ -1051,21 +1060,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
regmap_write(regs, CCSR_SSI_SRCR, srcr); regmap_write(regs, CCSR_SSI_SRCR, srcr);
regmap_write(regs, CCSR_SSI_SCR, scr); regmap_write(regs, CCSR_SSI_SCR, scr);
/* wm = ssi_private->fifo_watermark;
* Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't
* use FIFO 1. We program the transmit water to signal a DMA transfer
* if there are only two (or fewer) elements left in the FIFO. Two
* elements equals one frame (left channel, right channel). This value,
* however, depends on the depth of the transmit buffer.
*
* We set the watermark on the same level as the DMA burstsize. For
* fiq it is probably better to use the biggest possible watermark
* size.
*/
if (ssi_private->use_dma)
wm = ssi_private->fifo_depth - 2;
else
wm = ssi_private->fifo_depth;
regmap_write(regs, CCSR_SSI_SFCSR, regmap_write(regs, CCSR_SSI_SFCSR,
CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
@ -1373,12 +1368,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
PTR_ERR(ssi_private->baudclk)); PTR_ERR(ssi_private->baudclk));
/* ssi_private->dma_params_tx.maxburst = ssi_private->dma_maxburst;
* We have burstsize be "fifo_depth - 2" to match the SSI ssi_private->dma_params_rx.maxburst = ssi_private->dma_maxburst;
* watermark setting in fsl_ssi_startup().
*/
ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2;
ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2;
ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0;
@ -1543,6 +1534,47 @@ static int fsl_ssi_probe(struct platform_device *pdev)
/* Older 8610 DTs didn't have the fifo-depth property */ /* Older 8610 DTs didn't have the fifo-depth property */
ssi_private->fifo_depth = 8; ssi_private->fifo_depth = 8;
/*
* Set the watermark for transmit FIFO 0 and receive FIFO 0. We don't
* use FIFO 1 but set the watermark appropriately nontheless.
* We program the transmit water to signal a DMA transfer
* if there are N elements left in the FIFO. For chips with 15-deep
* FIFOs, set watermark to 8. This allows the SSI to operate at a
* high data rate without channel slipping. Behavior is unchanged
* for the older chips with a fifo depth of only 8. A value of 4
* might be appropriate for the older chips, but is left at
* fifo_depth-2 until sombody has a chance to test.
*
* We set the watermark on the same level as the DMA burstsize. For
* fiq it is probably better to use the biggest possible watermark
* size.
*/
switch (ssi_private->fifo_depth) {
case 15:
/*
* 2 samples is not enough when running at high data
* rates (like 48kHz @ 16 bits/channel, 16 channels)
* 8 seems to split things evenly and leave enough time
* for the DMA to fill the FIFO before it's over/under
* run.
*/
ssi_private->fifo_watermark = 8;
ssi_private->dma_maxburst = 8;
break;
case 8:
default:
/*
* maintain old behavior for older chips.
* Keeping it the same because I don't have an older
* board to test with.
* I suspect this could be changed to be something to
* leave some more space in the fifo.
*/
ssi_private->fifo_watermark = ssi_private->fifo_depth - 2;
ssi_private->dma_maxburst = ssi_private->fifo_depth - 2;
break;
}
dev_set_drvdata(&pdev->dev, ssi_private); dev_set_drvdata(&pdev->dev, ssi_private);
if (ssi_private->soc->imx) { if (ssi_private->soc->imx) {

View File

@ -142,7 +142,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
* for Jack detection and button press * for Jack detection and button press
*/ */
ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK, ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
0, 48000 * 512,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
if (!ret) { if (!ret) {
if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk)
@ -825,10 +825,20 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) { if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) {
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk)) { if (IS_ERR(priv->mclk)) {
ret_val = PTR_ERR(priv->mclk);
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Failed to get MCLK from pmc_plt_clk_3: %ld\n", "Failed to get MCLK from pmc_plt_clk_3: %d\n",
PTR_ERR(priv->mclk)); ret_val);
return PTR_ERR(priv->mclk);
/*
* Fall back to bit clock usage for -ENOENT (clock not
* available likely due to missing dependencies), bail
* for all other errors, including -EPROBE_DEFER
*/
if (ret_val != -ENOENT)
return ret_val;
byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
} }
} }

View File

@ -180,6 +180,9 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
snd_pcm_set_sync(substream); snd_pcm_set_sync(substream);
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
if (!mconfig)
return -EINVAL;
skl_tplg_d0i3_get(skl, mconfig->d0i3_caps); skl_tplg_d0i3_get(skl, mconfig->d0i3_caps);
return 0; return 0;

View File

@ -515,6 +515,9 @@ EXPORT_SYMBOL_GPL(skl_sst_init_fw);
void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
{ {
if (ctx->dsp->fw)
release_firmware(ctx->dsp->fw);
skl_clear_module_table(ctx->dsp); skl_clear_module_table(ctx->dsp);
skl_freeup_uuid_list(ctx); skl_freeup_uuid_list(ctx);
skl_ipc_free(&ctx->ipc); skl_ipc_free(&ctx->ipc);

View File

@ -1030,10 +1030,8 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
return -ENOMEM; return -ENOMEM;
ret = snd_ctl_add(card, kctrl); ret = snd_ctl_add(card, kctrl);
if (ret < 0) { if (ret < 0)
snd_ctl_free_one(kctrl);
return ret; return ret;
}
cfg->update = update; cfg->update = update;
cfg->card = card; cfg->card = card;

View File

@ -1748,6 +1748,7 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
component->init = aux_dev->init; component->init = aux_dev->init;
component->auxiliary = 1; component->auxiliary = 1;
list_add(&component->card_aux_list, &card->aux_comp_list);
return 0; return 0;
@ -1758,16 +1759,14 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
static int soc_probe_aux_devices(struct snd_soc_card *card) static int soc_probe_aux_devices(struct snd_soc_card *card)
{ {
struct snd_soc_component *comp; struct snd_soc_component *comp, *tmp;
int order; int order;
int ret; int ret;
for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
order++) { order++) {
list_for_each_entry(comp, &card->component_dev_list, card_list) { list_for_each_entry_safe(comp, tmp, &card->aux_comp_list,
if (!comp->auxiliary) card_aux_list) {
continue;
if (comp->driver->probe_order == order) { if (comp->driver->probe_order == order) {
ret = soc_probe_component(card, comp); ret = soc_probe_component(card, comp);
if (ret < 0) { if (ret < 0) {
@ -1776,6 +1775,7 @@ static int soc_probe_aux_devices(struct snd_soc_card *card)
comp->name, ret); comp->name, ret);
return ret; return ret;
} }
list_del(&comp->card_aux_list);
} }
} }
} }

View File

@ -2184,9 +2184,11 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
break; break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
break;
} }
out: out:

View File

@ -514,13 +514,12 @@ static void remove_widget(struct snd_soc_component *comp,
== SND_SOC_TPLG_TYPE_MIXER) == SND_SOC_TPLG_TYPE_MIXER)
kfree(kcontrol->tlv.p); kfree(kcontrol->tlv.p);
snd_ctl_remove(card, kcontrol);
/* Private value is used as struct soc_mixer_control /* Private value is used as struct soc_mixer_control
* for volume mixers or soc_bytes_ext for bytes * for volume mixers or soc_bytes_ext for bytes
* controls. * controls.
*/ */
kfree((void *)kcontrol->private_value); kfree((void *)kcontrol->private_value);
snd_ctl_remove(card, kcontrol);
} }
kfree(w->kcontrol_news); kfree(w->kcontrol_news);
} }

View File

@ -1135,6 +1135,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
case USB_ID(0x047F, 0x02F7): /* Plantronics BT-600 */
case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */ case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */
case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */ case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */