All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-11-30 15:37 ` Maxime Ripard
  0 siblings, 0 replies; 11+ messages in thread
From: Maxime Ripard @ 2015-11-30 15:37 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: Chen-Yu Tsai, alsa-devel, linux-arm-kernel, linux-kernel, Maxime Ripard

One of the input path used in the Allwinner codec is the MIC1. Add support
for it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 sound/soc/sunxi/sun4i-codec.c | 228 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 197 insertions(+), 31 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index bcbf4da168b6..30c9e9260491 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -69,6 +69,7 @@
 
 /* Codec ADC register offsets and bit fields */
 #define SUN4I_CODEC_ADC_FIFOC			(0x1c)
+#define SUN4I_CODEC_ADC_FIFOC_ADC_FS			(29)
 #define SUN4I_CODEC_ADC_FIFOC_EN_AD			(28)
 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE		(24)
 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL		(8)
@@ -102,6 +103,7 @@ struct sun4i_codec {
 	struct clk	*clk_apb;
 	struct clk	*clk_module;
 
+	struct snd_dmaengine_dai_dma_data	capture_dma_data;
 	struct snd_dmaengine_dai_dma_data	playback_dma_data;
 };
 
@@ -136,26 +138,54 @@ static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
 			   0);
 }
 
+static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
+{
+	/*
+	 * FIXME: according to the BSP, we might need to drive a PA
+	 *        GPIO high here on some boards
+	 */
+
+	/* Enable ADC DRQ */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
+}
+
+static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
+{
+	/*
+	 * FIXME: according to the BSP, we might need to drive a PA
+	 *        GPIO low here on some boards
+	 */
+
+	/* Disable ADC DRQ */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
+}
+
 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
 			       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		sun4i_codec_start_playback(scodec);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			sun4i_codec_start_playback(scodec);
+		else
+			sun4i_codec_start_capture(scodec);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		sun4i_codec_stop_playback(scodec);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			sun4i_codec_stop_playback(scodec);
+		else
+			sun4i_codec_stop_capture(scodec);
 		break;
 
 	default:
@@ -165,15 +195,54 @@ static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
 	return 0;
 }
 
-static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
-			       struct snd_soc_dai *dai)
+static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
+				       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
-	u32 val;
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
+
+	/* Flush RX FIFO */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
+
+
+	/* Set RX FIFO trigger level */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
+			   0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
+
+	/*
+	 * FIXME: Undocumented in the datasheet, but
+	 *        Allwinner's code mentions that it is related
+	 *        related to microphone gain
+	 */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
+			   0x3 << 25,
+			   0x1 << 25);
+
+	if (of_device_is_compatible(scodec->dev->of_node,
+				    "allwinner,sun7i-a20-codec"))
+		/* FIXME: Undocumented bits */
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
+				   0x3 << 8,
+				   0x1 << 8);
+
+	/* Fill most significant bits with valid data MSB */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
+
+	return 0;
+}
+
+static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
+					struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+	u32 val;
 
 	/* Flush the TX FIFO */
 	regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -202,6 +271,15 @@ static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
 			   0);
 
 	return 0;
+};
+
+static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return sun4i_codec_prepare_playback(substream, dai);
+
+	return sun4i_codec_prepare_capture(substream, dai);
 }
 
 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
@@ -276,30 +354,34 @@ static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
 	}
 }
 
-static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
-				 struct snd_pcm_hw_params *params,
-				 struct snd_soc_dai *dai)
+static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
+					 struct snd_pcm_hw_params *params,
+					 unsigned int hwrate)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
-	unsigned long clk_freq;
-	int ret, hwrate;
 	u32 val;
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
+	/* Set ADC sample rate */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
+			   hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
 
-	clk_freq = sun4i_codec_get_mod_freq(params);
-	if (!clk_freq)
-		return -EINVAL;
+	/* Set the number of channels we want to use */
+	if (params_channels(params) == 1)
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
+	else
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
 
-	ret = clk_set_rate(scodec->clk_module, clk_freq);
-	if (ret)
-		return ret;
+	return 0;
+}
 
-	hwrate = sun4i_codec_get_hw_rate(params);
-	if (hwrate < 0)
-		return hwrate;
+static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
+					  struct snd_pcm_hw_params *params,
+					  unsigned int hwrate)
+{
+	u32 val;
 
 	/* Set DAC sample rate */
 	regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -344,6 +426,34 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+	unsigned long clk_freq;
+	int hwrate;
+
+	clk_freq = sun4i_codec_get_mod_freq(params);
+	if (!clk_freq)
+		return -EINVAL;
+
+	if (clk_set_rate(scodec->clk_module, clk_freq))
+		return -EINVAL;
+
+	hwrate = sun4i_codec_get_hw_rate(params);
+	if (hwrate < 0)
+		return hwrate;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return sun4i_codec_hw_params_playback(scodec, params,
+						      hwrate);
+
+	return sun4i_codec_hw_params_capture(scodec, params,
+					     hwrate);
+}
+
 static int sun4i_codec_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
@@ -394,6 +504,20 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
 				  SNDRV_PCM_FMTBIT_S32_LE,
 		.sig_bits	= 24,
 	},
+	.capture = {
+		.stream_name	= "Codec Capture",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rate_min	= 8000,
+		.rate_max	= 192000,
+		.rates		= SNDRV_PCM_RATE_8000_48000 |
+				  SNDRV_PCM_RATE_96000 |
+				  SNDRV_PCM_RATE_192000 |
+				  SNDRV_PCM_RATE_KNOT,
+		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
+				  SNDRV_PCM_FMTBIT_S32_LE,
+		.sig_bits	= 24,
+	},
 };
 
 /*** Codec ***/
@@ -429,11 +553,22 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
 };
 
 static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
+	/* Digital parts of the ADCs */
+	SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
+			    SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
+			    NULL, 0),
+
 	/* Digital parts of the DACs */
 	SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
 			    NULL, 0),
 
+	/* Analog parts of the ADCs */
+	SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
+	SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
+
 	/* Analog parts of the DACs */
 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
 			 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
@@ -452,6 +587,14 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
 			    SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
 
+	/* VMIC */
+	SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
+			    SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
+
+	/* Mic Pre-Amplifiers */
+	SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
+
 	/* Pre-Amplifier */
 	SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
 			   SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
@@ -460,15 +603,19 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0,
 			    &sun4i_codec_pa_mute),
 
+	SND_SOC_DAPM_INPUT("Mic1"),
+
 	SND_SOC_DAPM_OUTPUT("HP Right"),
 	SND_SOC_DAPM_OUTPUT("HP Left"),
 };
 
 static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
-	/* Left DAC Routes */
+	/* Left ADC / DAC Routes */
+	{ "Left ADC", NULL, "ADC" },
 	{ "Left DAC", NULL, "DAC" },
 
-	/* Right DAC Routes */
+	/* Right ADC / DAC Routes */
+	{ "Right ADC", NULL, "ADC" },
 	{ "Right DAC", NULL, "DAC" },
 
 	/* Right Mixer Routes */
@@ -490,6 +637,12 @@ static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
 	{ "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" },
 	{ "HP Right", NULL, "Pre-Amplifier Mute" },
 	{ "HP Left", NULL, "Pre-Amplifier Mute" },
+
+	/* Mic1 Routes */
+	{ "Left ADC", NULL, "MIC1 Pre-Amplifier" },
+	{ "Right ADC", NULL, "MIC1 Pre-Amplifier" },
+	{ "MIC1 Pre-Amplifier", NULL, "Mic1"},
+	{ "Mic1", NULL, "VMIC" },
 };
 
 static struct snd_soc_codec_driver sun4i_codec_codec = {
@@ -515,7 +668,7 @@ static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
 
 	snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
-				  NULL);
+				  &scodec->capture_dma_data);
 
 	return 0;
 }
@@ -531,6 +684,14 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
 		.formats	= SUN4I_CODEC_FORMATS,
 		.sig_bits	= 24,
 	},
+	.capture = {
+		.stream_name	= "Capture",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rates 		= SUN4I_CODEC_RATES,
+		.formats 	= SUN4I_CODEC_FORMATS,
+		.sig_bits	= 24,
+	 },
 };
 
 static const struct regmap_config sun4i_codec_regmap_config = {
@@ -638,6 +799,11 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	scodec->playback_dma_data.maxburst = 4;
 	scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 
+	/* DMA configuration for RX FIFO */
+	scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
+	scodec->capture_dma_data.maxburst = 4;
+	scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+
 	ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
 				     &sun4i_codec_dai, 1);
 	if (ret) {
-- 
2.6.3


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

* [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-11-30 15:37 ` Maxime Ripard
  0 siblings, 0 replies; 11+ messages in thread
From: Maxime Ripard @ 2015-11-30 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

One of the input path used in the Allwinner codec is the MIC1. Add support
for it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 sound/soc/sunxi/sun4i-codec.c | 228 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 197 insertions(+), 31 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index bcbf4da168b6..30c9e9260491 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -69,6 +69,7 @@
 
 /* Codec ADC register offsets and bit fields */
 #define SUN4I_CODEC_ADC_FIFOC			(0x1c)
+#define SUN4I_CODEC_ADC_FIFOC_ADC_FS			(29)
 #define SUN4I_CODEC_ADC_FIFOC_EN_AD			(28)
 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE		(24)
 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL		(8)
@@ -102,6 +103,7 @@ struct sun4i_codec {
 	struct clk	*clk_apb;
 	struct clk	*clk_module;
 
+	struct snd_dmaengine_dai_dma_data	capture_dma_data;
 	struct snd_dmaengine_dai_dma_data	playback_dma_data;
 };
 
@@ -136,26 +138,54 @@ static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
 			   0);
 }
 
+static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
+{
+	/*
+	 * FIXME: according to the BSP, we might need to drive a PA
+	 *        GPIO high here on some boards
+	 */
+
+	/* Enable ADC DRQ */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
+}
+
+static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
+{
+	/*
+	 * FIXME: according to the BSP, we might need to drive a PA
+	 *        GPIO low here on some boards
+	 */
+
+	/* Disable ADC DRQ */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
+}
+
 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
 			       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		sun4i_codec_start_playback(scodec);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			sun4i_codec_start_playback(scodec);
+		else
+			sun4i_codec_start_capture(scodec);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		sun4i_codec_stop_playback(scodec);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			sun4i_codec_stop_playback(scodec);
+		else
+			sun4i_codec_stop_capture(scodec);
 		break;
 
 	default:
@@ -165,15 +195,54 @@ static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
 	return 0;
 }
 
-static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
-			       struct snd_soc_dai *dai)
+static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
+				       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
-	u32 val;
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
+
+	/* Flush RX FIFO */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
+
+
+	/* Set RX FIFO trigger level */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
+			   0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
+
+	/*
+	 * FIXME: Undocumented in the datasheet, but
+	 *        Allwinner's code mentions that it is related
+	 *        related to microphone gain
+	 */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
+			   0x3 << 25,
+			   0x1 << 25);
+
+	if (of_device_is_compatible(scodec->dev->of_node,
+				    "allwinner,sun7i-a20-codec"))
+		/* FIXME: Undocumented bits */
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
+				   0x3 << 8,
+				   0x1 << 8);
+
+	/* Fill most significant bits with valid data MSB */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
+
+	return 0;
+}
+
+static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
+					struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+	u32 val;
 
 	/* Flush the TX FIFO */
 	regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -202,6 +271,15 @@ static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
 			   0);
 
 	return 0;
+};
+
+static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return sun4i_codec_prepare_playback(substream, dai);
+
+	return sun4i_codec_prepare_capture(substream, dai);
 }
 
 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
@@ -276,30 +354,34 @@ static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
 	}
 }
 
-static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
-				 struct snd_pcm_hw_params *params,
-				 struct snd_soc_dai *dai)
+static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
+					 struct snd_pcm_hw_params *params,
+					 unsigned int hwrate)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
-	unsigned long clk_freq;
-	int ret, hwrate;
 	u32 val;
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
+	/* Set ADC sample rate */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
+			   hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
 
-	clk_freq = sun4i_codec_get_mod_freq(params);
-	if (!clk_freq)
-		return -EINVAL;
+	/* Set the number of channels we want to use */
+	if (params_channels(params) == 1)
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
+	else
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
 
-	ret = clk_set_rate(scodec->clk_module, clk_freq);
-	if (ret)
-		return ret;
+	return 0;
+}
 
-	hwrate = sun4i_codec_get_hw_rate(params);
-	if (hwrate < 0)
-		return hwrate;
+static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
+					  struct snd_pcm_hw_params *params,
+					  unsigned int hwrate)
+{
+	u32 val;
 
 	/* Set DAC sample rate */
 	regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -344,6 +426,34 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+	unsigned long clk_freq;
+	int hwrate;
+
+	clk_freq = sun4i_codec_get_mod_freq(params);
+	if (!clk_freq)
+		return -EINVAL;
+
+	if (clk_set_rate(scodec->clk_module, clk_freq))
+		return -EINVAL;
+
+	hwrate = sun4i_codec_get_hw_rate(params);
+	if (hwrate < 0)
+		return hwrate;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return sun4i_codec_hw_params_playback(scodec, params,
+						      hwrate);
+
+	return sun4i_codec_hw_params_capture(scodec, params,
+					     hwrate);
+}
+
 static int sun4i_codec_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
@@ -394,6 +504,20 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
 				  SNDRV_PCM_FMTBIT_S32_LE,
 		.sig_bits	= 24,
 	},
+	.capture = {
+		.stream_name	= "Codec Capture",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rate_min	= 8000,
+		.rate_max	= 192000,
+		.rates		= SNDRV_PCM_RATE_8000_48000 |
+				  SNDRV_PCM_RATE_96000 |
+				  SNDRV_PCM_RATE_192000 |
+				  SNDRV_PCM_RATE_KNOT,
+		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
+				  SNDRV_PCM_FMTBIT_S32_LE,
+		.sig_bits	= 24,
+	},
 };
 
 /*** Codec ***/
@@ -429,11 +553,22 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
 };
 
 static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
+	/* Digital parts of the ADCs */
+	SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
+			    SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
+			    NULL, 0),
+
 	/* Digital parts of the DACs */
 	SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
 			    NULL, 0),
 
+	/* Analog parts of the ADCs */
+	SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
+	SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
+
 	/* Analog parts of the DACs */
 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
 			 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
@@ -452,6 +587,14 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
 			    SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
 
+	/* VMIC */
+	SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
+			    SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
+
+	/* Mic Pre-Amplifiers */
+	SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
+
 	/* Pre-Amplifier */
 	SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
 			   SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
@@ -460,15 +603,19 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0,
 			    &sun4i_codec_pa_mute),
 
+	SND_SOC_DAPM_INPUT("Mic1"),
+
 	SND_SOC_DAPM_OUTPUT("HP Right"),
 	SND_SOC_DAPM_OUTPUT("HP Left"),
 };
 
 static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
-	/* Left DAC Routes */
+	/* Left ADC / DAC Routes */
+	{ "Left ADC", NULL, "ADC" },
 	{ "Left DAC", NULL, "DAC" },
 
-	/* Right DAC Routes */
+	/* Right ADC / DAC Routes */
+	{ "Right ADC", NULL, "ADC" },
 	{ "Right DAC", NULL, "DAC" },
 
 	/* Right Mixer Routes */
@@ -490,6 +637,12 @@ static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
 	{ "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" },
 	{ "HP Right", NULL, "Pre-Amplifier Mute" },
 	{ "HP Left", NULL, "Pre-Amplifier Mute" },
+
+	/* Mic1 Routes */
+	{ "Left ADC", NULL, "MIC1 Pre-Amplifier" },
+	{ "Right ADC", NULL, "MIC1 Pre-Amplifier" },
+	{ "MIC1 Pre-Amplifier", NULL, "Mic1"},
+	{ "Mic1", NULL, "VMIC" },
 };
 
 static struct snd_soc_codec_driver sun4i_codec_codec = {
@@ -515,7 +668,7 @@ static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
 
 	snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
-				  NULL);
+				  &scodec->capture_dma_data);
 
 	return 0;
 }
@@ -531,6 +684,14 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
 		.formats	= SUN4I_CODEC_FORMATS,
 		.sig_bits	= 24,
 	},
+	.capture = {
+		.stream_name	= "Capture",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rates 		= SUN4I_CODEC_RATES,
+		.formats 	= SUN4I_CODEC_FORMATS,
+		.sig_bits	= 24,
+	 },
 };
 
 static const struct regmap_config sun4i_codec_regmap_config = {
@@ -638,6 +799,11 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	scodec->playback_dma_data.maxburst = 4;
 	scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 
+	/* DMA configuration for RX FIFO */
+	scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
+	scodec->capture_dma_data.maxburst = 4;
+	scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+
 	ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
 				     &sun4i_codec_dai, 1);
 	if (ret) {
-- 
2.6.3

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

* Re: [PATCH] ASoC: sun4i: Implement MIC1 capture
  2015-11-30 15:37 ` Maxime Ripard
@ 2015-11-30 16:17   ` Mark Brown
  -1 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2015-11-30 16:17 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Liam Girdwood, Chen-Yu Tsai, alsa-devel, linux-arm-kernel, linux-kernel

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

On Mon, Nov 30, 2015 at 04:37:47PM +0100, Maxime Ripard wrote:

A couple of minor issues below but I'll apply this - please send
followup patches.

> +static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
> +{
> +	/*
> +	 * FIXME: according to the BSP, we might need to drive a PA
> +	 *        GPIO high here on some boards
> +	 */

That's not something this driver needs to worry about, that's something
the machine driver will do - the whole purpose is to glue all the
different components on the board together.

> +	if (clk_set_rate(scodec->clk_module, clk_freq))
> +		return -EINVAL;

It'd be better to pass back the error code from clk_set_rate().

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

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

* [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-11-30 16:17   ` Mark Brown
  0 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2015-11-30 16:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 30, 2015 at 04:37:47PM +0100, Maxime Ripard wrote:

A couple of minor issues below but I'll apply this - please send
followup patches.

> +static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
> +{
> +	/*
> +	 * FIXME: according to the BSP, we might need to drive a PA
> +	 *        GPIO high here on some boards
> +	 */

That's not something this driver needs to worry about, that's something
the machine driver will do - the whole purpose is to glue all the
different components on the board together.

> +	if (clk_set_rate(scodec->clk_module, clk_freq))
> +		return -EINVAL;

It'd be better to pass back the error code from clk_set_rate().
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151130/c06aef94/attachment.sig>

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

* Re: [PATCH] ASoC: sun4i: Implement MIC1 capture
  2015-11-30 15:37 ` Maxime Ripard
  (?)
@ 2015-11-30 16:21   ` kbuild test robot
  -1 siblings, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2015-11-30 16:21 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: kbuild-all, Mark Brown, Liam Girdwood, Chen-Yu Tsai, alsa-devel,
	linux-arm-kernel, linux-kernel, Maxime Ripard

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

Hi Maxime,

[auto build test WARNING on: v4.4-rc3]
[cannot apply to: asoc/for-next next-20151127]

url:    https://github.com/0day-ci/linux/commits/Maxime-Ripard/ASoC-sun4i-Implement-MIC1-capture/20151130-234314
config: i386-randconfig-i0-201548 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   sound/soc/sunxi/sun4i-codec.c: In function 'sun4i_codec_hw_params_capture':
>> sound/soc/sunxi/sun4i-codec.c:361:6: warning: unused variable 'val' [-Wunused-variable]
     u32 val;
         ^

vim +/val +361 sound/soc/sunxi/sun4i-codec.c

45fb6b6f Emilio López  2015-09-12  345  	case 11025:
45fb6b6f Emilio López  2015-09-12  346  		return 4;
45fb6b6f Emilio López  2015-09-12  347  
45fb6b6f Emilio López  2015-09-12  348  	case 8000:
45fb6b6f Emilio López  2015-09-12  349  	case 7350:
45fb6b6f Emilio López  2015-09-12  350  		return 5;
45fb6b6f Emilio López  2015-09-12  351  
45fb6b6f Emilio López  2015-09-12  352  	default:
45fb6b6f Emilio López  2015-09-12  353  		return -EINVAL;
45fb6b6f Emilio López  2015-09-12  354  	}
45fb6b6f Emilio López  2015-09-12  355  }
45fb6b6f Emilio López  2015-09-12  356  
e6fdf863 Maxime Ripard 2015-11-30  357  static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
45fb6b6f Emilio López  2015-09-12  358  					 struct snd_pcm_hw_params *params,
e6fdf863 Maxime Ripard 2015-11-30  359  					 unsigned int hwrate)
45fb6b6f Emilio López  2015-09-12  360  {
45fb6b6f Emilio López  2015-09-12 @361  	u32 val;
45fb6b6f Emilio López  2015-09-12  362  
e6fdf863 Maxime Ripard 2015-11-30  363  	/* Set ADC sample rate */
e6fdf863 Maxime Ripard 2015-11-30  364  	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
e6fdf863 Maxime Ripard 2015-11-30  365  			   7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
e6fdf863 Maxime Ripard 2015-11-30  366  			   hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
45fb6b6f Emilio López  2015-09-12  367  
e6fdf863 Maxime Ripard 2015-11-30  368  	/* Set the number of channels we want to use */
e6fdf863 Maxime Ripard 2015-11-30  369  	if (params_channels(params) == 1)

:::::: The code at line 361 was first introduced by commit
:::::: 45fb6b6f2aa3f6b22b81078db0dba4b26c9d0bdb ASoC: sunxi: add support for the on-chip codec on early Allwinner SoCs

:::::: TO: Emilio López <emilio@elopez.com.ar>
:::::: CC: Mark Brown <broonie@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 24519 bytes --]

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

* Re: [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-11-30 16:21   ` kbuild test robot
  0 siblings, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2015-11-30 16:21 UTC (permalink / raw)
  Cc: kbuild-all, Mark Brown, Liam Girdwood, Chen-Yu Tsai, alsa-devel,
	linux-arm-kernel, linux-kernel, Maxime Ripard

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

Hi Maxime,

[auto build test WARNING on: v4.4-rc3]
[cannot apply to: asoc/for-next next-20151127]

url:    https://github.com/0day-ci/linux/commits/Maxime-Ripard/ASoC-sun4i-Implement-MIC1-capture/20151130-234314
config: i386-randconfig-i0-201548 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   sound/soc/sunxi/sun4i-codec.c: In function 'sun4i_codec_hw_params_capture':
>> sound/soc/sunxi/sun4i-codec.c:361:6: warning: unused variable 'val' [-Wunused-variable]
     u32 val;
         ^

vim +/val +361 sound/soc/sunxi/sun4i-codec.c

45fb6b6f Emilio López  2015-09-12  345  	case 11025:
45fb6b6f Emilio López  2015-09-12  346  		return 4;
45fb6b6f Emilio López  2015-09-12  347  
45fb6b6f Emilio López  2015-09-12  348  	case 8000:
45fb6b6f Emilio López  2015-09-12  349  	case 7350:
45fb6b6f Emilio López  2015-09-12  350  		return 5;
45fb6b6f Emilio López  2015-09-12  351  
45fb6b6f Emilio López  2015-09-12  352  	default:
45fb6b6f Emilio López  2015-09-12  353  		return -EINVAL;
45fb6b6f Emilio López  2015-09-12  354  	}
45fb6b6f Emilio López  2015-09-12  355  }
45fb6b6f Emilio López  2015-09-12  356  
e6fdf863 Maxime Ripard 2015-11-30  357  static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
45fb6b6f Emilio López  2015-09-12  358  					 struct snd_pcm_hw_params *params,
e6fdf863 Maxime Ripard 2015-11-30  359  					 unsigned int hwrate)
45fb6b6f Emilio López  2015-09-12  360  {
45fb6b6f Emilio López  2015-09-12 @361  	u32 val;
45fb6b6f Emilio López  2015-09-12  362  
e6fdf863 Maxime Ripard 2015-11-30  363  	/* Set ADC sample rate */
e6fdf863 Maxime Ripard 2015-11-30  364  	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
e6fdf863 Maxime Ripard 2015-11-30  365  			   7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
e6fdf863 Maxime Ripard 2015-11-30  366  			   hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
45fb6b6f Emilio López  2015-09-12  367  
e6fdf863 Maxime Ripard 2015-11-30  368  	/* Set the number of channels we want to use */
e6fdf863 Maxime Ripard 2015-11-30  369  	if (params_channels(params) == 1)

:::::: The code at line 361 was first introduced by commit
:::::: 45fb6b6f2aa3f6b22b81078db0dba4b26c9d0bdb ASoC: sunxi: add support for the on-chip codec on early Allwinner SoCs

:::::: TO: Emilio López <emilio@elopez.com.ar>
:::::: CC: Mark Brown <broonie@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 24519 bytes --]

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

* [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-11-30 16:21   ` kbuild test robot
  0 siblings, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2015-11-30 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Maxime,

[auto build test WARNING on: v4.4-rc3]
[cannot apply to: asoc/for-next next-20151127]

url:    https://github.com/0day-ci/linux/commits/Maxime-Ripard/ASoC-sun4i-Implement-MIC1-capture/20151130-234314
config: i386-randconfig-i0-201548 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   sound/soc/sunxi/sun4i-codec.c: In function 'sun4i_codec_hw_params_capture':
>> sound/soc/sunxi/sun4i-codec.c:361:6: warning: unused variable 'val' [-Wunused-variable]
     u32 val;
         ^

vim +/val +361 sound/soc/sunxi/sun4i-codec.c

45fb6b6f Emilio L?pez  2015-09-12  345  	case 11025:
45fb6b6f Emilio L?pez  2015-09-12  346  		return 4;
45fb6b6f Emilio L?pez  2015-09-12  347  
45fb6b6f Emilio L?pez  2015-09-12  348  	case 8000:
45fb6b6f Emilio L?pez  2015-09-12  349  	case 7350:
45fb6b6f Emilio L?pez  2015-09-12  350  		return 5;
45fb6b6f Emilio L?pez  2015-09-12  351  
45fb6b6f Emilio L?pez  2015-09-12  352  	default:
45fb6b6f Emilio L?pez  2015-09-12  353  		return -EINVAL;
45fb6b6f Emilio L?pez  2015-09-12  354  	}
45fb6b6f Emilio L?pez  2015-09-12  355  }
45fb6b6f Emilio L?pez  2015-09-12  356  
e6fdf863 Maxime Ripard 2015-11-30  357  static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
45fb6b6f Emilio L?pez  2015-09-12  358  					 struct snd_pcm_hw_params *params,
e6fdf863 Maxime Ripard 2015-11-30  359  					 unsigned int hwrate)
45fb6b6f Emilio L?pez  2015-09-12  360  {
45fb6b6f Emilio L?pez  2015-09-12 @361  	u32 val;
45fb6b6f Emilio L?pez  2015-09-12  362  
e6fdf863 Maxime Ripard 2015-11-30  363  	/* Set ADC sample rate */
e6fdf863 Maxime Ripard 2015-11-30  364  	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
e6fdf863 Maxime Ripard 2015-11-30  365  			   7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
e6fdf863 Maxime Ripard 2015-11-30  366  			   hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
45fb6b6f Emilio L?pez  2015-09-12  367  
e6fdf863 Maxime Ripard 2015-11-30  368  	/* Set the number of channels we want to use */
e6fdf863 Maxime Ripard 2015-11-30  369  	if (params_channels(params) == 1)

:::::: The code at line 361 was first introduced by commit
:::::: 45fb6b6f2aa3f6b22b81078db0dba4b26c9d0bdb ASoC: sunxi: add support for the on-chip codec on early Allwinner SoCs

:::::: TO: Emilio L?pez <emilio@elopez.com.ar>
:::::: CC: Mark Brown <broonie@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 24519 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151201/5a68c78e/attachment-0001.obj>

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

* Applied "ASoC: sun4i: Implement MIC1 capture" to the asoc tree
  2015-11-30 15:37 ` Maxime Ripard
                   ` (2 preceding siblings ...)
  (?)
@ 2015-11-30 16:23 ` Mark Brown
  -1 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2015-11-30 16:23 UTC (permalink / raw)
  To: Maxime Ripard, Mark Brown; +Cc: alsa-devel

The patch

   ASoC: sun4i: Implement MIC1 capture

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 1fb34b48361eac63850513a045ed2eb9a7fd6168 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Mon, 30 Nov 2015 16:37:47 +0100
Subject: [PATCH] ASoC: sun4i: Implement MIC1 capture

One of the input path used in the Allwinner codec is the MIC1. Add support
for it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/sunxi/sun4i-codec.c | 228 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 197 insertions(+), 31 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index bcbf4da168b6..30c9e9260491 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -69,6 +69,7 @@
 
 /* Codec ADC register offsets and bit fields */
 #define SUN4I_CODEC_ADC_FIFOC			(0x1c)
+#define SUN4I_CODEC_ADC_FIFOC_ADC_FS			(29)
 #define SUN4I_CODEC_ADC_FIFOC_EN_AD			(28)
 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE		(24)
 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL		(8)
@@ -102,6 +103,7 @@ struct sun4i_codec {
 	struct clk	*clk_apb;
 	struct clk	*clk_module;
 
+	struct snd_dmaengine_dai_dma_data	capture_dma_data;
 	struct snd_dmaengine_dai_dma_data	playback_dma_data;
 };
 
@@ -136,26 +138,54 @@ static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
 			   0);
 }
 
+static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
+{
+	/*
+	 * FIXME: according to the BSP, we might need to drive a PA
+	 *        GPIO high here on some boards
+	 */
+
+	/* Enable ADC DRQ */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
+}
+
+static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
+{
+	/*
+	 * FIXME: according to the BSP, we might need to drive a PA
+	 *        GPIO low here on some boards
+	 */
+
+	/* Disable ADC DRQ */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
+}
+
 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
 			       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		sun4i_codec_start_playback(scodec);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			sun4i_codec_start_playback(scodec);
+		else
+			sun4i_codec_start_capture(scodec);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		sun4i_codec_stop_playback(scodec);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			sun4i_codec_stop_playback(scodec);
+		else
+			sun4i_codec_stop_capture(scodec);
 		break;
 
 	default:
@@ -165,15 +195,54 @@ static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
 	return 0;
 }
 
-static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
-			       struct snd_soc_dai *dai)
+static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
+				       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
-	u32 val;
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
+
+	/* Flush RX FIFO */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
+
+
+	/* Set RX FIFO trigger level */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
+			   0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
+
+	/*
+	 * FIXME: Undocumented in the datasheet, but
+	 *        Allwinner's code mentions that it is related
+	 *        related to microphone gain
+	 */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
+			   0x3 << 25,
+			   0x1 << 25);
+
+	if (of_device_is_compatible(scodec->dev->of_node,
+				    "allwinner,sun7i-a20-codec"))
+		/* FIXME: Undocumented bits */
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
+				   0x3 << 8,
+				   0x1 << 8);
+
+	/* Fill most significant bits with valid data MSB */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
+			   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
+
+	return 0;
+}
+
+static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
+					struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+	u32 val;
 
 	/* Flush the TX FIFO */
 	regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -202,6 +271,15 @@ static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
 			   0);
 
 	return 0;
