Skip to content

Commit

Permalink
Merge tag 'sound-6.0-rc5' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Lots of small fixes for various drivers at this time, hopefully it
  will be the last big bump before 6.0 release.

  The significant changes are regression fixes for (yet again) HD-audio
  memory allocations and USB-audio PCM parameter handling, while there
  are many small ASoC device-specific fixes as well as a few
  out-of-bounds and race issues spotted by fuzzers"

* tag 'sound-6.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (29 commits)
  ALSA: usb-audio: Clear fixed clock rate at closing EP
  ALSA: emu10k1: Fix out of bounds access in snd_emu10k1_pcm_channel_alloc()
  ALSA: hda: Once again fix regression of page allocations with IOMMU
  ALSA: usb-audio: Fix an out-of-bounds bug in __snd_usb_parse_audio_interface()
  ALSA: hda/tegra: Align BDL entry to 4KB boundary
  ALSA: hda/sigmatel: Fix unused variable warning for beep power change
  ALSA: pcm: oss: Fix race at SNDCTL_DSP_SYNC
  ALSA: hda/sigmatel: Keep power up while beep is enabled
  ALSA: aloop: Fix random zeros in capture data when using jiffies timer
  ALSA: usb-audio: Split endpoint setups for hw_params and prepare
  ALSA: usb-audio: Register card again for iface over delayed_register option
  ALSA: usb-audio: Inform the delayed registration more properly
  ASoC: fsl_aud2htx: Add error handler for pm_runtime_enable
  ASoC: fsl_aud2htx: register platform component before registering cpu dai
  ASoC: SOF: ipc4-topology: fix alh_group_ida max value
  ASoC: mchp-spdiftx: Fix clang -Wbitfield-constant-conversion
  ASoC: SOF: Kconfig: Make IPC_MESSAGE_INJECTOR depend on SND_SOC_SOF
  ASoC: SOF: Kconfig: Make IPC_FLOOD_TEST depend on SND_SOC_SOF
  ASoC: fsl_mqs: Fix supported clock DAI format
  ASoC: nau8540: Implement hw constraint for rates
  ...
  • Loading branch information
torvalds committed Sep 9, 2022
2 parents d8a450a + 09e3e31 commit 83dfc0e
Show file tree
Hide file tree
Showing 26 changed files with 257 additions and 168 deletions.
9 changes: 7 additions & 2 deletions sound/core/memalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,13 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
dmab->dev.need_sync = dma_need_sync(dmab->dev.dev,
sg_dma_address(sgt->sgl));
p = dma_vmap_noncontiguous(dmab->dev.dev, size, sgt);
if (p)
if (p) {
dmab->private_data = sgt;
else
/* store the first page address for convenience */
dmab->addr = snd_sgbuf_get_addr(dmab, 0);
} else {
dma_free_noncontiguous(dmab->dev.dev, size, sgt, dmab->dev.dir);
}
return p;
}

Expand Down Expand Up @@ -780,6 +783,8 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size)
if (!p)
goto error;
dmab->private_data = sgbuf;
/* store the first page address for convenience */
dmab->addr = snd_sgbuf_get_addr(dmab, 0);
return p;

error:
Expand Down
6 changes: 3 additions & 3 deletions sound/core/oss/pcm_oss.c
Original file line number Diff line number Diff line change
Expand Up @@ -1672,14 +1672,14 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
runtime = substream->runtime;
if (atomic_read(&substream->mmap_count))
goto __direct;
err = snd_pcm_oss_make_ready(substream);
if (err < 0)
return err;
atomic_inc(&runtime->oss.rw_ref);
if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
atomic_dec(&runtime->oss.rw_ref);
return -ERESTARTSYS;
}
err = snd_pcm_oss_make_ready_locked(substream);
if (err < 0)
goto unlock;
format = snd_pcm_oss_format_from(runtime->oss.format);
width = snd_pcm_format_physical_width(format);
if (runtime->oss.buffer_used > 0) {
Expand Down
7 changes: 4 additions & 3 deletions sound/drivers/aloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,17 +605,18 @@ static unsigned int loopback_jiffies_timer_pos_update
cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
struct loopback_pcm *dpcm_capt =
cable->streams[SNDRV_PCM_STREAM_CAPTURE];
unsigned long delta_play = 0, delta_capt = 0;
unsigned long delta_play = 0, delta_capt = 0, cur_jiffies;
unsigned int running, count1, count2;

cur_jiffies = jiffies;
running = cable->running ^ cable->pause;
if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
delta_play = jiffies - dpcm_play->last_jiffies;
delta_play = cur_jiffies - dpcm_play->last_jiffies;
dpcm_play->last_jiffies += delta_play;
}

if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
delta_capt = jiffies - dpcm_capt->last_jiffies;
delta_capt = cur_jiffies - dpcm_capt->last_jiffies;
dpcm_capt->last_jiffies += delta_capt;
}

Expand Down
2 changes: 1 addition & 1 deletion sound/pci/emu10k1/emupcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic
epcm->voices[0]->epcm = epcm;
if (voices > 1) {
for (i = 1; i < voices; i++) {
epcm->voices[i] = &epcm->emu->voices[epcm->voices[0]->number + i];
epcm->voices[i] = &epcm->emu->voices[(epcm->voices[0]->number + i) % NUM_G];
epcm->voices[i]->epcm = epcm;
}
}
Expand Down
2 changes: 1 addition & 1 deletion sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1817,7 +1817,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,

/* use the non-cached pages in non-snoop mode */
if (!azx_snoop(chip))
azx_bus(chip)->dma_type = SNDRV_DMA_TYPE_DEV_WC;
azx_bus(chip)->dma_type = SNDRV_DMA_TYPE_DEV_WC_SG;

if (chip->driver_type == AZX_DRIVER_NVIDIA) {
dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
Expand Down
3 changes: 2 additions & 1 deletion sound/pci/hda/hda_tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,8 @@ MODULE_DEVICE_TABLE(of, hda_tegra_match);
static int hda_tegra_probe(struct platform_device *pdev)
{
const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR |
AZX_DCAPS_PM_RUNTIME;
AZX_DCAPS_PM_RUNTIME |
AZX_DCAPS_4K_BDLE_BOUNDARY;
struct snd_card *card;
struct azx *chip;
struct hda_tegra *hda;
Expand Down
24 changes: 24 additions & 0 deletions sound/pci/hda/patch_sigmatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ struct sigmatel_spec {

/* beep widgets */
hda_nid_t anabeep_nid;
bool beep_power_on;

/* SPDIF-out mux */
const char * const *spdif_labels;
Expand Down Expand Up @@ -4443,6 +4444,28 @@ static int stac_suspend(struct hda_codec *codec)

return 0;
}

static int stac_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
#ifdef CONFIG_SND_HDA_INPUT_BEEP
struct sigmatel_spec *spec = codec->spec;
#endif
int ret = snd_hda_gen_check_power_status(codec, nid);

#ifdef CONFIG_SND_HDA_INPUT_BEEP
if (nid == spec->gen.beep_nid && codec->beep) {
if (codec->beep->enabled != spec->beep_power_on) {
spec->beep_power_on = codec->beep->enabled;
if (spec->beep_power_on)
snd_hda_power_up_pm(codec);
else
snd_hda_power_down_pm(codec);
}
ret |= spec->beep_power_on;
}
#endif
return ret;
}
#else
#define stac_suspend NULL
#endif /* CONFIG_PM */
Expand All @@ -4455,6 +4478,7 @@ static const struct hda_codec_ops stac_patch_ops = {
.unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM
.suspend = stac_suspend,
.check_power_status = stac_check_power_status,
#endif
};

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/atmel/mchp-spdiftx.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ struct mchp_spdiftx_dev {
struct clk *pclk;
struct clk *gclk;
unsigned int fmt;
int gclk_enabled:1;
unsigned int gclk_enabled:1;
};

static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev)
Expand Down
13 changes: 7 additions & 6 deletions sound/soc/codecs/cs42l42.c
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,6 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
unsigned int current_plug_status;
unsigned int current_button_status;
unsigned int i;
int report = 0;

mutex_lock(&cs42l42->irq_lock);
if (cs42l42->suspended) {
Expand Down Expand Up @@ -1711,13 +1710,15 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)

if (current_button_status & CS42L42_M_DETECT_TF_MASK) {
dev_dbg(cs42l42->dev, "Button released\n");
report = 0;
snd_soc_jack_report(cs42l42->jack, 0,
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
} else if (current_button_status & CS42L42_M_DETECT_FT_MASK) {
report = cs42l42_handle_button_press(cs42l42);

snd_soc_jack_report(cs42l42->jack,
cs42l42_handle_button_press(cs42l42),
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
}
snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
}
}

Expand Down
40 changes: 29 additions & 11 deletions sound/soc/codecs/nau8540.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,39 +357,56 @@ static const struct snd_soc_dapm_route nau8540_dapm_routes[] = {
{"AIFTX", NULL, "Digital CH4 Mux"},
};

static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr)
static const struct nau8540_osr_attr *
nau8540_get_osr(struct nau8540 *nau8540)
{
unsigned int osr;

regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr);
osr &= NAU8540_ADC_OSR_MASK;
if (osr >= ARRAY_SIZE(osr_adc_sel))
return -EINVAL;
return NULL;
return &osr_adc_sel[osr];
}

static int nau8540_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
const struct nau8540_osr_attr *osr;

if (rate * osr > CLK_ADC_MAX) {
dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n");
osr = nau8540_get_osr(nau8540);
if (!osr || !osr->osr)
return -EINVAL;
}

return 0;
return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
0, CLK_ADC_MAX / osr->osr);
}

