All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format
@ 2017-09-01 21:35 Ryan Lee
  2017-09-01 21:35 ` [PATCH 2/3] ASoC: max98927: Added controls for Envelope tracking Ryan Lee
  2017-09-01 21:35 ` [PATCH 3/3] ASoC: max98927: Removed obsolete variables Ryan Lee
  0 siblings, 2 replies; 7+ messages in thread
From: Ryan Lee @ 2017-09-01 21:35 UTC (permalink / raw)
  To: lgirdwood, broonie, perex, tiwai, ryans.lee,
	kuninori.morimoto.gx, alsa-devel, linux-kernel
  Cc: ryan.lee.maxim

Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
---
Changelog: 
	Added support for DSP_A and DSP_B format
    Added 'max98927_dai_tdm_slot' function to configure for proper slot configuration.
    Moved max98927->iface out of switch statement to avoid line duplication.
	Added variable 'tdm_mode' to avoid BCLK overwrite after 'max98927_dai_tdm_slot' configure right BCLK value.

 sound/soc/codecs/max98927.c | 155 +++++++++++++++++++++++++++++++++++---------
 sound/soc/codecs/max98927.h |   7 +-
 2 files changed, 129 insertions(+), 33 deletions(-)

diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index d9dbbe7..a1d3935 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -1,7 +1,7 @@
 /*
  * max98927.c  --  MAX98927 ALSA Soc Audio driver
  *
- * Copyright (C) 2016 Maxim Integrated Products
+ * Copyright (C) 2016-2017 Maxim Integrated Products
  * Author: Ryan Lee <ryans.lee@maximintegrated.com>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -146,6 +146,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
 	unsigned int mode = 0;
 	unsigned int format = 0;
+	bool use_pdm = false;
 	unsigned int invert = 0;
 
 	dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
@@ -187,22 +188,27 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		max98927->iface |= SND_SOC_DAIFMT_I2S;
 		format = MAX98927_PCM_FORMAT_I2S;
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
-		max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
 		format = MAX98927_PCM_FORMAT_LJ;
 		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		format = MAX98927_PCM_FORMAT_TDM_MODE1;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		format = MAX98927_PCM_FORMAT_TDM_MODE0;
+		break;
 	case SND_SOC_DAIFMT_PDM:
-		max98927->iface |= SND_SOC_DAIFMT_PDM;
+		use_pdm = true;
 		break;
 	default:
 		return -EINVAL;
 	}
+	max98927->iface = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
-	/* pcm channel configuration */
-	if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
+	if (!use_pdm) {
+		/* pcm channel configuration */
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R0018_PCM_RX_EN_A,
 			MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
@@ -217,13 +223,11 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 			MAX98927_R003B_SPK_SRC_SEL,
 			MAX98927_SPK_SRC_MASK, 0);
 
-	} else
 		regmap_update_bits(max98927->regmap,
-			MAX98927_R0018_PCM_RX_EN_A,
-			MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
-
-	/* pdm channel configuration */
-	if (max98927->iface & SND_SOC_DAIFMT_PDM) {
+			MAX98927_R0035_PDM_RX_CTRL,
+			MAX98927_PDM_RX_EN_MASK, 0);
+	} else {
+		/* pdm channel configuration */
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R0035_PDM_RX_CTRL,
 			MAX98927_PDM_RX_EN_MASK, 1);
@@ -231,10 +235,11 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R003B_SPK_SRC_SEL,
 			MAX98927_SPK_SRC_MASK, 3);
-	} else
+
 		regmap_update_bits(max98927->regmap,
-			MAX98927_R0035_PDM_RX_CTRL,
-			MAX98927_PDM_RX_EN_MASK, 0);
+			MAX98927_R0018_PCM_RX_EN_A,
+			MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
+	}
 	return 0;
 }
 
@@ -245,6 +250,21 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	13000000, 19200000,
 };
 
+/* BCLKs per LRCLK */
+static const int bclk_sel_table[] = {
+	32, 48, 64, 96, 128, 192, 256, 384, 512,
+};
+
+static int max98927_get_bclk_sel(int bclk)
+{
+	int i;
+	/* match BCLKs per LRCLK */
+	for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
+		if (bclk_sel_table[i] == bclk)
+			return i + 2;
+	}
+	return 0;
+}
 static int max98927_set_clock(struct max98927_priv *max98927,
 	struct snd_pcm_hw_params *params)
 {
@@ -270,23 +290,20 @@ static int max98927_set_clock(struct max98927_priv *max98927,
 			i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
 	}
 
-	switch (blr_clk_ratio) {
-	case 32:
-		value = 2;
-		break;
-	case 48:
-		value = 3;
-		break;
-	case 64:
-		value = 4;
-		break;
-	default:
-		return -EINVAL;
+	if (!max98927->tdm_mode) {
+		/* BCLK configuration */
+		value = max98927_get_bclk_sel(blr_clk_ratio);
+		if (!value) {
+			dev_err(codec->dev, "format unsupported %d\n",
+				params_format(params));
+			return -EINVAL;
+		}
+
+		regmap_update_bits(max98927->regmap,
+			MAX98927_R0022_PCM_CLK_SETUP,
+			MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+			value);
 	}
-	regmap_update_bits(max98927->regmap,
-		MAX98927_R0022_PCM_CLK_SETUP,
-		MAX98927_PCM_CLK_SETUP_BSEL_MASK,
-		value);
 	return 0;
 }
 
@@ -386,6 +403,78 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
 	return -EINVAL;
 }
 
