Message ID | 1448992031-8271-6-git-send-email-subhransu.s.prusty@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, 01 Dec 2015 18:47:02 +0100, Subhransu S. Prusty wrote: > > +static int eld_limit_formats(struct snd_pcm_runtime *runtime, void *eld) > +{ > + u64 formats = SNDRV_PCM_FMTBIT_S16_LE; > + int i; > + const u8 *sad, *eld_buf = eld; > + > + sad = drm_eld_sad(eld_buf); > + if (!sad) > + goto format_constraint; > + > + for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) { > + if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */ > + > + /* 20 bit */ > + if (sad_sample_bits_lpcm(sad) & 0x2) > + formats |= SNDRV_PCM_FMTBIT_S32_LE; > + > + /* 24 bit */ > + if (sad_sample_bits_lpcm(sad) & 0x4) > + formats |= SNDRV_PCM_FMTBIT_S24_LE; Does it work correctly with HD-audio...? Takashi
On Wed, 02 Dec 2015 13:27:21 +0100, Subhransu S. Prusty wrote: > > On Tue, Dec 01, 2015 at 01:55:03PM +0100, Takashi Iwai wrote: > > On Tue, 01 Dec 2015 18:47:02 +0100, > > Subhransu S. Prusty wrote: > > > > > > +static int eld_limit_formats(struct snd_pcm_runtime *runtime, void *eld) > > > +{ > > > + u64 formats = SNDRV_PCM_FMTBIT_S16_LE; > > > + int i; > > > + const u8 *sad, *eld_buf = eld; > > > + > > > + sad = drm_eld_sad(eld_buf); > > > + if (!sad) > > > + goto format_constraint; > > > + > > > + for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) { > > > + if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */ > > > + > > > + /* 20 bit */ > > > + if (sad_sample_bits_lpcm(sad) & 0x2) > > > + formats |= SNDRV_PCM_FMTBIT_S32_LE; > > > + > > > + /* 24 bit */ > > > + if (sad_sample_bits_lpcm(sad) & 0x4) > > > + formats |= SNDRV_PCM_FMTBIT_S24_LE; > > > > Does it work correctly with HD-audio...? > > It works correctly. Do you suspect something wrong? Traditionally, 24bit is supported by S32 format on HDA controller, so I wonder it. Takashi
On Tue, Dec 01, 2015 at 01:55:03PM +0100, Takashi Iwai wrote: > On Tue, 01 Dec 2015 18:47:02 +0100, > Subhransu S. Prusty wrote: > > > > +static int eld_limit_formats(struct snd_pcm_runtime *runtime, void *eld) > > +{ > > + u64 formats = SNDRV_PCM_FMTBIT_S16_LE; > > + int i; > > + const u8 *sad, *eld_buf = eld; > > + > > + sad = drm_eld_sad(eld_buf); > > + if (!sad) > > + goto format_constraint; > > + > > + for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) { > > + if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */ > > + > > + /* 20 bit */ > > + if (sad_sample_bits_lpcm(sad) & 0x2) > > + formats |= SNDRV_PCM_FMTBIT_S32_LE; > > + > > + /* 24 bit */ > > + if (sad_sample_bits_lpcm(sad) & 0x4) > > + formats |= SNDRV_PCM_FMTBIT_S24_LE; > > Does it work correctly with HD-audio...? It works correctly. Do you suspect something wrong? > > > Takashi
diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c index e70379f..0c5653e 100644 --- a/sound/core/pcm_drm_eld.c +++ b/sound/core/pcm_drm_eld.c @@ -20,11 +20,49 @@ static const unsigned int eld_rates[] = { 192000, }; +static unsigned int sad_format(const u8 *sad) +{ + return ((sad[0] >> 0x3) & 0x1f); +} + +static unsigned int sad_sample_bits_lpcm(const u8 *sad) +{ + return (sad[2] & 7); +} + static unsigned int sad_max_channels(const u8 *sad) { return 1 + (sad[0] & 7); } +static int eld_limit_formats(struct snd_pcm_runtime *runtime, void *eld) +{ + u64 formats = SNDRV_PCM_FMTBIT_S16_LE; + int i; + const u8 *sad, *eld_buf = eld; + + sad = drm_eld_sad(eld_buf); + if (!sad) + goto format_constraint; + + for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) { + if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */ + + /* 20 bit */ + if (sad_sample_bits_lpcm(sad) & 0x2) + formats |= SNDRV_PCM_FMTBIT_S32_LE; + + /* 24 bit */ + if (sad_sample_bits_lpcm(sad) & 0x4) + formats |= SNDRV_PCM_FMTBIT_S24_LE; + } + } + +format_constraint: + return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, + formats); +} + static int eld_limit_rates(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { @@ -93,7 +131,9 @@ int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime *runtime, void *eld) ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, eld_limit_channels, eld, SNDRV_PCM_HW_PARAM_RATE, -1); + if (ret < 0) + return ret; - return ret; + return eld_limit_formats(runtime, eld); } EXPORT_SYMBOL_GPL(snd_pcm_hw_constraint_eld);