static int nau8540_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr;
unsigned int val_len = 0;
const struct nau8540_osr_attr *osr;

/* CLK_ADC = OSR * FS
* ADC clock frequency is defined as Over Sampling Rate (OSR)
* multiplied by the audio sample rate (Fs). Note that the OSR and Fs
* values must be selected such that the maximum frequency is less
* than 6.144 MHz.
*/
regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr);
osr &= NAU8540_ADC_OSR_MASK;
if (nau8540_clock_check(nau8540, params_rate(params), osr))
osr = nau8540_get_osr(nau8540);
if (!osr || !osr->osr)
return -EINVAL;
if (params_rate(params) * osr->osr > CLK_ADC_MAX)
return -EINVAL;
regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
NAU8540_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT);
osr->clk_src << NAU8540_CLK_ADC_SRC_SFT);

switch (params_width(params)) {
case 16:
Expand Down Expand Up @@ -515,6 +532,7 @@ static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,


static const struct snd_soc_dai_ops nau8540_dai_ops = {
.startup = nau8540_dai_startup,
.hw_params = nau8540_hw_params,
.set_fmt = nau8540_set_fmt,
.set_tdm_slot = nau8540_set_tdm_slot,
Expand Down
66 changes: 36 additions & 30 deletions sound/soc/codecs/nau8821.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,36 +670,49 @@ static const struct snd_soc_dapm_route nau8821_dapm_routes[] = {
{"HPOR", NULL, "Class G"},
};

static int nau8821_clock_check(struct nau8821 *nau8821,
int stream, int rate, int osr)
static const struct nau8821_osr_attr *
nau8821_get_osr(struct nau8821 *nau8821, int stream)
{
int osrate = 0;
unsigned int osr;

if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr);
osr &= NAU8821_DAC_OVERSAMPLE_MASK;
if (osr >= ARRAY_SIZE(osr_dac_sel))
return -EINVAL;
osrate = osr_dac_sel[osr].osr;
return NULL;
return &osr_dac_sel[osr];
} else {
regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr);
osr &= NAU8821_ADC_SYNC_DOWN_MASK;
if (osr >= ARRAY_SIZE(osr_adc_sel))
return -EINVAL;
osrate = osr_adc_sel[osr].osr;
return NULL;
return &osr_adc_sel[osr];
}
}

if (!osrate || rate * osrate > CLK_DA_AD_MAX) {
dev_err(nau8821->dev,
"exceed the maximum frequency of CLK_ADC or CLK_DAC");
static int nau8821_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
const struct nau8821_osr_attr *osr;

osr = nau8821_get_osr(nau8821, substream->stream);
if (!osr || !osr->osr)
return -EINVAL;
}

return 0;
return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
0, CLK_DA_AD_MAX / osr->osr);
}

static int nau8821_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, clk_div;
unsigned int val_len = 0, ctrl_val, bclk_fs, clk_div;
const struct nau8821_osr_attr *osr;

nau8821->fs = params_rate(params);
/* CLK_DAC or CLK_ADC = OSR * FS
Expand All @@ -708,27 +721,19 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream,
* values must be selected such that the maximum frequency is less
* than 6.144 MHz.
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr);
osr &= NAU8821_DAC_OVERSAMPLE_MASK;
if (nau8821_clock_check(nau8821, substream->stream,
nau8821->fs, osr)) {
return -EINVAL;
}
osr = nau8821_get_osr(nau8821, substream->stream);
if (!osr || !osr->osr)
return -EINVAL;
if (nau8821->fs * osr->osr > CLK_DA_AD_MAX)
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER,
NAU8821_CLK_DAC_SRC_MASK,
osr_dac_sel[osr].clk_src << NAU8821_CLK_DAC_SRC_SFT);
} else {
regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr);
osr &= NAU8821_ADC_SYNC_DOWN_MASK;
if (nau8821_clock_check(nau8821, substream->stream,
nau8821->fs, osr)) {
return -EINVAL;
}
osr->clk_src << NAU8821_CLK_DAC_SRC_SFT);
else
regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER,
NAU8821_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8821_CLK_ADC_SRC_SFT);
}
osr->clk_src << NAU8821_CLK_ADC_SRC_SFT);

/* make BCLK and LRC divde configuration if the codec as master. */
regmap_read(nau8821->regmap, NAU8821_R1D_I2S_PCM_CTRL2, &ctrl_val);
Expand Down Expand Up @@ -843,6 +848,7 @@ static int nau8821_digital_mute(struct snd_soc_dai *dai, int mute,
}

static const struct snd_soc_dai_ops nau8821_dai_ops = {
.startup = nau8821_dai_startup,
.hw_params = nau8821_hw_params,
.set_fmt = nau8821_set_dai_fmt,
.mute_stream = nau8821_digital_mute,
Expand Down
Loading

0 comments on commit 83dfc0e

Please sign in to comment.