+static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
+	unsigned int tx_mask, unsigned int rx_mask,
+	int slots, int slot_width)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	int bsel = 0;
+	unsigned int chan_sz = 0;
+
+	max98927->tdm_mode = true;
+
+	/* BCLK configuration */
+	bsel = max98927_get_bclk_sel(slots * slot_width);
+	if (bsel == 0) {
+		dev_err(codec->dev, "BCLK %d not supported\n",
+			slots * slot_width);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(max98927->regmap,
+		MAX98927_R0022_PCM_CLK_SETUP,
+		MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+		bsel);
+
+	/* Channel size configuration */
+	switch (slot_width) {
+	case 16:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
+		break;
+	case 24:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
+		break;
+	case 32:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
+		break;
+	default:
+		dev_err(codec->dev, "format unsupported %d\n",
+			slot_width);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(max98927->regmap,
+		MAX98927_R0020_PCM_MODE_CFG,
+		MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
+
+	/* Rx slot configuration */
+	regmap_write(max98927->regmap,
+		MAX98927_R0018_PCM_RX_EN_A,
+		rx_mask & 0xFF);
+	regmap_write(max98927->regmap,
+		MAX98927_R0019_PCM_RX_EN_B,
+		(rx_mask & 0xFF00) >> 8);
+
+	/* Tx slot configuration */
+	regmap_write(max98927->regmap,
+		MAX98927_R001A_PCM_TX_EN_A,
+		tx_mask & 0xFF);
+	regmap_write(max98927->regmap,
+		MAX98927_R001B_PCM_TX_EN_B,
+		(tx_mask & 0xFF00) >> 8);
+
+	/* Tx slot Hi-Z configuration */
+	regmap_write(max98927->regmap,
+		MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+		~tx_mask & 0xFF);
+	regmap_write(max98927->regmap,
+		MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+		(~tx_mask & 0xFF00) >> 8);
+
+	return 0;
+}
+
 #define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
 
 #define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -405,6 +494,7 @@ static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
 	.set_sysclk = max98927_dai_set_sysclk,
 	.set_fmt = max98927_dai_set_fmt,
 	.hw_params = max98927_dai_hw_params,
+	.set_tdm_slot = max98927_dai_tdm_slot,
 };
 
 static int max98927_dac_event(struct snd_soc_dapm_widget *w,
@@ -414,6 +504,9 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
 	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
 
 	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		max98927->tdm_mode = 0;
+		break;
 	case SND_SOC_DAPM_POST_PMU:
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R003A_AMP_EN,
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index ece6a60..9ea8397 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -1,7 +1,7 @@
 /*
  * max98927.h  --  MAX98927 ALSA Soc Audio driver
  *
- * Copyright 2013-15 Maxim Integrated Products
+ * Copyright (C) 2016-2017 Maxim Integrated Products
  * Author: Ryan Lee <ryans.lee@maximintegrated.com>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -161,7 +161,9 @@
 #define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
 #define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
 #define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
-
+#define MAX98927_PCM_FORMAT_TDM_MODE0 (0x3 << 0)
+#define MAX98927_PCM_FORMAT_TDM_MODE1 (0x4 << 0)
+#define MAX98927_PCM_FORMAT_TDM_MODE2 (0x5 << 0)
 #define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
 #define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
 #define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
@@ -268,5 +270,6 @@ struct max98927_priv {
 	unsigned int iface;
 	unsigned int master;
 	unsigned int digital_gain;
+	bool tdm_mode;
 };
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] ASoC: max98927: Added controls for Envelope tracking
  2017-09-01 21:35 [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format Ryan Lee
@ 2017-09-01 21:35 ` Ryan Lee
  2017-09-01 21:35 ` [PATCH 3/3] ASoC: max98927: Removed obsolete variables Ryan Lee
  1 sibling, 0 replies; 7+ messages in thread
From: Ryan Lee @ 2017-09-01 21:35 UTC (permalink / raw)
  To: lgirdwood, broonie, perex, tiwai, ryans.lee,
	kuninori.morimoto.gx, alsa-devel, linux-kernel
  Cc: ryan.lee.maxim

Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
---
Changelog:
	Added one control to set different headroom value for envelop tracking function.
    Added one more control to enable/disable envelop tracking function.
    Removed writing process to register 0x0087 because it is read only register.

 sound/soc/codecs/max98927.c | 19 +++++++++++++++----
 sound/soc/codecs/max98927.h |  4 ++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index a1d3935..73c7a33 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -624,6 +624,18 @@ static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
 		MAX98927_R0042_BOOST_CTRL1, 1,
 		max98927_current_limit_text);
 
+static const char * const max98927_env_track_headroom_text[] = {
+	"0.000V", "0.125V", "0.250V", "0.375V", "0.500V", "0.625V",
+	"0.750V", "0.875V", "1.000V", "1.125V", "1.250V", "1.375V",
+	"1.500V", "1.625V", "1.750V", "1.875V", "2.000V", "2.125V",
+	"2.250V", "2.375V", "2.500V", "2.625V", "2.750V", "2.875V",
+	"3.000V", "3.125V", "3.250V", "3.375V", "3.500V"
+};
+
+static SOC_ENUM_SINGLE_DECL(max98927_env_track_headroom,
+		MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, 0,
+		max98927_env_track_headroom_text);
+
 static const struct snd_kcontrol_new max98927_snd_controls[] = {
 	SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
 		0, 6, 0,
@@ -641,6 +653,9 @@ static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
 		MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
 	SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
 	SOC_ENUM("Current Limit", max98927_current_limit),
+	SOC_SINGLE("EnvTrack Switch", MAX98927_R0086_ENV_TRACK_CTRL,
+		MAX98927_ENV_TRACKER_EN_SHIFT, 1, 0),
+	SOC_ENUM("EnvTrack Headroom", max98927_env_track_headroom),
 };
 
 static const struct snd_soc_dapm_route max98927_audio_map[] = {
@@ -744,10 +759,6 @@ static int max98927_probe(struct snd_soc_codec *codec)
 	regmap_write(max98927->regmap,
 		MAX98927_R0086_ENV_TRACK_CTRL,
 		0x01);
-	regmap_write(max98927->regmap,
-		MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
-		0x10);
-
 	/* voltage, current slot configuration */
 	regmap_write(max98927->regmap,
 		MAX98927_R001E_PCM_TX_CH_SRC_A,
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index 9ea8397..98b5f17 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -250,6 +250,10 @@
 #define MAX98927_BROWNOUT_DSP_EN (0x1 << 2)
 #define MAX98927_BROWNOUT_DSP_SHIFT (2)
 
+/* MAX98927_R0086_ENV_TRACK_CTRL */
+#define MAX98927_ENV_TRACKER_EN (0x1 << 0)
+#define MAX98927_ENV_TRACKER_EN_SHIFT (0)
+
 /* MAX98927_R0100_SOFT_RESET */
 #define MAX98927_SOFT_RESET (0x1 << 0)
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] ASoC: max98927: Removed obsolete variables
  2017-09-01 21:35 [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format Ryan Lee
  2017-09-01 21:35 ` [PATCH 2/3] ASoC: max98927: Added controls for Envelope tracking Ryan Lee
@ 2017-09-01 21:35 ` Ryan Lee
  1 sibling, 0 replies; 7+ messages in thread
From: Ryan Lee @ 2017-09-01 21:35 UTC (permalink / raw)
  To: lgirdwood, broonie, perex, tiwai, ryans.lee,
	kuninori.morimoto.gx, alsa-devel, linux-kernel
  Cc: ryan.lee.maxim

Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
---
Changelog:
	Removed obsolete variables that have never been referred from driver before.

 sound/soc/codecs/max98927.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index 98b5f17..d215f60 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -263,17 +263,13 @@
 struct max98927_priv {
 	struct regmap *regmap;
 	struct snd_soc_codec *codec;
-	struct max98927_pdata *pdata;
-	unsigned int spk_gain;
 	unsigned int sysclk;
 	unsigned int v_l_slot;
 	unsigned int i_l_slot;
 	bool interleave_mode;
 	unsigned int ch_size;
-	unsigned int rate;
 	unsigned int iface;
 	unsigned int master;
-	unsigned int digital_gain;
 	bool tdm_mode;
 };
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format
  2017-09-14 18:49   ` Mark Brown
  (?)
@ 2017-09-15  0:30   ` Ryan Lee
  -1 siblings, 0 replies; 7+ messages in thread
From: Ryan Lee @ 2017-09-15  0:30 UTC (permalink / raw)
  To: Mark Brown
  Cc: lgirdwood, perex, tiwai, kuninori.morimoto.gx, alsa-devel,
	linux-kernel, ryan.lee.maxim

>-----Original Message-----
>From: Mark Brown [mailto:broonie@kernel.org]
>Sent: Thursday, September 14, 2017 11:50 AM
>To: Ryan Lee <RyanS.Lee@maximintegrated.com>
>Cc: lgirdwood@gmail.com; perex@perex.cz; tiwai@suse.com;
>kuninori.morimoto.gx@renesas.com; alsa-devel@alsa-project.org; linux-
>kernel@vger.kernel.org; ryan.lee.maxim@gmail.com
>Subject: Re: [PATCH 1/3] ASoC: max98927: Added support for DSP_A and
>DSP_B format
>
>On Mon, Sep 11, 2017 at 09:12:18AM -0700, Ryan Lee wrote:
>> Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
>> ---
>
>Please make an effort to write changelogs that clearly describe the change
>you're making.  This is doing way more than just implementing DSP mode, it's
>also adding a fairly complicated set_tdm_slot() implementation which isn't
>mentioned at all.  It probably needs splitting into multiple patches as well.

I split this patch as two separated patches and sent again.
One is about adding DSP_A, DSP_B support.
Another is about TDM slot configuration.
I added more changelog inside.

>
>> @@ -414,6 +504,9 @@ static int max98927_dac_event(struct
>snd_soc_dapm_widget *w,
>>  	struct max98927_priv *max98927 =
>snd_soc_codec_get_drvdata(codec);
>>
>>  	switch (event) {
>> +	case SND_SOC_DAPM_PRE_PMU:
>> +		max98927->tdm_mode = 0;
>> +		break;
>>  	case SND_SOC_DAPM_POST_PMU:
>>  		regmap_update_bits(max98927->regmap,
>>  			MAX98927_R003A_AMP_EN,
>
>Why is an event associated with the DAC changing something related to the DAI
>format?  These things should be unrelated.

In TDM mode, BCLK is being configured inside 'max98927_dai_tdm_slot' because TDM slot information(number of slots, slot width) is available in there.
In normal case, BCLK is being configured when 'hw_params' is called and TDM slot information is not available in this function.
So I added 'tdm_mode' variable to avoid overwrite BCLK configuration when 'hw_params' function is called after TDM slot configuration is done.
I wanted to clear this variable once playback is over so I added clear function when DAPM event is received.
I referred some codec driver change TDM related things when DAC event is received after TDM slot configuration is done.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format
  2017-09-11 16:12 [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format Ryan Lee
@ 2017-09-14 18:49   ` Mark Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2017-09-14 18:49 UTC (permalink / raw)
  To: Ryan Lee
  Cc: lgirdwood, perex, tiwai, kuninori.morimoto.gx, alsa-devel,
	linux-kernel, ryan.lee.maxim

[-- Attachment #1: Type: text/plain, Size: 929 bytes --]

On Mon, Sep 11, 2017 at 09:12:18AM -0700, Ryan Lee wrote:
> Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
> ---

Please make an effort to write changelogs that clearly describe the
change you're making.  This is doing way more than just implementing DSP
mode, it's also adding a fairly complicated set_tdm_slot() implementation 
which isn't mentioned at all.  It probably needs splitting into multiple
patches as well.

> @@ -414,6 +504,9 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
>  	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
>  
>  	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		max98927->tdm_mode = 0;
> +		break;
>  	case SND_SOC_DAPM_POST_PMU:
>  		regmap_update_bits(max98927->regmap,
>  			MAX98927_R003A_AMP_EN,

Why is an event associated with the DAC changing something related to
the DAI format?  These things should be unrelated.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format
@ 2017-09-14 18:49   ` Mark Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2017-09-14 18:49 UTC (permalink / raw)
  To: Ryan Lee
  Cc: alsa-devel, ryan.lee.maxim, kuninori.morimoto.gx, lgirdwood,
	linux-kernel, tiwai


[-- Attachment #1.1: Type: text/plain, Size: 929 bytes --]

On Mon, Sep 11, 2017 at 09:12:18AM -0700, Ryan Lee wrote:
> Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
> ---

Please make an effort to write changelogs that clearly describe the
change you're making.  This is doing way more than just implementing DSP
mode, it's also adding a fairly complicated set_tdm_slot() implementation 
which isn't mentioned at all.  It probably needs splitting into multiple
patches as well.

> @@ -414,6 +504,9 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
>  	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
>  
>  	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		max98927->tdm_mode = 0;
> +		break;
>  	case SND_SOC_DAPM_POST_PMU:
>  		regmap_update_bits(max98927->regmap,
>  			MAX98927_R003A_AMP_EN,

Why is an event associated with the DAC changing something related to
the DAI format?  These things should be unrelated.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format
@ 2017-09-11 16:12 Ryan Lee
  2017-09-14 18:49   ` Mark Brown
  0 siblings, 1 reply; 7+ messages in thread
From: Ryan Lee @ 2017-09-11 16:12 UTC (permalink / raw)
  To: lgirdwood, broonie, perex, tiwai, ryans.lee,
	kuninori.morimoto.gx, alsa-devel, linux-kernel
  Cc: ryan.lee.maxim

Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
---
Changelog: 
Added support for DSP_A and DSP_B format
Added 'max98927_dai_tdm_slot' function to set proper slot configuration.
Moved max98927->iface out of switch statement to avoid line duplication.
Added variable 'tdm_mode' to avoid BCLK overwrite after 'max98927_dai_tdm_slot' configure BCLK value.

 sound/soc/codecs/max98927.c | 155 +++++++++++++++++++++++++++++++++++---------
 sound/soc/codecs/max98927.h |   7 +-
 2 files changed, 129 insertions(+), 33 deletions(-)

diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index d9dbbe7..a1d3935 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -1,7 +1,7 @@
 /*
  * max98927.c  --  MAX98927 ALSA Soc Audio driver
  *
- * Copyright (C) 2016 Maxim Integrated Products
+ * Copyright (C) 2016-2017 Maxim Integrated Products
  * Author: Ryan Lee <ryans.lee@maximintegrated.com>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -146,6 +146,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
 	unsigned int mode = 0;
 	unsigned int format = 0;
+	bool use_pdm = false;
 	unsigned int invert = 0;
 
 	dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
@@ -187,22 +188,27 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		max98927->iface |= SND_SOC_DAIFMT_I2S;
 		format = MAX98927_PCM_FORMAT_I2S;
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
-		max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
 		format = MAX98927_PCM_FORMAT_LJ;
 		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		format = MAX98927_PCM_FORMAT_TDM_MODE1;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		format = MAX98927_PCM_FORMAT_TDM_MODE0;
+		break;
 	case SND_SOC_DAIFMT_PDM:
-		max98927->iface |= SND_SOC_DAIFMT_PDM;
+		use_pdm = true;
 		break;
 	default:
 		return -EINVAL;
 	}
+	max98927->iface = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
-	/* pcm channel configuration */
-	if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
+	if (!use_pdm) {
+		/* pcm channel configuration */
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R0018_PCM_RX_EN_A,
 			MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
@@ -217,13 +223,11 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 			MAX98927_R003B_SPK_SRC_SEL,
 			MAX98927_SPK_SRC_MASK, 0);
 
-	} else
 		regmap_update_bits(max98927->regmap,
-			MAX98927_R0018_PCM_RX_EN_A,
-			MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
-
-	/* pdm channel configuration */
-	if (max98927->iface & SND_SOC_DAIFMT_PDM) {
+			MAX98927_R0035_PDM_RX_CTRL,
+			MAX98927_PDM_RX_EN_MASK, 0);
+	} else {
+		/* pdm channel configuration */
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R0035_PDM_RX_CTRL,
 			MAX98927_PDM_RX_EN_MASK, 1);
@@ -231,10 +235,11 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R003B_SPK_SRC_SEL,
 			MAX98927_SPK_SRC_MASK, 3);
-	} else
+
 		regmap_update_bits(max98927->regmap,
-			MAX98927_R0035_PDM_RX_CTRL,
-			MAX98927_PDM_RX_EN_MASK, 0);
+			MAX98927_R0018_PCM_RX_EN_A,
+			MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
+	}
 	return 0;
 }
 
@@ -245,6 +250,21 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	13000000, 19200000,
 };
 
+/* BCLKs per LRCLK */
+static const int bclk_sel_table[] = {
+	32, 48, 64, 96, 128, 192, 256, 384, 512,
+};
+
+static int max98927_get_bclk_sel(int bclk)
+{
+	int i;
+	/* match BCLKs per LRCLK */
+	for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
+		if (bclk_sel_table[i] == bclk)
+			return i + 2;
+	}
+	return 0;
+}
 static int max98927_set_clock(struct max98927_priv *max98927,
 	struct snd_pcm_hw_params *params)
 {
@@ -270,23 +290,20 @@ static int max98927_set_clock(struct max98927_priv *max98927,
 			i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
 	}
 
-	switch (blr_clk_ratio) {
-	case 32:
-		value = 2;
-		break;
-	case 48:
-		value = 3;
-		break;
-	case 64:
-		value = 4;
-		break;
-	default:
-		return -EINVAL;
+	if (!max98927->tdm_mode) {
+		/* BCLK configuration */
+		value = max98927_get_bclk_sel(blr_clk_ratio);
+		if (!value) {
+			dev_err(codec->dev, "format unsupported %d\n",
+				params_format(params));
+			return -EINVAL;
+		}
+
+		regmap_update_bits(max98927->regmap,
+			MAX98927_R0022_PCM_CLK_SETUP,
+			MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+			value);
 	}
-	regmap_update_bits(max98927->regmap,
-		MAX98927_R0022_PCM_CLK_SETUP,
-		MAX98927_PCM_CLK_SETUP_BSEL_MASK,
-		value);
 	return 0;
 }
 
@@ -386,6 +403,78 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
 	return -EINVAL;
 }
 
+static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
+	unsigned int tx_mask, unsigned int rx_mask,
+	int slots, int slot_width)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	int bsel = 0;
+	unsigned int chan_sz = 0;
+
+	max98927->tdm_mode = true;
+
+	/* BCLK configuration */
+	bsel = max98927_get_bclk_sel(slots * slot_width);
+	if (bsel == 0) {
+		dev_err(codec->dev, "BCLK %d not supported\n",
+			slots * slot_width);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(max98927->regmap,
+		MAX98927_R0022_PCM_CLK_SETUP,
+		MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+		bsel);
+
+	/* Channel size configuration */
+	switch (slot_width) {
+	case 16:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
+		break;
+	case 24:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
+		break;
+	case 32:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
+		break;
+	default:
+		dev_err(codec->dev, "format unsupported %d\n",
+			slot_width);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(max98927->regmap,
+		MAX98927_R0020_PCM_MODE_CFG,
+		MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
+
+	/* Rx slot configuration */
+	regmap_write(max98927->regmap,
+		MAX98927_R0018_PCM_RX_EN_A,
+		rx_mask & 0xFF);
+	regmap_write(max98927->regmap,
+		MAX98927_R0019_PCM_RX_EN_B,
+		(rx_mask & 0xFF00) >> 8);
+
+	/* Tx slot configuration */
+	regmap_write(max98927->regmap,
+		MAX98927_R001A_PCM_TX_EN_A,
+		tx_mask & 0xFF);
+	regmap_write(max98927->regmap,
+		MAX98927_R001B_PCM_TX_EN_B,
+		(tx_mask & 0xFF00) >> 8);
+
+	/* Tx slot Hi-Z configuration */
+	regmap_write(max98927->regmap,
+		MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+		~tx_mask & 0xFF);
+	regmap_write(max98927->regmap,
+		MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+		(~tx_mask & 0xFF00) >> 8);
+
+	return 0;
+}
+
 #define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
 
 #define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -405,6 +494,7 @@ static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
 	.set_sysclk = max98927_dai_set_sysclk,
 	.set_fmt = max98927_dai_set_fmt,
 	.hw_params = max98927_dai_hw_params,
+	.set_tdm_slot = max98927_dai_tdm_slot,
 };
 
 static int max98927_dac_event(struct snd_soc_dapm_widget *w,
@@ -414,6 +504,9 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
 	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
 
 	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		max98927->tdm_mode = 0;
+		break;
 	case SND_SOC_DAPM_POST_PMU:
 		regmap_update_bits(max98927->regmap,
 			MAX98927_R003A_AMP_EN,
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index ece6a60..9ea8397 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -1,7 +1,7 @@
 /*
  * max98927.h  --  MAX98927 ALSA Soc Audio driver
  *
- * Copyright 2013-15 Maxim Integrated Products
+ * Copyright (C) 2016-2017 Maxim Integrated Products
  * Author: Ryan Lee <ryans.lee@maximintegrated.com>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -161,7 +161,9 @@
 #define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
 #define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
 #define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
-
+#define MAX98927_PCM_FORMAT_TDM_MODE0 (0x3 << 0)
+#define MAX98927_PCM_FORMAT_TDM_MODE1 (0x4 << 0)
+#define MAX98927_PCM_FORMAT_TDM_MODE2 (0x5 << 0)
 #define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
 #define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
 #define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
@@ -268,5 +270,6 @@ struct max98927_priv {
 	unsigned int iface;
 	unsigned int master;
 	unsigned int digital_gain;
+	bool tdm_mode;
 };
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-09-15  0:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-01 21:35 [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format Ryan Lee
2017-09-01 21:35 ` [PATCH 2/3] ASoC: max98927: Added controls for Envelope tracking Ryan Lee
2017-09-01 21:35 ` [PATCH 3/3] ASoC: max98927: Removed obsolete variables Ryan Lee
2017-09-11 16:12 [PATCH 1/3] ASoC: max98927: Added support for DSP_A and DSP_B format Ryan Lee
2017-09-14 18:49 ` Mark Brown
2017-09-14 18:49   ` Mark Brown
2017-09-15  0:30   ` Ryan Lee

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.