summaryrefslogtreecommitdiff
path: root/sound/x86
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-02-07 15:33:17 +0300
committerTakashi Iwai <tiwai@suse.de>2017-02-10 12:21:45 +0300
commit85bd8748ca23a25f6dc56154d9a61d87ae07a807 (patch)
tree41ceaabf4346242990688b98e737fb05d0ddea6e /sound/x86
parente8de9859e4e834a74da824e13070aa992c32de10 (diff)
downloadlinux-85bd8748ca23a25f6dc56154d9a61d87ae07a807.tar.xz
ALSA: x86: Support S32 format
The hardware has the support for the left-aligned 24bit format in 32bit packet. This corresponds to S32 format in ALSA. We need to set the msbits restriction as well to inform user-space that only MSB 24bit are available. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/x86')
-rw-r--r--sound/x86/intel_hdmi_audio.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index 80b1ab9b1c57..e8f8be2f590b 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -135,7 +135,8 @@ static const struct snd_pcm_hardware had_pcm_hardware = {
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
- .formats = SNDRV_PCM_FMTBIT_S24,
+ .formats = (SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rates = SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
@@ -249,7 +250,6 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream,
union aud_cfg cfg_val = {.regval = 0};
union aud_ch_status_0 ch_stat0 = {.regval = 0};
union aud_ch_status_1 ch_stat1 = {.regval = 0};
- int format;
ch_stat0.regx.lpcm_id = (intelhaddata->aes_bits &
IEC958_AES0_NONAUDIO) >> 1;
@@ -289,17 +289,20 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream,
had_write_register(intelhaddata,
AUD_CH_STATUS_0, ch_stat0.regval);
- format = substream->runtime->format;
-
- if (format == SNDRV_PCM_FORMAT_S16_LE) {
+ switch (substream->runtime->format) {
+#if 0 /* FIXME: not supported yet */
+ case SNDRV_PCM_FORMAT_S16_LE:
ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_20;
ch_stat1.regx.wrd_len = SMPL_WIDTH_16BITS;
- } else if (format == SNDRV_PCM_FORMAT_S24_LE) {
+ break;
+#endif
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S32_LE:
ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_24;
ch_stat1.regx.wrd_len = SMPL_WIDTH_24BITS;
- } else {
- ch_stat1.regx.max_wrd_len = 0;
- ch_stat1.regx.wrd_len = 0;
+ break;
+ default:
+ return -EINVAL;
}
had_write_register(intelhaddata,
@@ -333,6 +336,9 @@ static int had_init_audio_ctrl(struct snd_pcm_substream *substream,
else
cfg_val.regx.layout = LAYOUT1;
+ if (substream->runtime->format == SNDRV_PCM_FORMAT_S32_LE)
+ cfg_val.regx.left_align = 1;
+
cfg_val.regx.val_bit = 1;
/* fix up the DP bits */
@@ -1050,6 +1056,10 @@ static int had_pcm_open(struct snd_pcm_substream *substream)
if (retval < 0)
goto error;
+ retval = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+ if (retval < 0)
+ goto error;
+
/* expose PCM substream */
spin_lock_irq(&intelhaddata->had_spinlock);
intelhaddata->stream_info.substream = substream;