summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/hdaudio.h3
-rw-r--r--sound/hda/hdac_stream.c34
2 files changed, 37 insertions, 0 deletions
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index b4fa1c775251..45f944d57982 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -539,6 +539,9 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
unsigned int streams);
void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
unsigned int streams);
+int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
+ struct snd_pcm_substream *substream);
+
/*
* macros for easy use
*/
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index ba73a33480b6..820694a2061e 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -13,6 +13,40 @@
#include "trace.h"
/**
+ * snd_hdac_get_stream_stripe_ctl - get stripe control value
+ * @bus: HD-audio core bus
+ * @substream: PCM substream
+ */
+int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned int channels = runtime->channels,
+ rate = runtime->rate,
+ bits_per_sample = runtime->sample_bits,
+ max_sdo_lines, value, sdo_line;
+
+ /* T_AZA_GCAP_NSDO is 1:2 bitfields in GCAP */
+ max_sdo_lines = snd_hdac_chip_readl(bus, GCAP) & AZX_GCAP_NSDO;
+
+ /* following is from HD audio spec */
+ for (sdo_line = max_sdo_lines; sdo_line > 0; sdo_line >>= 1) {
+ if (rate > 48000)
+ value = (channels * bits_per_sample *
+ (rate / 48000)) / sdo_line;
+ else
+ value = (channels * bits_per_sample) / sdo_line;
+
+ if (value >= 8)
+ break;
+ }
+
+ /* stripe value: 0 for 1SDO, 1 for 2SDO, 2 for 4SDO lines */
+ return sdo_line >> 1;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_get_stream_stripe_ctl);
+
+/**
* snd_hdac_stream_init - initialize each stream (aka device)
* @bus: HD-audio core bus
* @azx_dev: HD-audio core stream object to initialize