* [PATCH 2/5] ASoC: wm8903: Make interrupt handler use regmap directly
2012-06-09 3:09 [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Mark Brown
@ 2012-06-09 3:09 ` Mark Brown
2012-06-09 3:09 ` [PATCH 3/5] ASoC: wm8903: Move interrupt request to I2C probe Mark Brown
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2012-06-09 3:09 UTC (permalink / raw)
To: Stephen Warren, Liam Girdwood; +Cc: alsa-devel, patches, Mark Brown
There's no urgent need for the interrupt handler to use the ASoC I/O
functions and it'll support a further move in where we request the
interrupt so call the regmap APIs directly.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 48 ++++++++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 16 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 7200088..8fe9b78 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1830,17 +1830,27 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
static irqreturn_t wm8903_irq(int irq, void *data)
{
- struct snd_soc_codec *codec = data;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int mic_report;
- int int_pol;
- int int_val = 0;
- int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
+ struct wm8903_priv *wm8903 = data;
+ int mic_report, ret;
+ unsigned int int_val, mask, int_pol;
+
+ ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1_MASK,
+ &mask);
+ if (ret != 0) {
+ dev_err(wm8903->dev, "Failed to read IRQ mask: %d\n", ret);
+ return IRQ_NONE;
+ }
+
+ ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1, &int_val);
+ if (ret != 0) {
+ dev_err(wm8903->dev, "Failed to read IRQ status: %d\n", ret);
+ return IRQ_NONE;
+ }
- int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
+ int_val &= ~mask;
if (int_val & WM8903_WSEQ_BUSY_EINT) {
- dev_warn(codec->dev, "Write sequencer done\n");
+ dev_warn(wm8903->dev, "Write sequencer done\n");
}
/*
@@ -1851,22 +1861,28 @@ static irqreturn_t wm8903_irq(int irq, void *data)
* the polarity register.
*/
mic_report = wm8903->mic_last_report;
- int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
+ ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1,
+ &int_pol);
+ if (ret != 0) {
+ dev_err(wm8903->dev, "Failed to read interrupt polarity: %d\n",
+ ret);
+ return IRQ_HANDLED;
+ }
#ifndef CONFIG_SND_SOC_WM8903_MODULE
if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
- trace_snd_soc_jack_irq(dev_name(codec->dev));
+ trace_snd_soc_jack_irq(dev_name(wm8903->dev));
#endif
if (int_val & WM8903_MICSHRT_EINT) {
- dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
+ dev_dbg(wm8903->dev, "Microphone short (pol=%x)\n", int_pol);
mic_report ^= wm8903->mic_short;
int_pol ^= WM8903_MICSHRT_INV;
}
if (int_val & WM8903_MICDET_EINT) {
- dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol);
+ dev_dbg(wm8903->dev, "Microphone detect (pol=%x)\n", int_pol);
mic_report ^= wm8903->mic_det;
int_pol ^= WM8903_MICDET_INV;
@@ -1874,8 +1890,8 @@ static irqreturn_t wm8903_irq(int irq, void *data)
msleep(wm8903->mic_delay);
}
- snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1,
- WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
+ regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1,
+ WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
snd_soc_jack_report(wm8903->mic_jack, mic_report,
wm8903->mic_short | wm8903->mic_det);
@@ -2108,7 +2124,7 @@ static int wm8903_probe(struct snd_soc_codec *codec)
ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
trigger | IRQF_ONESHOT,
- "wm8903", codec);
+ "wm8903", wm8903);
if (ret != 0) {
dev_err(codec->dev, "Failed to request IRQ: %d\n",
ret);
@@ -2164,7 +2180,7 @@ static int wm8903_remove(struct snd_soc_codec *codec)
wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
if (wm8903->irq)
- free_irq(wm8903->irq, codec);
+ free_irq(wm8903->irq, wm8903);
return 0;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/5] ASoC: wm8903: Move interrupt request to I2C probe
2012-06-09 3:09 [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Mark Brown
2012-06-09 3:09 ` [PATCH 2/5] ASoC: wm8903: Make interrupt handler use regmap directly Mark Brown
@ 2012-06-09 3:09 ` Mark Brown
2012-06-09 3:09 ` [PATCH 4/5] ASoC: wm8903: Move register default changes " Mark Brown
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2012-06-09 3:09 UTC (permalink / raw)
To: Stephen Warren, Liam Girdwood; +Cc: alsa-devel, patches, Mark Brown
There's no reason to defer requesting of the interrupt until the CODEC
probe and doing so results in more work if we hit an error as we'll have
registered the CODEC with the core. It's neater to acquire as many of the
resources we'll need as we can in the bus probe function.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 66 +++++++++++++++++++++------------------------
1 file changed, 31 insertions(+), 35 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 8fe9b78..21c4dd2 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -122,7 +122,6 @@ struct wm8903_priv {
int sysclk;
int sysclk_src;
- int irq;
int fs;
int deemph;
@@ -2096,9 +2095,7 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903)
static int wm8903_probe(struct snd_soc_codec *codec)
{
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct wm8903_platform_data *pdata = wm8903->pdata;
int ret;
- int trigger, irq_pol;
u16 val;
wm8903->codec = codec;
@@ -2110,32 +2107,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
return ret;
}
- if (wm8903->irq) {
- if (pdata->irq_active_low) {
- trigger = IRQF_TRIGGER_LOW;
- irq_pol = WM8903_IRQ_POL;
- } else {
- trigger = IRQF_TRIGGER_HIGH;
- irq_pol = 0;
- }
-
- snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
- WM8903_IRQ_POL, irq_pol);
-
- ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
- trigger | IRQF_ONESHOT,
- "wm8903", wm8903);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request IRQ: %d\n",
- ret);
- return ret;
- }
-
- /* Enable write sequencer interrupts */
- snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
- WM8903_IM_WSEQ_BUSY_EINT, 0);
- }
-
/* power on device */
wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -2176,11 +2147,7 @@ static int wm8903_probe(struct snd_soc_codec *codec)
/* power down chip */
static int wm8903_remove(struct snd_soc_codec *codec)
{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
- if (wm8903->irq)
- free_irq(wm8903->irq, wm8903);
return 0;
}
@@ -2290,8 +2257,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
{
struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct wm8903_priv *wm8903;
+ int trigger;
bool mic_gpio = false;
- unsigned int val;
+ unsigned int val, irq_pol;
int ret, i;
wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv),
@@ -2309,7 +2277,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
}
i2c_set_clientdata(i2c, wm8903);
- wm8903->irq = i2c->irq;
/* If no platform data was supplied, create storage for defaults */
if (pdata) {
@@ -2403,6 +2370,33 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
wm8903->mic_delay = pdata->micdet_delay;
+ if (i2c->irq) {
+ if (pdata->irq_active_low) {
+ trigger = IRQF_TRIGGER_LOW;
+ irq_pol = WM8903_IRQ_POL;
+ } else {
+ trigger = IRQF_TRIGGER_HIGH;
+ irq_pol = 0;
+ }
+
+ regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_CONTROL,
+ WM8903_IRQ_POL, irq_pol);
+
+ ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
+ trigger | IRQF_ONESHOT,
+ "wm8903", wm8903);
+ if (ret != 0) {
+ dev_err(wm8903->dev, "Failed to request IRQ: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Enable write sequencer interrupts */
+ regmap_update_bits(wm8903->regmap,
+ WM8903_INTERRUPT_STATUS_1_MASK,
+ WM8903_IM_WSEQ_BUSY_EINT, 0);
+ }
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8903, &wm8903_dai, 1);
if (ret != 0)
@@ -2418,6 +2412,8 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
{
struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
+ if (client->irq)
+ free_irq(client->irq, wm8903);
wm8903_free_gpio(wm8903);
regmap_exit(wm8903->regmap);
snd_soc_unregister_codec(&client->dev);
--
1.7.10
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/5] ASoC: wm8903: Move register default changes to I2C probe
2012-06-09 3:09 [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Mark Brown
2012-06-09 3:09 ` [PATCH 2/5] ASoC: wm8903: Make interrupt handler use regmap directly Mark Brown
2012-06-09 3:09 ` [PATCH 3/5] ASoC: wm8903: Move interrupt request to I2C probe Mark Brown
@ 2012-06-09 3:09 ` Mark Brown
2012-06-09 3:09 ` [PATCH 5/5] ASoC: wm8903: Convert to devm_regmap_init_i2c() Mark Brown
2012-06-11 17:26 ` [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Stephen Warren
4 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2012-06-09 3:09 UTC (permalink / raw)
To: Stephen Warren, Liam Girdwood; +Cc: alsa-devel, patches, Mark Brown
Also convert to use update_bits() while we're at it. No great need to do
this, it's just a bit neater to do as much as possible in the I2C probe.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 63 ++++++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 32 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 21c4dd2..9410d54 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2096,7 +2096,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
{
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
int ret;
- u16 val;
wm8903->codec = codec;
codec->control_data = wm8903->regmap;
@@ -2110,37 +2109,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
/* power on device */
wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* Latch volume update bits */
- val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
- val |= WM8903_ADCVU;
- snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
- snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
- val |= WM8903_DACVU;
- snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
- snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
- val |= WM8903_HPOUTVU;
- snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
- val |= WM8903_LINEOUTVU;
- snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
- val |= WM8903_SPKVU;
- snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
-
- /* Enable DAC soft mute by default */
- snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
- WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
- WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
-
return ret;
}
@@ -2397,6 +2365,37 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
WM8903_IM_WSEQ_BUSY_EINT, 0);
}
+ /* Latch volume update bits */
+ regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_LEFT,
+ WM8903_ADCVU, WM8903_ADCVU);
+ regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_RIGHT,
+ WM8903_ADCVU, WM8903_ADCVU);
+
+ regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_LEFT,
+ WM8903_DACVU, WM8903_DACVU);
+ regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_RIGHT,
+ WM8903_DACVU, WM8903_DACVU);
+
+ regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_LEFT,
+ WM8903_HPOUTVU, WM8903_HPOUTVU);
+ regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_RIGHT,
+ WM8903_HPOUTVU, WM8903_HPOUTVU);
+
+ regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_LEFT,
+ WM8903_LINEOUTVU, WM8903_LINEOUTVU);
+ regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_RIGHT,
+ WM8903_LINEOUTVU, WM8903_LINEOUTVU);
+
+ regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_LEFT,
+ WM8903_SPKVU, WM8903_SPKVU);
+ regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_RIGHT,
+ WM8903_SPKVU, WM8903_SPKVU);
+
+ /* Enable DAC soft mute by default */
+ regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_1,
+ WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
+ WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8903, &wm8903_dai, 1);
if (ret != 0)
--
1.7.10
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/5] ASoC: wm8903: Convert to devm_regmap_init_i2c()
2012-06-09 3:09 [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Mark Brown
` (2 preceding siblings ...)
2012-06-09 3:09 ` [PATCH 4/5] ASoC: wm8903: Move register default changes " Mark Brown
@ 2012-06-09 3:09 ` Mark Brown
2012-06-11 17:26 ` [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Stephen Warren
4 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2012-06-09 3:09 UTC (permalink / raw)
To: Stephen Warren, Liam Girdwood; +Cc: alsa-devel, patches, Mark Brown
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 9410d54..676432d 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2236,7 +2236,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
wm8903->dev = &i2c->dev;
- wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap);
+ wm8903->regmap = devm_regmap_init_i2c(i2c, &wm8903_regmap);
if (IS_ERR(wm8903->regmap)) {
ret = PTR_ERR(wm8903->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2403,7 +2403,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
return 0;
err:
- regmap_exit(wm8903->regmap);
return ret;
}
@@ -2414,7 +2413,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
if (client->irq)
free_irq(client->irq, wm8903);
wm8903_free_gpio(wm8903);
- regmap_exit(wm8903->regmap);
snd_soc_unregister_codec(&client->dev);
return 0;
--
1.7.10
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function
2012-06-09 3:09 [PATCH 1/5] ASoC: wm8903: Move pin configuration into I2C probe() function Mark Brown
` (3 preceding siblings ...)
2012-06-09 3:09 ` [PATCH 5/5] ASoC: wm8903: Convert to devm_regmap_init_i2c() Mark Brown
@ 2012-06-11 17:26 ` Stephen Warren
2012-06-13 17:52 ` Mark Brown
4 siblings, 1 reply; 7+ messages in thread
From: Stephen Warren @ 2012-06-11 17:26 UTC (permalink / raw)
To: Mark Brown; +Cc: alsa-devel, patches, Liam Girdwood
On 06/08/2012 09:09 PM, Mark Brown wrote:
> Ensure that the device pins are configured as soon as possible by moving
> the pin configration (including MICBIAS) into the I2C probe() function.
> This had been done in the CODEC probe() function when we were relying on
> the ASoC register I/O code.
>
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
The series,
Tested-by: Stephen Warren <swarren@wwwdotorg.org>
(although I had a little trouble applying it; what was it based on?)
^ permalink raw reply [flat|nested] 7+ messages in thread