[alsa-devel] [PATCH] ASoC: max98090: support 20-bit and 24-bit audio format
From datasheet of max98090:
If RJ = 1, WS = 00, 16 bits WS = 01, 20 bits WS = 10, 24 bits
Signed-off-by: Tzung-Bi Shih tzungbi@google.com --- sound/soc/codecs/max98090.c | 16 +++++++++++++++- sound/soc/codecs/max98090.h | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index c97f21836c66..0ecc2f1accb5 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1942,7 +1942,21 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, switch (params_width(params)) { case 16: snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT, - M98090_WS_MASK, 0); + M98090_RJ_MASK, M98090_RJ_MASK); + snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT, + M98090_WS_MASK, M98090_FORMAT_S16_LE); + break; + case 20: + snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT, + M98090_RJ_MASK, M98090_RJ_MASK); + snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT, + M98090_WS_MASK, M98090_FORMAT_S20_LE; + break; + case 24: + snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT, + M98090_RJ_MASK, M98090_RJ_MASK); + snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT, + M98090_WS_MASK, M98090_FORMAT_S24_LE); break; default: return -EINVAL; diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index b1572a2d19da..9088f9d64ff2 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h @@ -706,6 +706,9 @@ #define M98090_WS_SHIFT 0 #define M98090_WS_WIDTH 2 #define M98090_WS_NUM (1<<M98090_WS_WIDTH) +#define M98090_FORMAT_S16_LE (0<<0) +#define M98090_FORMAT_S20_LE (1<<0) +#define M98090_FORMAT_S24_LE (2<<0)
/* * M98090_REG_TDM_CONTROL
Missing a parenthesis for M98090_FORMAT_S20_LE. Please ignore this patch.
On Mon, Jan 28, 2019 at 5:15 PM Tzung-Bi Shih tzungbi@google.com wrote:
From datasheet of max98090: If RJ = 1, WS = 00, 16 bits WS = 01, 20 bits WS = 10, 24 bits
Signed-off-by: Tzung-Bi Shih tzungbi@google.com
sound/soc/codecs/max98090.c | 16 +++++++++++++++- sound/soc/codecs/max98090.h | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index c97f21836c66..0ecc2f1accb5 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1942,7 +1942,21 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, switch (params_width(params)) { case 16: snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, 0);
M98090_RJ_MASK, M98090_RJ_MASK);
snd_soc_component_update_bits(component,
M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, M98090_FORMAT_S16_LE);
break;
case 20:
snd_soc_component_update_bits(component,
M98090_REG_INTERFACE_FORMAT,
M98090_RJ_MASK, M98090_RJ_MASK);
snd_soc_component_update_bits(component,
M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, M98090_FORMAT_S20_LE;
break;
case 24:
snd_soc_component_update_bits(component,
M98090_REG_INTERFACE_FORMAT,
M98090_RJ_MASK, M98090_RJ_MASK);
snd_soc_component_update_bits(component,
M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, M98090_FORMAT_S24_LE); break; default: return -EINVAL;
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index b1572a2d19da..9088f9d64ff2 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h @@ -706,6 +706,9 @@ #define M98090_WS_SHIFT 0 #define M98090_WS_WIDTH 2 #define M98090_WS_NUM (1<<M98090_WS_WIDTH) +#define M98090_FORMAT_S16_LE (0<<0) +#define M98090_FORMAT_S20_LE (1<<0) +#define M98090_FORMAT_S24_LE (2<<0)
/*
- M98090_REG_TDM_CONTROL
-- 2.20.1.495.gaa96b0ce6b-goog
On 1/28/19 3:15 AM, Tzung-Bi Shih wrote:
From datasheet of max98090: If RJ = 1, WS = 00, 16 bits WS = 01, 20 bits WS = 10, 24 bits
Yes, but there is a if (Right Justified)
DAI Input Data Word Size (TDM = 0)
If RJ = 1: 00: 16 bits 01: 20 bits 10: 24 bits 11: Reserved
If RJ = 0: 00: 16 bits 01, 10, 11: 20 bits
You can't arbitrarily set the RJ bit without having the SOC know about it - this should be conditional on the DAI format already used elsewhere:
case SND_SOC_DAIFMT_RIGHT_J: regval |= M98090_RJ_MASK; break;
I also vaguely recall there were limitations on capture with an odd format being used?
Signed-off-by: Tzung-Bi Shih tzungbi@google.com
sound/soc/codecs/max98090.c | 16 +++++++++++++++- sound/soc/codecs/max98090.h | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index c97f21836c66..0ecc2f1accb5 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1942,7 +1942,21 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, switch (params_width(params)) { case 16: snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, 0);
M98090_RJ_MASK, M98090_RJ_MASK);
snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, M98090_FORMAT_S16_LE);
break;
- case 20:
snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_RJ_MASK, M98090_RJ_MASK);
snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, M98090_FORMAT_S20_LE;
break;
- case 24:
snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_RJ_MASK, M98090_RJ_MASK);
snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
break; default: return -EINVAL;M98090_WS_MASK, M98090_FORMAT_S24_LE);
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index b1572a2d19da..9088f9d64ff2 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h @@ -706,6 +706,9 @@ #define M98090_WS_SHIFT 0 #define M98090_WS_WIDTH 2 #define M98090_WS_NUM (1<<M98090_WS_WIDTH) +#define M98090_FORMAT_S16_LE (0<<0) +#define M98090_FORMAT_S20_LE (1<<0) +#define M98090_FORMAT_S24_LE (2<<0)
/*
- M98090_REG_TDM_CONTROL
participants (2)
-
Pierre-Louis Bossart
-
Tzung-Bi Shih