linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format
@ 2011-06-06 11:38 Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 2/6] ASoC: AD1836: Add ADC/DAC controls helper macros Lars-Peter Clausen
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2011-06-06 11:38 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel, device-drivers-devel, linux-kernel, Lars-Peter Clausen

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>

---
This patch doesn't need to go into stable since there are currently no users of
PCM formats other than S32, which is the default.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1836.c |   14 +++++++-------
 sound/soc/codecs/ad1836.h |    6 ++++++
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index ab63d52..754c496 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -145,22 +145,22 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
 	/* bit size */
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
-		word_len = 3;
+		word_len = AD1836_WORD_LEN_16;
 		break;
 	case SNDRV_PCM_FORMAT_S20_3LE:
-		word_len = 1;
+		word_len = AD1836_WORD_LEN_20;
 		break;
 	case SNDRV_PCM_FORMAT_S24_LE:
 	case SNDRV_PCM_FORMAT_S32_LE:
-		word_len = 0;
+		word_len = AD1836_WORD_LEN_24;
 		break;
 	}
 
-	snd_soc_update_bits(codec, AD1836_DAC_CTRL1,
-		AD1836_DAC_WORD_LEN_MASK, word_len);
+	snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK,
+		word_len << AD1836_DAC_WORD_LEN_OFFSET);
 
-	snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
-		AD1836_ADC_WORD_LEN_MASK, word_len);
+	snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK,
+		word_len << AD1836_ADC_WORD_OFFSET);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 8455967..9d6a3f8 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -25,6 +25,7 @@
 #define AD1836_DAC_SERFMT_PCK256       (0x4 << 5)
 #define AD1836_DAC_SERFMT_PCK128       (0x5 << 5)
 #define AD1836_DAC_WORD_LEN_MASK       0x18
+#define AD1836_DAC_WORD_LEN_OFFSET     3
 
 #define AD1836_DAC_CTRL2               1
 #define AD1836_DACL1_MUTE              0
@@ -51,6 +52,7 @@
 #define AD1836_ADCL2_MUTE 		2
 #define AD1836_ADCR2_MUTE 		3
 #define AD1836_ADC_WORD_LEN_MASK       0x30
+#define AD1836_ADC_WORD_OFFSET         5
 #define AD1836_ADC_SERFMT_MASK	       (7 << 6)
 #define AD1836_ADC_SERFMT_PCK256       (0x4 << 6)
 #define AD1836_ADC_SERFMT_PCK128       (0x5 << 6)
@@ -60,4 +62,8 @@
 
 #define AD1836_NUM_REGS                16
 
+#define AD1836_WORD_LEN_24 0x0
+#define AD1836_WORD_LEN_20 0x1
+#define AD1836_WORD_LEN_16 0x2
+
 #endif
-- 
1.7.2.5


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

