summaryrefslogtreecommitdiffstats
path: root/sound/x86
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-02-07 07:33:17 -0500
committerTakashi Iwai <tiwai@suse.de>2017-02-10 04:21:45 -0500
commit85bd8748ca23a25f6dc56154d9a61d87ae07a807 (patch)
tree41ceaabf4346242990688b98e737fb05d0ddea6e /sound/x86
parente8de9859e4e834a74da824e13070aa992c32de10 (diff)
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 = {
135 SNDRV_PCM_INFO_MMAP | 135 SNDRV_PCM_INFO_MMAP |
136 SNDRV_PCM_INFO_MMAP_VALID | 136 SNDRV_PCM_INFO_MMAP_VALID |
137 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), 137 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
138 .formats = SNDRV_PCM_FMTBIT_S24, 138 .formats = (SNDRV_PCM_FMTBIT_S24_LE |
139 SNDRV_PCM_FMTBIT_S32_LE),
139 .rates = SNDRV_PCM_RATE_32000 | 140 .rates = SNDRV_PCM_RATE_32000 |
140 SNDRV_PCM_RATE_44100 | 141 SNDRV_PCM_RATE_44100 |
141 SNDRV_PCM_RATE_48000 | 142 SNDRV_PCM_RATE_48000 |
@@ -249,7 +250,6 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream,
249 union aud_cfg cfg_val = {.regval = 0}; 250 union aud_cfg cfg_val = {.regval = 0};
250 union aud_ch_status_0 ch_stat0 = {.regval = 0}; 251 union aud_ch_status_0 ch_stat0 = {.regval = 0};
251 union aud_ch_status_1 ch_stat1 = {.regval = 0}; 252 union aud_ch_status_1 ch_stat1 = {.regval = 0};
252 int format;
253 253
254 ch_stat0.regx.lpcm_id = (intelhaddata->aes_bits & 254 ch_stat0.regx.lpcm_id = (intelhaddata->aes_bits &
255 IEC958_AES0_NONAUDIO) >> 1; 255 IEC958_AES0_NONAUDIO) >> 1;
@@ -289,17 +289,20 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream,
289 had_write_register(intelhaddata, 289 had_write_register(intelhaddata,
290 AUD_CH_STATUS_0, ch_stat0.regval); 290 AUD_CH_STATUS_0, ch_stat0.regval);
291 291
292 format = substream->runtime->format; 292 switch (substream->runtime->format) {
293 293#if 0 /* FIXME: not supported yet */
294 if (format == SNDRV_PCM_FORMAT_S16_LE) { 294 case SNDRV_PCM_FORMAT_S16_LE:
295 ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_20; 295 ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_20;
296 ch_stat1.regx.wrd_len = SMPL_WIDTH_16BITS; 296 ch_stat1.regx.wrd_len = SMPL_WIDTH_16BITS;
297 } else if (format == SNDRV_PCM_FORMAT_S24_LE) { 297 break;
298#endif
299 case SNDRV_PCM_FORMAT_S24_LE:
300 case SNDRV_PCM_FORMAT_S32_LE:
298 ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_24; 301 ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_24;
299 ch_stat1.regx.wrd_len = SMPL_WIDTH_24BITS; 302 ch_stat1.regx.wrd_len = SMPL_WIDTH_24BITS;
300 } else { 303 break;
301 ch_stat1.regx.max_wrd_len = 0; 304 default:
302 ch_stat1.regx.wrd_len = 0; 305 return -EINVAL;
303 } 306 }
304 307
305 had_write_register(intelhaddata, 308 had_write_register(intelhaddata,
@@ -333,6 +336,9 @@ static int had_init_audio_ctrl(struct snd_pcm_substream *substream,
333 else 336 else
334 cfg_val.regx.layout = LAYOUT1; 337 cfg_val.regx.layout = LAYOUT1;
335 338
339 if (substream->runtime->format == SNDRV_PCM_FORMAT_S32_LE)
340 cfg_val.regx.left_align = 1;
341
336 cfg_val.regx.val_bit = 1; 342 cfg_val.regx.val_bit = 1;
337 343
338 /* fix up the DP bits */ 344 /* fix up the DP bits */
@@ -1050,6 +1056,10 @@ static int had_pcm_open(struct snd_pcm_substream *substream)
1050 if (retval < 0) 1056 if (retval < 0)
1051 goto error; 1057 goto error;
1052 1058
1059 retval = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1060 if (retval < 0)
1061 goto error;
1062
1053 /* expose PCM substream */ 1063 /* expose PCM substream */
1054 spin_lock_irq(&intelhaddata->had_spinlock); 1064 spin_lock_irq(&intelhaddata->had_spinlock);
1055 intelhaddata->stream_info.substream = substream; 1065 intelhaddata->stream_info.substream = substream;