+};
+
+static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return sun4i_codec_prepare_playback(substream, dai);
+
+	return sun4i_codec_prepare_capture(substream, dai);
 }
 
 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
@@ -276,30 +354,34 @@ static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
 	}
 }
 
-static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
-				 struct snd_pcm_hw_params *params,
-				 struct snd_soc_dai *dai)
+static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
+					 struct snd_pcm_hw_params *params,
+					 unsigned int hwrate)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
-	unsigned long clk_freq;
-	int ret, hwrate;
 	u32 val;
 
-	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-		return -ENOTSUPP;
+	/* Set ADC sample rate */
+	regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+			   7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
+			   hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
 
-	clk_freq = sun4i_codec_get_mod_freq(params);
-	if (!clk_freq)
-		return -EINVAL;
+	/* Set the number of channels we want to use */
+	if (params_channels(params) == 1)
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
+	else
+		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
+				   BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
 
-	ret = clk_set_rate(scodec->clk_module, clk_freq);
-	if (ret)
-		return ret;
+	return 0;
+}
 
-	hwrate = sun4i_codec_get_hw_rate(params);
-	if (hwrate < 0)
-		return hwrate;
+static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
+					  struct snd_pcm_hw_params *params,
+					  unsigned int hwrate)
+{
+	u32 val;
 
 	/* Set DAC sample rate */
 	regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -344,6 +426,34 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+	unsigned long clk_freq;
+	int hwrate;
+
+	clk_freq = sun4i_codec_get_mod_freq(params);
+	if (!clk_freq)
+		return -EINVAL;
+
+	if (clk_set_rate(scodec->clk_module, clk_freq))
+		return -EINVAL;
+
+	hwrate = sun4i_codec_get_hw_rate(params);
+	if (hwrate < 0)
+		return hwrate;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return sun4i_codec_hw_params_playback(scodec, params,
+						      hwrate);
+
+	return sun4i_codec_hw_params_capture(scodec, params,
+					     hwrate);
+}
+
 static int sun4i_codec_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
@@ -394,6 +504,20 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
 				  SNDRV_PCM_FMTBIT_S32_LE,
 		.sig_bits	= 24,
 	},
+	.capture = {
+		.stream_name	= "Codec Capture",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rate_min	= 8000,
+		.rate_max	= 192000,
+		.rates		= SNDRV_PCM_RATE_8000_48000 |
+				  SNDRV_PCM_RATE_96000 |
+				  SNDRV_PCM_RATE_192000 |
+				  SNDRV_PCM_RATE_KNOT,
+		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
+				  SNDRV_PCM_FMTBIT_S32_LE,
+		.sig_bits	= 24,
+	},
 };
 
 /*** Codec ***/
@@ -429,11 +553,22 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
 };
 
 static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
+	/* Digital parts of the ADCs */
+	SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
+			    SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
+			    NULL, 0),
+
 	/* Digital parts of the DACs */
 	SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
 			    NULL, 0),
 
+	/* Analog parts of the ADCs */
+	SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
+	SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
+
 	/* Analog parts of the DACs */
 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
 			 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
@@ -452,6 +587,14 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
 			    SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
 
+	/* VMIC */
+	SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
+			    SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
+
+	/* Mic Pre-Amplifiers */
+	SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
+
 	/* Pre-Amplifier */
 	SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
 			   SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
@@ -460,15 +603,19 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0,
 			    &sun4i_codec_pa_mute),
 
+	SND_SOC_DAPM_INPUT("Mic1"),
+
 	SND_SOC_DAPM_OUTPUT("HP Right"),
 	SND_SOC_DAPM_OUTPUT("HP Left"),
 };
 
 static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
-	/* Left DAC Routes */
+	/* Left ADC / DAC Routes */
+	{ "Left ADC", NULL, "ADC" },
 	{ "Left DAC", NULL, "DAC" },
 
-	/* Right DAC Routes */
+	/* Right ADC / DAC Routes */
+	{ "Right ADC", NULL, "ADC" },
 	{ "Right DAC", NULL, "DAC" },
 
 	/* Right Mixer Routes */
@@ -490,6 +637,12 @@ static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
 	{ "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" },
 	{ "HP Right", NULL, "Pre-Amplifier Mute" },
 	{ "HP Left", NULL, "Pre-Amplifier Mute" },
+
+	/* Mic1 Routes */
+	{ "Left ADC", NULL, "MIC1 Pre-Amplifier" },
+	{ "Right ADC", NULL, "MIC1 Pre-Amplifier" },
+	{ "MIC1 Pre-Amplifier", NULL, "Mic1"},
+	{ "Mic1", NULL, "VMIC" },
 };
 
 static struct snd_soc_codec_driver sun4i_codec_codec = {
@@ -515,7 +668,7 @@ static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
 
 	snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
-				  NULL);
+				  &scodec->capture_dma_data);
 
 	return 0;
 }
@@ -531,6 +684,14 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
 		.formats	= SUN4I_CODEC_FORMATS,
 		.sig_bits	= 24,
 	},
+	.capture = {
+		.stream_name	= "Capture",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rates 		= SUN4I_CODEC_RATES,
+		.formats 	= SUN4I_CODEC_FORMATS,
+		.sig_bits	= 24,
+	 },
 };
 
 static const struct regmap_config sun4i_codec_regmap_config = {
@@ -638,6 +799,11 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	scodec->playback_dma_data.maxburst = 4;
 	scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 
+	/* DMA configuration for RX FIFO */
+	scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
+	scodec->capture_dma_data.maxburst = 4;
+	scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+
 	ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
 				     &sun4i_codec_dai, 1);
 	if (ret) {
-- 
2.6.2

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

* Re: [PATCH] ASoC: sun4i: Implement MIC1 capture
  2015-11-30 16:17   ` Mark Brown
  (?)
@ 2015-12-01  9:14     ` Maxime Ripard
  -1 siblings, 0 replies; 11+ messages in thread
From: Maxime Ripard @ 2015-12-01  9:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Liam Girdwood, Chen-Yu Tsai, alsa-devel, linux-arm-kernel, linux-kernel

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

Hi,

On Mon, Nov 30, 2015 at 04:17:05PM +0000, Mark Brown wrote:
> On Mon, Nov 30, 2015 at 04:37:47PM +0100, Maxime Ripard wrote:
> 
> A couple of minor issues below but I'll apply this - please send
> followup patches.
> 
> > +static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
> > +{
> > +	/*
> > +	 * FIXME: according to the BSP, we might need to drive a PA
> > +	 *        GPIO high here on some boards
> > +	 */
> 
> That's not something this driver needs to worry about, that's something
> the machine driver will do - the whole purpose is to glue all the
> different components on the board together.

Indeed, I'll remove the comment.

> 
> > +	if (clk_set_rate(scodec->clk_module, clk_freq))
> > +		return -EINVAL;
> 
> It'd be better to pass back the error code from clk_set_rate().

Ack, I'll send a patch.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-12-01  9:14     ` Maxime Ripard
  0 siblings, 0 replies; 11+ messages in thread
From: Maxime Ripard @ 2015-12-01  9:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-arm-kernel, Chen-Yu Tsai, Liam Girdwood, alsa-devel, linux-kernel


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

Hi,

On Mon, Nov 30, 2015 at 04:17:05PM +0000, Mark Brown wrote:
> On Mon, Nov 30, 2015 at 04:37:47PM +0100, Maxime Ripard wrote:
> 
> A couple of minor issues below but I'll apply this - please send
> followup patches.
> 
> > +static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
> > +{
> > +	/*
> > +	 * FIXME: according to the BSP, we might need to drive a PA
> > +	 *        GPIO high here on some boards
> > +	 */
> 
> That's not something this driver needs to worry about, that's something
> the machine driver will do - the whole purpose is to glue all the
> different components on the board together.

Indeed, I'll remove the comment.

> 
> > +	if (clk_set_rate(scodec->clk_module, clk_freq))
> > +		return -EINVAL;
> 
> It'd be better to pass back the error code from clk_set_rate().

Ack, I'll send a patch.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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



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

* [PATCH] ASoC: sun4i: Implement MIC1 capture
@ 2015-12-01  9:14     ` Maxime Ripard
  0 siblings, 0 replies; 11+ messages in thread
From: Maxime Ripard @ 2015-12-01  9:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Nov 30, 2015 at 04:17:05PM +0000, Mark Brown wrote:
> On Mon, Nov 30, 2015 at 04:37:47PM +0100, Maxime Ripard wrote:
> 
> A couple of minor issues below but I'll apply this - please send
> followup patches.
> 
> > +static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
> > +{
> > +	/*
> > +	 * FIXME: according to the BSP, we might need to drive a PA
> > +	 *        GPIO high here on some boards
> > +	 */
> 
> That's not something this driver needs to worry about, that's something
> the machine driver will do - the whole purpose is to glue all the
> different components on the board together.

Indeed, I'll remove the comment.

> 
> > +	if (clk_set_rate(scodec->clk_module, clk_freq))
> > +		return -EINVAL;
> 
> It'd be better to pass back the error code from clk_set_rate().

Ack, I'll send a patch.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151201/23d528a7/attachment.sig>

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

end of thread, other threads:[~2015-12-01  9:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-30 15:37 [PATCH] ASoC: sun4i: Implement MIC1 capture Maxime Ripard
2015-11-30 15:37 ` Maxime Ripard
2015-11-30 16:17 ` Mark Brown
2015-11-30 16:17   ` Mark Brown
2015-12-01  9:14   ` Maxime Ripard
2015-12-01  9:14     ` Maxime Ripard
2015-12-01  9:14     ` Maxime Ripard
2015-11-30 16:21 ` kbuild test robot
2015-11-30 16:21   ` kbuild test robot
2015-11-30 16:21   ` kbuild test robot
2015-11-30 16:23 ` Applied "ASoC: sun4i: Implement MIC1 capture" to the asoc tree Mark Brown

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.