* [PATCH 2/6] ASoC: AD1836: Add ADC/DAC controls helper macros
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
@ 2011-06-06 11:38 ` Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 3/6] ASoC: AD1836: Use snd_soc_update_bits for read-modify-write Lars-Peter Clausen
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2011-06-06 11:38 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel, device-drivers-devel, linux-kernel, Lars-Peter Clausen

The different ADC and DAC controls follow the same scheme, so add some helper
macros for declaring them.
This should make the code a bit more readable and also decreases the code size
a bit.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1836.c |   48 ++++++++++++++++++++++++--------------------
 sound/soc/codecs/ad1836.h |   23 ++++++---------------
 2 files changed, 33 insertions(+), 38 deletions(-)

diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 754c496..5c6d239 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -44,28 +44,32 @@ static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
 static const struct soc_enum ad1836_deemp_enum =
 	SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp);
 
+#define AD1836_DAC_VOLUME(x) \
+	SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \
+			AD1836_DAC_R_VOL(x), 0, 0x3FF, 0)
+
+#define AD1836_DAC_SWITCH(x) \
+	SOC_DOUBLE("DAC" #x " Playback Switch", AD1836_DAC_CTRL2, \
+			AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
+
+#define AD1836_ADC_SWITCH(x) \
+	SOC_DOUBLE("ADC" #x " Capture Switch", AD1836_ADC_CTRL2, \
+		AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
+
 static const struct snd_kcontrol_new ad1836_snd_controls[] = {
 	/* DAC volume control */
-	SOC_DOUBLE_R("DAC1 Volume", AD1836_DAC_L1_VOL,
-			AD1836_DAC_R1_VOL, 0, 0x3FF, 0),
-	SOC_DOUBLE_R("DAC2 Volume", AD1836_DAC_L2_VOL,
-			AD1836_DAC_R2_VOL, 0, 0x3FF, 0),
-	SOC_DOUBLE_R("DAC3 Volume", AD1836_DAC_L3_VOL,
-			AD1836_DAC_R3_VOL, 0, 0x3FF, 0),
+	AD1836_DAC_VOLUME(1),
+	AD1836_DAC_VOLUME(2),
+	AD1836_DAC_VOLUME(3),
 
 	/* ADC switch control */
-	SOC_DOUBLE("ADC1 Switch", AD1836_ADC_CTRL2, AD1836_ADCL1_MUTE,
-		AD1836_ADCR1_MUTE, 1, 1),
-	SOC_DOUBLE("ADC2 Switch", AD1836_ADC_CTRL2, AD1836_ADCL2_MUTE,
-		AD1836_ADCR2_MUTE, 1, 1),
+	AD1836_ADC_SWITCH(1),
+	AD1836_ADC_SWITCH(2),
 
 	/* DAC switch control */
-	SOC_DOUBLE("DAC1 Switch", AD1836_DAC_CTRL2, AD1836_DACL1_MUTE,
-		AD1836_DACR1_MUTE, 1, 1),
-	SOC_DOUBLE("DAC2 Switch", AD1836_DAC_CTRL2, AD1836_DACL2_MUTE,
-		AD1836_DACR2_MUTE, 1, 1),
-	SOC_DOUBLE("DAC3 Switch", AD1836_DAC_CTRL2, AD1836_DACL3_MUTE,
-		AD1836_DACR3_MUTE, 1, 1),
+	AD1836_DAC_SWITCH(1),
+	AD1836_DAC_SWITCH(2),
+	AD1836_DAC_SWITCH(3),
 
 	/* ADC high-pass filter */
 	SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
@@ -242,12 +246,12 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 	/* left/right diff:PGA/MUX */
 	snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
 	/* volume */
-	snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
+	snd_soc_write(codec, AD1836_DAC_L_VOL(1), 0x3FF);
+	snd_soc_write(codec, AD1836_DAC_R_VOL(1), 0x3FF);
+	snd_soc_write(codec, AD1836_DAC_L_VOL(2), 0x3FF);
+	snd_soc_write(codec, AD1836_DAC_R_VOL(2), 0x3FF);
+	snd_soc_write(codec, AD1836_DAC_L_VOL(3), 0x3FF);
+	snd_soc_write(codec, AD1836_DAC_R_VOL(3), 0x3FF);
 
 	snd_soc_add_controls(codec, ad1836_snd_controls,
 			     ARRAY_SIZE(ad1836_snd_controls));
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 9d6a3f8..f13402f 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -28,29 +28,20 @@
 #define AD1836_DAC_WORD_LEN_OFFSET     3
 
 #define AD1836_DAC_CTRL2               1
-#define AD1836_DACL1_MUTE              0
-#define AD1836_DACR1_MUTE              1
-#define AD1836_DACL2_MUTE              2
-#define AD1836_DACR2_MUTE              3
-#define AD1836_DACL3_MUTE              4
-#define AD1836_DACR3_MUTE              5
 
-#define AD1836_DAC_L1_VOL              2
-#define AD1836_DAC_R1_VOL              3
-#define AD1836_DAC_L2_VOL              4
-#define AD1836_DAC_R2_VOL              5
-#define AD1836_DAC_L3_VOL              6
-#define AD1836_DAC_R3_VOL              7
+/* These macros are one-based. So AD183X_MUTE_LEFT(1) will return the mute bit
+ * for the first ADC/DAC */
+#define AD1836_MUTE_LEFT(x) (((x) * 2) - 2)
+#define AD1836_MUTE_RIGHT(x) (((x) * 2) - 1)
+
+#define AD1836_DAC_L_VOL(x) ((x) * 2)
+#define AD1836_DAC_R_VOL(x) (1 + ((x) * 2))
 
 #define AD1836_ADC_CTRL1               12
 #define AD1836_ADC_POWERDOWN           7
 #define AD1836_ADC_HIGHPASS_FILTER     8
 
 #define AD1836_ADC_CTRL2               13
-#define AD1836_ADCL1_MUTE 		0
-#define AD1836_ADCR1_MUTE 		1
-#define AD1836_ADCL2_MUTE 		2
-#define AD1836_ADCR2_MUTE 		3
 #define AD1836_ADC_WORD_LEN_MASK       0x30
 #define AD1836_ADC_WORD_OFFSET         5
 #define AD1836_ADC_SERFMT_MASK	       (7 << 6)
-- 
1.7.2.5


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

* [PATCH 3/6] ASoC: AD1836: Use snd_soc_update_bits for read-modify-write
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 2/6] ASoC: AD1836: Add ADC/DAC controls helper macros Lars-Peter Clausen
@ 2011-06-06 11:38 ` Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 4/6] ASoC: AD1836: Add AD1835/AD1837/AD1838/AD1839 support Lars-Peter Clausen
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2011-06-06 11:38 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel, device-drivers-devel, linux-kernel, Lars-Peter Clausen

Use snd_soc_update_bits for read-modify-write register access instead of
open-coding it using snd_soc_read and snd_soc_write.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1836.c |   18 ++++++------------
 1 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 5c6d239..fde0f17 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -174,19 +174,15 @@ static int ad1836_soc_suspend(struct snd_soc_codec *codec,
 		pm_message_t state)
 {
 	/* reset clock control mode */
-	u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
-	adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
-
-	return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
+	return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+		AD1836_ADC_SERFMT_MASK, 0);
 }
 
 static int ad1836_soc_resume(struct snd_soc_codec *codec)
 {
 	/* restore clock control mode */
-	u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
-	adc_ctrl2 |= AD1836_ADC_AUX;
-
-	return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
+	return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+		AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
 }
 #else
 #define ad1836_soc_suspend NULL
@@ -266,10 +262,8 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 static int ad1836_remove(struct snd_soc_codec *codec)
 {
 	/* reset clock control mode */
-	u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
-	adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
-
-	return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
+	return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+		AD1836_ADC_SERFMT_MASK, 0);
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
-- 
1.7.2.5


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

* [PATCH 4/6] ASoC: AD1836: Add AD1835/AD1837/AD1838/AD1839 support
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 2/6] ASoC: AD1836: Add ADC/DAC controls helper macros Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 3/6] ASoC: AD1836: Use snd_soc_update_bits for read-modify-write Lars-Peter Clausen
@ 2011-06-06 11:38 ` Lars-Peter Clausen
  2011-06-06 20:53   ` Mark Brown
  2011-06-06 11:38 ` [PATCH 5/6] ASoC: AD1836: Remove unused fields from private struct Lars-Peter Clausen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Lars-Peter Clausen @ 2011-06-06 11:38 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel, device-drivers-devel, linux-kernel, Lars-Peter Clausen

The AD183X codec devices are mostly register compatible and can easily be
supported by the same driver.
The main difference between those devices is the number of DACs and ADCs.

This patch adjusts the driver to allocate the controls, DAPM widgets and
routes for the DACs and ADCs dynamically based on the chip type.

The AD1836 is a bit special in that it supports different modes for its second
ADC, so it needs some special handling. Right now the driver hardcodes the mode
to the differential PGA mode.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1836.c |  183 +++++++++++++++++++++++++++++++-------------
 1 files changed, 129 insertions(+), 54 deletions(-)

diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index fde0f17..a443cfe 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -30,10 +30,17 @@
 #include <linux/spi/spi.h>
 #include "ad1836.h"
 
+enum ad1836_type {
+	AD1835,
+	AD1836,
+	AD1838,
+};
+
 /* codec private data */
 struct ad1836_priv {
 	enum snd_soc_control_type control_type;
 	void *control_data;
+	enum ad1836_type type;
 };
 
 /*
@@ -56,21 +63,48 @@ static const struct soc_enum ad1836_deemp_enum =
 	SOC_DOUBLE("ADC" #x " Capture Switch", AD1836_ADC_CTRL2, \
 		AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
 
-static const struct snd_kcontrol_new ad1836_snd_controls[] = {
-	/* DAC volume control */
+static const struct snd_kcontrol_new ad183x_dac_controls[] = {
 	AD1836_DAC_VOLUME(1),
+	AD1836_DAC_SWITCH(1),
 	AD1836_DAC_VOLUME(2),
+	AD1836_DAC_SWITCH(2),
 	AD1836_DAC_VOLUME(3),
+	AD1836_DAC_SWITCH(3),
+	AD1836_DAC_VOLUME(4),
+	AD1836_DAC_SWITCH(4),
+};
+
+static const struct snd_soc_dapm_widget ad183x_dac_dapm_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("DAC1OUT"),
+	SND_SOC_DAPM_OUTPUT("DAC2OUT"),
+	SND_SOC_DAPM_OUTPUT("DAC3OUT"),
+	SND_SOC_DAPM_OUTPUT("DAC4OUT"),
+};
+
+static const struct snd_soc_dapm_route ad183x_dac_routes[] = {
+	{ "DAC1OUT", NULL, "DAC" },
+	{ "DAC2OUT", NULL, "DAC" },
+	{ "DAC3OUT", NULL, "DAC" },
+	{ "DAC4OUT", NULL, "DAC" },
+};
 
-	/* ADC switch control */
+static const struct snd_kcontrol_new ad183x_adc_controls[] = {
 	AD1836_ADC_SWITCH(1),
 	AD1836_ADC_SWITCH(2),
+	AD1836_ADC_SWITCH(3),
+};
 
-	/* DAC switch control */
-	AD1836_DAC_SWITCH(1),
-	AD1836_DAC_SWITCH(2),
-	AD1836_DAC_SWITCH(3),
+static const struct snd_soc_dapm_widget ad183x_adc_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("ADC1IN"),
+	SND_SOC_DAPM_INPUT("ADC2IN"),
+};
+
+static const struct snd_soc_dapm_route ad183x_adc_routes[] = {
+	{ "ADC", NULL, "ADC1IN" },
+	{ "ADC", NULL, "ADC2IN" },
+};
 
+static const struct snd_kcontrol_new ad183x_controls[] = {
 	/* ADC high-pass filter */
 	SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
 			AD1836_ADC_HIGHPASS_FILTER, 1, 0),
@@ -79,27 +113,17 @@ static const struct snd_kcontrol_new ad1836_snd_controls[] = {
 	SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
 };
 
-static const struct snd_soc_dapm_widget ad1836_dapm_widgets[] = {
+static const struct snd_soc_dapm_widget ad183x_dapm_widgets[] = {
 	SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
 				AD1836_DAC_POWERDOWN, 1),
 	SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
 	SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
 				AD1836_ADC_POWERDOWN, 1, NULL, 0),
-	SND_SOC_DAPM_OUTPUT("DAC1OUT"),
-	SND_SOC_DAPM_OUTPUT("DAC2OUT"),
-	SND_SOC_DAPM_OUTPUT("DAC3OUT"),
-	SND_SOC_DAPM_INPUT("ADC1IN"),
-	SND_SOC_DAPM_INPUT("ADC2IN"),
 };
 
-static const struct snd_soc_dapm_route audio_paths[] = {
+static const struct snd_soc_dapm_route ad183x_dapm_routes[] = {
 	{ "DAC", NULL, "ADC_PWR" },
 	{ "ADC", NULL, "ADC_PWR" },
-	{ "DAC1OUT", "DAC1 Switch", "DAC" },
-	{ "DAC2OUT", "DAC2 Switch", "DAC" },
-	{ "DAC3OUT", "DAC3 Switch", "DAC" },
-	{ "ADC", "ADC1 Switch", "ADC1IN" },
-	{ "ADC", "ADC2 Switch", "ADC2IN" },
 };
 
 /*
@@ -194,33 +218,44 @@ static struct snd_soc_dai_ops ad1836_dai_ops = {
 	.set_fmt = ad1836_set_dai_fmt,
 };
 
-/* codec DAI instance */
-static struct snd_soc_dai_driver ad1836_dai = {
-	.name = "ad1836-hifi",
-	.playback = {
-		.stream_name = "Playback",
-		.channels_min = 2,
-		.channels_max = 6,
-		.rates = SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
-			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
-	},
-	.capture = {
-		.stream_name = "Capture",
-		.channels_min = 2,
-		.channels_max = 4,
-		.rates = SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
-			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
-	},
-	.ops = &ad1836_dai_ops,
+#define AD183X_DAI(_name, num_dacs, num_adcs) \
+{ \
+	.name = _name "-hifi", \
+	.playback = { \
+		.stream_name = "Playback", \
+		.channels_min = 2, \
+		.channels_max = (num_dacs) * 2, \
+		.rates = SNDRV_PCM_RATE_48000,  \
+		.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
+			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
+	}, \
+	.capture = { \
+		.stream_name = "Capture", \
+		.channels_min = 2, \
+		.channels_max = (num_adcs) * 2, \
+		.rates = SNDRV_PCM_RATE_48000, \
+		.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
+			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
+	}, \
+	.ops = &ad1836_dai_ops, \
+}
+
+static struct snd_soc_dai_driver ad183x_dais[] = {
+	[AD1835] = AD183X_DAI("ad1835", 4, 1),
+	[AD1836] = AD183X_DAI("ad1836", 3, 2),
+	[AD1838] = AD183X_DAI("ad1838", 3, 1),
 };
 
 static int ad1836_probe(struct snd_soc_codec *codec)
 {
 	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	int num_dacs, num_adcs;
 	int ret = 0;
+	int i;
+
+	num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
+	num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
 
 	codec->control_data = ad1836->control_data;
 	ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
@@ -239,21 +274,42 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 	snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
 	/* unmute adc channles, adc aux mode */
 	snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
-	/* left/right diff:PGA/MUX */
-	snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
 	/* volume */
-	snd_soc_write(codec, AD1836_DAC_L_VOL(1), 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_R_VOL(1), 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_L_VOL(2), 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_R_VOL(2), 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_L_VOL(3), 0x3FF);
-	snd_soc_write(codec, AD1836_DAC_R_VOL(3), 0x3FF);
-
-	snd_soc_add_controls(codec, ad1836_snd_controls,
-			     ARRAY_SIZE(ad1836_snd_controls));
-	snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets,
-				  ARRAY_SIZE(ad1836_dapm_widgets));
-	snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
+	for (i = 1; i <= num_dacs; ++i) {
+		snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF);
+		snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF);
+	}
+
+	if (ad1836->type == AD1836) {
+		/* left/right diff:PGA/MUX */
+		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
+	} else {
+		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
+	}
+
+	ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_dapm_new_controls(dapm, ad183x_dac_dapm_widgets, num_dacs);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_dapm_new_controls(dapm, ad183x_adc_dapm_widgets, num_adcs);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_dapm_add_routes(dapm, ad183x_dac_routes, num_dacs);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_dapm_add_routes(dapm, ad183x_adc_routes, num_adcs);
+	if (ret)
+		return ret;
 
 	return ret;
 }
@@ -273,6 +329,13 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
 	.resume =       ad1836_soc_resume,
 	.reg_cache_size = AD1836_NUM_REGS,
 	.reg_word_size = sizeof(u16),
+
+	.controls = ad183x_controls,
+	.num_controls = ARRAY_SIZE(ad183x_controls),
+	.dapm_widgets = ad183x_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets),
+	.dapm_routes = ad183x_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
 };
 
 static int __devinit ad1836_spi_probe(struct spi_device *spi)
@@ -284,12 +347,14 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi)
 	if (ad1836 == NULL)
 		return -ENOMEM;
 
+	ad1836->type = spi_get_device_id(spi)->driver_data;
+
 	spi_set_drvdata(spi, ad1836);
 	ad1836->control_data = spi;
 	ad1836->control_type = SND_SOC_SPI;
 
 	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_ad1836, &ad1836_dai, 1);
+			&soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
 	if (ret < 0)
 		kfree(ad1836);
 	return ret;
@@ -301,6 +366,15 @@ static int __devexit ad1836_spi_remove(struct spi_device *spi)
 	kfree(spi_get_drvdata(spi));
 	return 0;
 }
+static const struct spi_device_id ad1836_ids[] = {
+	{ "ad1835", AD1835 },
+	{ "ad1836", AD1836 },
+	{ "ad1837", AD1835 },
+	{ "ad1838", AD1838 },
+	{ "ad1839", AD1838 },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, ad1836_ids);
 
 static struct spi_driver ad1836_spi_driver = {
 	.driver = {
@@ -309,6 +383,7 @@ static struct spi_driver ad1836_spi_driver = {
 	},
 	.probe		= ad1836_spi_probe,
 	.remove		= __devexit_p(ad1836_spi_remove),
+	.id_table	= ad1836_ids,
 };
 
 static int __init ad1836_init(void)
-- 
1.7.2.5


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

* [PATCH 5/6] ASoC: AD1836: Remove unused fields from private struct
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
                   ` (2 preceding siblings ...)
  2011-06-06 11:38 ` [PATCH 4/6] ASoC: AD1836: Add AD1835/AD1837/AD1838/AD1839 support Lars-Peter Clausen
@ 2011-06-06 11:38 ` Lars-Peter Clausen
  2011-06-06 11:38 ` [PATCH 6/6] ASoC: AD1836: Add input gain control for ADC2 Lars-Peter Clausen
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2011-06-06 11:38 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel, device-drivers-devel, linux-kernel, Lars-Peter Clausen

The control_type field is never used, so it can be removed.
The control_data field is used to initialize the codec's control_data field, but
since this is also done by the snd-soc-cache core, the redundant assignment can
be removed and the field can be dropped.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1836.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index a443cfe..75ff5a5 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -38,8 +38,6 @@ enum ad1836_type {
 
 /* codec private data */
 struct ad1836_priv {
-	enum snd_soc_control_type control_type;
-	void *control_data;
 	enum ad1836_type type;
 };
 
@@ -257,7 +255,6 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 	num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
 	num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
 
-	codec->control_data = ad1836->control_data;
 	ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
 	if (ret < 0) {
 		dev_err(codec->dev, "failed to set cache I/O: %d\n",
@@ -350,8 +347,6 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi)
 	ad1836->type = spi_get_device_id(spi)->driver_data;
 
 	spi_set_drvdata(spi, ad1836);
-	ad1836->control_data = spi;
-	ad1836->control_type = SND_SOC_SPI;
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
-- 
1.7.2.5


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

* [PATCH 6/6] ASoC: AD1836: Add input gain control for ADC2
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
                   ` (3 preceding siblings ...)
  2011-06-06 11:38 ` [PATCH 5/6] ASoC: AD1836: Remove unused fields from private struct Lars-Peter Clausen
@ 2011-06-06 11:38 ` Lars-Peter Clausen
  2011-06-06 19:39 ` [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Liam Girdwood
  2011-06-06 20:55 ` Mark Brown
  6 siblings, 0 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2011-06-06 11:38 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel, device-drivers-devel, linux-kernel, Lars-Peter Clausen

The AD1836 has a PGA for its second ADC. This patch adds a control for
adjusting the the gain of the PGA.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1836.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 75ff5a5..1e9a801 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -124,6 +124,13 @@ static const struct snd_soc_dapm_route ad183x_dapm_routes[] = {
 	{ "ADC", NULL, "ADC_PWR" },
 };
 
+static const DECLARE_TLV_DB_SCALE(ad1836_in_tlv, 0, 300, 0);
+
+static const struct snd_kcontrol_new ad1836_controls[] = {
+	SOC_DOUBLE_TLV("ADC2 Capture Volume", AD183X_ADC_CTRL1, 3, 0, 4, 0,
+	    ad1836_in_tlv),
+};
+
 /*
  * DAI ops entries
  */
@@ -280,6 +287,10 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 	if (ad1836->type == AD1836) {
 		/* left/right diff:PGA/MUX */
 		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
+		ret = snd_soc_add_controls(codec, ad1836_controls,
+				ARRAY_SIZE(ad1836_controls));
+		if (ret)
+			return ret;
 	} else {
 		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
 	}
-- 
1.7.2.5


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

* Re: [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
                   ` (4 preceding siblings ...)
  2011-06-06 11:38 ` [PATCH 6/6] ASoC: AD1836: Add input gain control for ADC2 Lars-Peter Clausen
@ 2011-06-06 19:39 ` Liam Girdwood
  2011-06-06 20:55 ` Mark Brown
  6 siblings, 0 replies; 9+ messages in thread
From: Liam Girdwood @ 2011-06-06 19:39 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: Mark Brown, alsa-devel, device-drivers-devel, linux-kernel

On 06/06/11 12:38, Lars-Peter Clausen wrote:
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> 
> ---
> This patch doesn't need to go into stable since there are currently no users of
> PCM formats other than S32, which is the default.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---

All

Acked-by: Liam Girdwood <lrg@ti.com>

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

* Re: [PATCH 4/6] ASoC: AD1836: Add AD1835/AD1837/AD1838/AD1839 support
  2011-06-06 11:38 ` [PATCH 4/6] ASoC: AD1836: Add AD1835/AD1837/AD1838/AD1839 support Lars-Peter Clausen
@ 2011-06-06 20:53   ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2011-06-06 20:53 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: Liam Girdwood, alsa-devel, device-drivers-devel, linux-kernel

On Mon, Jun 06, 2011 at 01:38:38PM +0200, Lars-Peter Clausen wrote:
> The AD183X codec devices are mostly register compatible and can easily be
> supported by the same driver.
> The main difference between those devices is the number of DACs and ADCs.

Please try to fix whatever it is gives this really weird word wrapping
in your changelogs - they frequently have line breaks in the middle of
paragraphs for some reason.

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

* Re: [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format
  2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
                   ` (5 preceding siblings ...)
  2011-06-06 19:39 ` [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Liam Girdwood
@ 2011-06-06 20:55 ` Mark Brown
  6 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2011-06-06 20:55 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: Liam Girdwood, alsa-devel, device-drivers-devel, linux-kernel

On Mon, Jun 06, 2011 at 01:38:35PM +0200, Lars-Peter Clausen wrote:
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>

All applied, thanks.

> This patch doesn't need to go into stable since there are currently no users of
> PCM formats other than S32, which is the default.

Even if there's no mainline users it's still worth distributing the fix
so out of tree users get to pick it up.

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

end of thread, other threads:[~2011-06-06 20:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-06 11:38 [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Lars-Peter Clausen
2011-06-06 11:38 ` [PATCH 2/6] ASoC: AD1836: Add ADC/DAC controls helper macros Lars-Peter Clausen
2011-06-06 11:38 ` [PATCH 3/6] ASoC: AD1836: Use snd_soc_update_bits for read-modify-write Lars-Peter Clausen
2011-06-06 11:38 ` [PATCH 4/6] ASoC: AD1836: Add AD1835/AD1837/AD1838/AD1839 support Lars-Peter Clausen
2011-06-06 20:53   ` Mark Brown
2011-06-06 11:38 ` [PATCH 5/6] ASoC: AD1836: Remove unused fields from private struct Lars-Peter Clausen
2011-06-06 11:38 ` [PATCH 6/6] ASoC: AD1836: Add input gain control for ADC2 Lars-Peter Clausen
2011-06-06 19:39 ` [PATCH 1/6] ASoC: AD1836: Fix setting the PCM format Liam Girdwood
2011-06-06 20:55 ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).