[alsa-devel] ASoC updates for 2.6.30
The following changes since commit 93b760b7072ca6972c15c798e97af3f830d8bbba: Mark Brown (1): ASoC: Implement SPI device unregistration for WM8731
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.30
Mark Brown (3): ASoC: Check for errors when writing WM8731 reset register ASoC: Add device init/exit annotations to new-style Wolfson CODEC drivers ASoC: Disable WM8731 line bypass by default
Peter Ujfalusi (1): ASoC: TWL4030: Add digital loopback support
sound/soc/codecs/twl4030.c | 56 +++++++++++++++++++++++++++++++++++++++---- sound/soc/codecs/wm8350.c | 2 +- sound/soc/codecs/wm8731.c | 19 +++++++++++---- sound/soc/codecs/wm8900.c | 8 +++--- sound/soc/codecs/wm8903.c | 8 +++--- 5 files changed, 73 insertions(+), 20 deletions(-)
From: Peter Ujfalusi peter.ujfalusi@nokia.com
This patch adds the digital loopback/bypass support for twl4030 codec.
The digital loopback will let the digimic0 (routed in the TX1 capture path inside of TWL4030) data to be routed back to the RX2 playback path (I2S stereo). It can also route the analog capture date routed through the TX1 back to RX2.
Effectively the digital loopback is routing the audio from the TX1 capture path to the RX2 playback path.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/twl4030.c | 56 +++++++++++++++++++++++++++++++++++++++---- 1 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index c26854b..535d8ce 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -504,6 +504,25 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control = static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
+/* Digital bypass gain, 0 mutes the bypass */ +static const unsigned int twl4030_dapm_dbypass_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0, 3, TLV_DB_SCALE_ITEM(-2400, 0, 1), + 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0), +}; + +/* Digital bypass left (TX1L -> RX2L) */ +static const struct snd_kcontrol_new twl4030_dapm_dbypassl_control = + SOC_DAPM_SINGLE_TLV("Volume", + TWL4030_REG_ATX2ARXPGA, 3, 7, 0, + twl4030_dapm_dbypass_tlv); + +/* Digital bypass right (TX1R -> RX2R) */ +static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control = + SOC_DAPM_SINGLE_TLV("Volume", + TWL4030_REG_ATX2ARXPGA, 0, 7, 0, + twl4030_dapm_dbypass_tlv); + static int micpath_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -608,12 +627,22 @@ static int bypass_event(struct snd_soc_dapm_widget *w, unsigned char reg;
reg = twl4030_read_reg_cache(w->codec, m->reg); - if (reg & (1 << m->shift)) - twl4030->bypass_state |= - (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); - else - twl4030->bypass_state &= - ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); + + if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) { + /* Analog bypass */ + if (reg & (1 << m->shift)) + twl4030->bypass_state |= + (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); + else + twl4030->bypass_state &= + ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); + } else { + /* Digital bypass */ + if (reg & (0x7 << m->shift)) + twl4030->bypass_state |= (1 << (m->shift ? 5 : 4)); + else + twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4)); + }
if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { if (twl4030->bypass_state) @@ -934,6 +963,14 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { &twl4030_dapm_abypassl2_control, bypass_event, SND_SOC_DAPM_POST_REG),
+ /* Digital bypasses */ + SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_dbypassl_control, bypass_event, + SND_SOC_DAPM_POST_REG), + SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_dbypassr_control, bypass_event, + SND_SOC_DAPM_POST_REG), + SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", TWL4030_REG_AVDAC_CTL, @@ -1118,6 +1155,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
+ /* Digital bypass routes */ + {"Right Digital Loopback", "Volume", "TX1 Capture Route"}, + {"Left Digital Loopback", "Volume", "TX1 Capture Route"}, + + {"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"}, + {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"}, + };
static int twl4030_add_widgets(struct snd_soc_codec *codec)
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/wm8731.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 4191bdb..9c9fc3b 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -574,9 +574,14 @@ static int wm8731_register(struct wm8731_priv *wm8731)
memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
+ ret = wm8731_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + return ret; + } + wm8731_dai.dev = codec->dev;
- wm8731_reset(codec); wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Latch the update bits */
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/wm8350.c | 2 +- sound/soc/codecs/wm8731.c | 8 ++++---- sound/soc/codecs/wm8900.c | 8 ++++---- sound/soc/codecs/wm8903.c | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index d356278..359e5cc 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1574,7 +1574,7 @@ struct snd_soc_codec_device soc_codec_dev_wm8350 = { }; EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
-static int wm8350_codec_probe(struct platform_device *pdev) +static __devinit int wm8350_codec_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_data *priv; diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 9c9fc3b..4cac319 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -686,8 +686,8 @@ static struct spi_driver wm8731_spi_driver = { #endif /* CONFIG_SPI_MASTER */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int wm8731_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8731_priv *wm8731; struct snd_soc_codec *codec; @@ -707,7 +707,7 @@ static int wm8731_i2c_probe(struct i2c_client *i2c, return wm8731_register(wm8731); }
-static int wm8731_i2c_remove(struct i2c_client *client) +static __devexit int wm8731_i2c_remove(struct i2c_client *client) { struct wm8731_priv *wm8731 = i2c_get_clientdata(client); wm8731_unregister(wm8731); @@ -726,7 +726,7 @@ static struct i2c_driver wm8731_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8731_i2c_probe, - .remove = wm8731_i2c_remove, + .remove = __devexit_p(wm8731_i2c_remove), .id_table = wm8731_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 85c0f1b..da5ca64 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1272,8 +1272,8 @@ static int wm8900_resume(struct platform_device *pdev)
static struct snd_soc_codec *wm8900_codec;
-static int wm8900_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8900_priv *wm8900; struct snd_soc_codec *codec; @@ -1372,7 +1372,7 @@ err: return ret; }
-static int wm8900_i2c_remove(struct i2c_client *client) +static __devexit int wm8900_i2c_remove(struct i2c_client *client) { snd_soc_unregister_dai(&wm8900_dai); snd_soc_unregister_codec(wm8900_codec); @@ -1398,7 +1398,7 @@ static struct i2c_driver wm8900_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8900_i2c_probe, - .remove = wm8900_i2c_remove, + .remove = __devexit_p(wm8900_i2c_remove), .id_table = wm8900_i2c_id, };
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index d36b2b1..c6fa8a7 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1562,8 +1562,8 @@ static int wm8903_resume(struct platform_device *pdev)
static struct snd_soc_codec *wm8903_codec;
-static int wm8903_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8903_priv *wm8903; struct snd_soc_codec *codec; @@ -1669,7 +1669,7 @@ err: return ret; }
-static int wm8903_i2c_remove(struct i2c_client *client) +static __devexit int wm8903_i2c_remove(struct i2c_client *client) { struct snd_soc_codec *codec = i2c_get_clientdata(client);
@@ -1699,7 +1699,7 @@ static struct i2c_driver wm8903_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8903_i2c_probe, - .remove = wm8903_i2c_remove, + .remove = __devexit_p(wm8903_i2c_remove), .id_table = wm8903_i2c_id, };
This avoids temporarily enabling the ouput stages during startup which can cause audible effets in the output stages.
Reported-by: Fredrik RedgÄrd rik@svep.se Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/wm8731.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 4cac319..9e7ebcc 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -594,6 +594,10 @@ static int wm8731_register(struct wm8731_priv *wm8731) reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
+ /* Disable bypass path by default */ + reg = wm8731_read_reg_cache(codec, WM8731_APANA); + wm8731_write(codec, WM8731_APANA, reg & ~0x4); + wm8731_codec = codec;
ret = snd_soc_register_codec(codec);
At Thu, 19 Feb 2009 19:01:41 +0000, Mark Brown wrote:
The following changes since commit 93b760b7072ca6972c15c798e97af3f830d8bbba: Mark Brown (1): ASoC: Implement SPI device unregistration for WM8731
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.30
Pulled now. Thanks.
Takashi
participants (2)
-
Mark Brown
-
Takashi Iwai