diff options
Diffstat (limited to 'sound/hda')
-rw-r--r-- | sound/hda/hdac_component.c | 7 | ||||
-rw-r--r-- | sound/hda/hdac_stream.c | 63 |
2 files changed, 40 insertions, 30 deletions
diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c index bb37e7e0bd79..9c82a2864a2f 100644 --- a/sound/hda/hdac_component.c +++ b/sound/hda/hdac_component.c @@ -5,6 +5,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/component.h> +#include <linux/string_choices.h> #include <sound/core.h> #include <sound/hdaudio.h> #include <sound/hda_component.h> @@ -42,8 +43,7 @@ int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) if (!acomp->ops->codec_wake_override) return 0; - dev_dbg(bus->dev, "%s codec wakeup\n", - enable ? "enable" : "disable"); + dev_dbg(bus->dev, "%s codec wakeup\n", str_enable_disable(enable)); acomp->ops->codec_wake_override(acomp->dev, enable); @@ -67,8 +67,7 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) { struct drm_audio_component *acomp = bus->audio_component; - dev_dbg(bus->dev, "display power %s\n", - enable ? "enable" : "disable"); + dev_dbg(bus->dev, "display power %s\n", str_enable_disable(enable)); mutex_lock(&bus->lock); if (enable) diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 2670792f43b4..4e85a838ad7e 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -492,32 +492,21 @@ static int setup_bdle(struct hdac_bus *bus, } /** - * snd_hdac_stream_setup_periods - set up BDL entries + * snd_hdac_stream_setup_bdle - set up BDL entries * @azx_dev: HD-audio core stream to set up + * @dmab: allocated DMA buffer + * @runtime: substream runtime, optional * * Set up the buffer descriptor table of the given stream based on the * period and buffer sizes of the assigned PCM substream. */ -int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) +static int snd_hdac_stream_setup_bdle(struct hdac_stream *azx_dev, struct snd_dma_buffer *dmab, + struct snd_pcm_runtime *runtime) { struct hdac_bus *bus = azx_dev->bus; - struct snd_pcm_substream *substream = azx_dev->substream; - struct snd_compr_stream *cstream = azx_dev->cstream; - struct snd_pcm_runtime *runtime = NULL; - struct snd_dma_buffer *dmab; - __le32 *bdl; int i, ofs, periods, period_bytes; int pos_adj, pos_align; - - if (substream) { - runtime = substream->runtime; - dmab = snd_pcm_get_dma_buf(substream); - } else if (cstream) { - dmab = snd_pcm_get_dma_buf(cstream); - } else { - WARN(1, "No substream or cstream assigned\n"); - return -EINVAL; - } + __le32 *bdl; /* reset BDL address */ snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0); @@ -571,6 +560,33 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) azx_dev->bufsize, period_bytes); return -EINVAL; } + +/** + * snd_hdac_stream_setup_periods - set up BDL entries + * @azx_dev: HD-audio core stream to set up + * + * Set up the buffer descriptor table of the given stream based on the + * period and buffer sizes of the assigned PCM substream. + */ +int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) +{ + struct snd_pcm_substream *substream = azx_dev->substream; + struct snd_compr_stream *cstream = azx_dev->cstream; + struct snd_pcm_runtime *runtime = NULL; + struct snd_dma_buffer *dmab; + + if (substream) { + runtime = substream->runtime; + dmab = snd_pcm_get_dma_buf(substream); + } else if (cstream) { + dmab = snd_pcm_get_dma_buf(cstream); + } else { + WARN(1, "No substream or cstream assigned\n"); + return -EINVAL; + } + + return snd_hdac_stream_setup_bdle(azx_dev, dmab, runtime); +} EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods); /** @@ -923,7 +939,6 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, unsigned int byte_size, struct snd_dma_buffer *bufp) { struct hdac_bus *bus = azx_dev->bus; - __le32 *bdl; int err; snd_hdac_dsp_lock(azx_dev); @@ -943,18 +958,14 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, azx_dev->substream = NULL; azx_dev->bufsize = byte_size; - azx_dev->period_bytes = byte_size; + /* It is recommended to transfer the firmware in two or more chunks. */ + azx_dev->period_bytes = byte_size / 2; azx_dev->format_val = format; + azx_dev->no_period_wakeup = 1; snd_hdac_stream_reset(azx_dev); - /* reset BDL address */ - snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0); - snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0); - - azx_dev->frags = 0; - bdl = (__le32 *)azx_dev->bdl.area; - err = setup_bdle(bus, bufp, azx_dev, &bdl, 0, byte_size, 0); + err = snd_hdac_stream_setup_bdle(azx_dev, bufp, NULL); if (err < 0) goto error; |