From: Ashish Chavan <ashish.chavan@kpitcummins.com>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>, <lrg@ti.com>,
alsa-devel <alsa-devel@alsa-project.org>
Cc: David Dajun Chen <david.chen@diasemi.com>,
<kuninori.morimoto.gx@renesas.com>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: [alsa-devel] [PATCH 7/9] ASoC: da7210: Add support for ALC and Noise suppression
Date: Wed, 12 Oct 2011 20:37:50 +0530 [thread overview]
Message-ID: <1318432070.12107.426.camel@matrix> (raw)
This patch adds controls to set following ALC parameters,
- Max gain, Min gain, Noise gain, Attack rate, Release rate and delay
It also adds a switch to enable/disable noise suppression.
As per DA7210 data sheet, ALC and noise suppression can be enabled
only if certain conditions are met. This condition checks are handled
by simply using "_EXT" version of controls to capture change events.
Tested on Samsung SMDK6410 board with DA7210 evaluation board.
Signed-off-by: Ashish Chavan <ashish.chavan@kpitcummins.com>
Signed-off-by: David Dajun Chen <dchen@diasemi.com>
---
sound/soc/codecs/da7210.c | 104 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 104 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index eb12c82..9cab62a 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -26,6 +26,7 @@
#include <sound/tlv.h>
/* DA7210 register space */
+#define DA7210_CONTROL 0x01
#define DA7210_STATUS 0x02
#define DA7210_STARTUP1 0x03
#define DA7210_MIC_L 0x07
@@ -65,6 +66,12 @@
#define DA7210_PLL_DIV2 0x2A
#define DA7210_PLL_DIV3 0x2B
#define DA7210_PLL 0x2C
+#define DA7210_ALC_MAX 0x83
+#define DA7210_ALC_MIN 0x84
+#define DA7210_ALC_NOIS 0x85
+#define DA7210_ALC_ATT 0x86
+#define DA7210_ALC_REL 0x87
+#define DA7210_ALC_DEL 0x88
#define DA7210_A_HID_UNLOCK 0x8A
#define DA7210_A_TEST_UNLOCK 0x8B
#define DA7210_A_PLL1 0x90
@@ -87,6 +94,7 @@
#define DA7210_IN_R_EN (1 << 7)
/* ADC bit fields */
+#define DA7210_ADC_ALC_EN (1 << 0)
#define DA7210_ADC_L_EN (1 << 3)
#define DA7210_ADC_R_EN (1 << 7)
@@ -165,9 +173,11 @@
#define DA7210_OUT2_EN (1 << 7)
/* AUX1_L bit fields */
+#define DA7210_AUX1_L_VOL (0x3F << 0)
#define DA7210_AUX1_L_EN (1 << 7)
/* AUX1_R bit fields */
+#define DA7210_AUX1_R_VOL (0x3F << 0)
#define DA7210_AUX1_R_EN (1 << 7)
/* AUX2 bit fields */
@@ -176,6 +186,19 @@
/* SOFTMUTE bit fields */
#define DA7210_RAMP_EN (1 << 6)
+/* CONTROL bit fields */
+#define DA7210_NOISE_SUP_EN (1 << 3)
+
+/* IN_GAIN bit fields */
+#define DA7210_INPGA_L_VOL (0x0F << 0)
+#define DA7210_INPGA_R_VOL (0xF0 << 0)
+
+/* ZERO_CROSS bit fields */
+#define DA7210_AUX1_L_ZC (1 << 0)
+#define DA7210_AUX1_R_ZC (1 << 1)
+#define DA7210_HP_L_ZC (1 << 6)
+#define DA7210_HP_R_ZC (1 << 7)
+
/* Default gain/vol values */
#define DA7210_DFLT_DAC_GAIN 0x10 /* 0dB */
#define DA7210_DFLT_OUT1_VOL 0x35 /* 0dB */
@@ -185,6 +208,10 @@
#define DA7210_DFLT_AUX2_VOL 0x02 /* 6dB */
#define DA7210_DFLT_INPGA_VOL 0x07 /* 6dB */
+/* Minimum INPGA and AUX1 volume to enable noise suppression */
+#define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */
+#define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */
+
#define DA7210_VERSION "0.0.1"
/*
@@ -247,6 +274,70 @@ static const char *da7210_hp_mode_txt[] = {
static const struct soc_enum da7210_hp_mode_sel =
SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt);
+/* ALC can be enabled only if noise suppression is disabled */
+static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 *reg_cache = codec->reg_cache;
+
+ if (ucontrol->value.integer.value[0]) {
+ /* Check if noise suppression is enabled */
+ if (reg_cache[DA7210_CONTROL] & DA7210_NOISE_SUP_EN) {
+ dev_dbg(codec->dev, "Failed to enable ALC\n");
+ return -EPERM;
+ }
+ }
+ /* If all conditions are met or we are actually disabling ALC */
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+/* Noise suppression can be enabled only if following conditions are met
+ * ALC disabled
+ * ZC enabled for HP and AUX1 PGA
+ * INPGA_L_VOL and INPGA_R_VOL >= 10.5 dB
+ * AUX1_L_VOL and AUX1_R_VOL >= 6 dB
+ */
+static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 *reg_cache = codec->reg_cache;
+ u8 val;
+
+ if (ucontrol->value.integer.value[0]) {
+ /* Check if ALC is enabled */
+ if (reg_cache[DA7210_ADC] & DA7210_ADC_ALC_EN)
+ goto err;
+
+ /* Check ZC for HP and AUX1 PGA */
+ if ((reg_cache[DA7210_ZERO_CROSS] &
+ (DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC |
+ DA7210_HP_R_ZC)) != 0xc3)
+ goto err;
+
+ /* Check INPGA_L_VOL and INPGA_R_VOL */
+ val = reg_cache[DA7210_IN_GAIN];
+ if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) ||
+ (((val & DA7210_INPGA_R_VOL) >> 4) <
+ DA7210_INPGA_MIN_VOL_NS))
+ goto err;
+
+ /* Check AUX1_L_VOL and AUX1_R_VOL */
+ if (((reg_cache[DA7210_AUX1_L] & DA7210_AUX1_L_VOL) <
+ DA7210_AUX1_MIN_VOL_NS) ||
+ ((reg_cache[DA7210_AUX1_R] & DA7210_AUX1_R_VOL) <
+ DA7210_AUX1_MIN_VOL_NS))
+ goto err;
+ }
+ /* If all conditions are met or we are actually disabling Noise sup */
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+
+err:
+ dev_dbg(codec->dev, "Failed to enable Noise suppression\n");
+ return -EPERM;
+}
+
static const struct snd_kcontrol_new da7210_snd_controls[] = {
SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
@@ -322,6 +413,19 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
SOC_DOUBLE("Headphone ZC Switch", DA7210_ZERO_CROSS, 6, 7, 1, 0),
SOC_ENUM("Headphone Class", da7210_hp_mode_sel),
+
+ /* ALC controls */
+ SOC_SINGLE_EXT("ALC Enable Switch", DA7210_ADC, 0, 1, 0,
+ snd_soc_get_volsw, da7210_put_alc_sw),
+ SOC_SINGLE("ALC Capture Max Gain", DA7210_ALC_MAX, 0, 0x3F, 0),
+ SOC_SINGLE("ALC Capture Min Gain", DA7210_ALC_MIN, 0, 0x3F, 0),
+ SOC_SINGLE("ALC Capture Noise Gain", DA7210_ALC_NOIS, 0, 0x3F, 0),
+ SOC_SINGLE("ALC Capture Attack Rate", DA7210_ALC_ATT, 0, 0xFF, 0),
+ SOC_SINGLE("ALC Capture Release Rate", DA7210_ALC_REL, 0, 0xFF, 0),
+ SOC_SINGLE("ALC Capture Release Delay", DA7210_ALC_DEL, 0, 0xFF, 0),
+
+ SOC_SINGLE_EXT("Noise Suppression Enable Switch", DA7210_CONTROL, 3, 1,
+ 0, snd_soc_get_volsw, da7210_put_noise_sup_sw),
};
/* Codec private data */
--
1.7.1
next reply other threads:[~2011-10-12 15:00 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-12 15:07 Ashish Chavan [this message]
2011-10-12 15:04 ` [alsa-devel] [PATCH 7/9] ASoC: da7210: Add support for ALC and Noise suppression Mark Brown
2011-10-13 9:15 ` Ashish Chavan
2011-10-13 10:26 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1318432070.12107.426.camel@matrix \
--to=ashish.chavan@kpitcummins.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=david.chen@diasemi.com \
--cc=kuninori.morimoto.gx@renesas.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lrg@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox