All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] ASoC: WM8903: init GPIOs during I2C probe not codec probe
@ 2012-05-22 22:08 Stephen Warren
       [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2012-05-23 11:20 ` [PATCH 1/5] ASoC: WM8903: init GPIOs during I2C probe not codec probe Mark Brown
  0 siblings, 2 replies; 6+ messages in thread
From: Stephen Warren @ 2012-05-22 22:08 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren

From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

This allows the GPIOs to be available as soon as the I2C device has
probed, which in turn enables machine drivers to request the GPIOs in
their probe(), rather than deferring this to their ASoC machine init
function, i.e. after the whole sound card has been constructed, and
hence the WM8903 codec is available.

Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 sound/soc/codecs/wm8903.c |   48 ++++++++++++++++++++------------------------
 1 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 86b8a29..f6a3fc5 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2,7 +2,7 @@
  * wm8903.c  --  WM8903 ALSA SoC Audio driver
  *
  * Copyright 2008 Wolfson Microelectronics
- * Copyright 2011 NVIDIA, Inc.
+ * Copyright 2011-2012 NVIDIA, Inc.
  *
  * Author: Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
  *
@@ -116,6 +116,7 @@ static const struct reg_default wm8903_reg_defaults[] = {
 
 struct wm8903_priv {
 	struct wm8903_platform_data *pdata;
+	struct device *dev;
 	struct snd_soc_codec *codec;
 	struct regmap *regmap;
 
@@ -1774,7 +1775,6 @@ static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
 static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
 {
 	struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
-	struct snd_soc_codec *codec = wm8903->codec;
 	unsigned int mask, val;
 	int ret;
 
@@ -1782,8 +1782,8 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
 	val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
 		WM8903_GP1_DIR;
 
-	ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
-				  mask, val);
+	ret = regmap_update_bits(wm8903->regmap,
+				 WM8903_GPIO_CONTROL_1 + offset, mask, val);
 	if (ret < 0)
 		return ret;
 
@@ -1793,10 +1793,9 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
 static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
 	struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
-	struct snd_soc_codec *codec = wm8903->codec;
-	int reg;
+	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset);
+	regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg);
 
 	return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
 }
@@ -1805,7 +1804,6 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
 				     unsigned offset, int value)
 {
 	struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
-	struct snd_soc_codec *codec = wm8903->codec;
 	unsigned int mask, val;
 	int ret;
 
@@ -1813,8 +1811,8 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
 	val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
 		(value << WM8903_GP2_LVL_SHIFT);
 
-	ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
-				  mask, val);
+	ret = regmap_update_bits(wm8903->regmap,
+				 WM8903_GPIO_CONTROL_1 + offset, mask, val);
 	if (ret < 0)
 		return ret;
 
@@ -1824,11 +1822,10 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
 static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
-	struct snd_soc_codec *codec = wm8903->codec;
 
-	snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
-			    WM8903_GP1_LVL_MASK,
-			    !!value << WM8903_GP1_LVL_SHIFT);
+	regmap_update_bits(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset,
+			   WM8903_GP1_LVL_MASK,
+			   !!value << WM8903_GP1_LVL_SHIFT);
 }
 
 static struct gpio_chip wm8903_template_chip = {
@@ -1842,15 +1839,14 @@ static struct gpio_chip wm8903_template_chip = {
 	.can_sleep		= 1,
 };
 
-static void wm8903_init_gpio(struct snd_soc_codec *codec)
+static void wm8903_init_gpio(struct wm8903_priv *wm8903)
 {
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
 	struct wm8903_platform_data *pdata = wm8903->pdata;
 	int ret;
 
 	wm8903->gpio_chip = wm8903_template_chip;
 	wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
-	wm8903->gpio_chip.dev = codec->dev;
+	wm8903->gpio_chip.dev = wm8903->dev;
 
 	if (pdata->gpio_base)
 		wm8903->gpio_chip.base = pdata->gpio_base;
@@ -1859,24 +1855,23 @@ static void wm8903_init_gpio(struct snd_soc_codec *codec)
 
 	ret = gpiochip_add(&wm8903->gpio_chip);
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+		dev_err(wm8903->dev, "Failed to add GPIOs: %d\n", ret);
 }
 
-static void wm8903_free_gpio(struct snd_soc_codec *codec)
+static void wm8903_free_gpio(struct wm8903_priv *wm8903)
 {
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
 	ret = gpiochip_remove(&wm8903->gpio_chip);
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+		dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret);
 }
 #else
-static void wm8903_init_gpio(struct snd_soc_codec *codec)
+static void wm8903_init_gpio(struct wm8903_priv *wm8903)
 {
 }
 
-static void wm8903_free_gpio(struct snd_soc_codec *codec)
+static void wm8903_free_gpio(struct wm8903_priv *wm8903)
 {
 }
 #endif
@@ -2000,8 +1995,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
 			    WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
 			    WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
 
-	wm8903_init_gpio(codec);
-
 	return ret;
 }
 
@@ -2010,7 +2003,6 @@ static int wm8903_remove(struct snd_soc_codec *codec)
 {
 	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
 
-	wm8903_free_gpio(codec);
 	wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
 	if (wm8903->irq)
 		free_irq(wm8903->irq, codec);
@@ -2130,6 +2122,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
 			      GFP_KERNEL);
 	if (wm8903 == NULL)
 		return -ENOMEM;
+	wm8903->dev = &i2c->dev;
 
 	wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap);
 	if (IS_ERR(wm8903->regmap)) {
@@ -2189,6 +2182,8 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
 	/* Reset the device */
 	regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903);
 
+	wm8903_init_gpio(wm8903);
+
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8903, &wm8903_dai, 1);
 	if (ret != 0)
@@ -2204,6 +2199,7 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
 {
 	struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
 
+	wm8903_free_gpio(wm8903);
 	regmap_exit(wm8903->regmap);
 	snd_soc_unregister_codec(&client->dev);
 
-- 
1.7.0.4

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

* [PATCH 2/5] ASoC: tegra+wm8903: simplify gpio tests in widget callbacks
       [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-05-22 22:08   ` Stephen Warren
  2012-05-22 22:08   ` [PATCH 3/5] ASoC: tegra+wm8903: move all GPIO setup into probe Stephen Warren
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Stephen Warren @ 2012-05-22 22:08 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren

From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

By the time any widget callbacks could be called, if the GPIO ID they
will manipulate is valid, it must have already been requested, or the
card would have failed to probe or initialize. So, testing for GPIO
validity is equivalent to testing whether the GPIO was successfully
requested at this point in the code. Making this change will allow later
patches to remove the gpio_requested variable.

Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 sound/soc/tegra/tegra_wm8903.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 0b0df49..f33fe7c 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -160,7 +160,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
 	struct tegra_wm8903_platform_data *pdata = &machine->pdata;
 
-	if (!(machine->gpio_requested & GPIO_SPKR_EN))
+	if (!gpio_is_valid(pdata->gpio_spkr_en))
 		return 0;
 
 	gpio_set_value_cansleep(pdata->gpio_spkr_en,
@@ -177,7 +177,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
 	struct tegra_wm8903_platform_data *pdata = &machine->pdata;
 
-	if (!(machine->gpio_requested & GPIO_HP_MUTE))
+	if (!gpio_is_valid(pdata->gpio_hp_mute))
 		return 0;
 
 	gpio_set_value_cansleep(pdata->gpio_hp_mute,
-- 
1.7.0.4

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

* [PATCH 3/5] ASoC: tegra+wm8903: move all GPIO setup into probe
       [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2012-05-22 22:08   ` [PATCH 2/5] ASoC: tegra+wm8903: simplify gpio tests in widget callbacks Stephen Warren
@ 2012-05-22 22:08   ` Stephen Warren
  2012-05-22 22:08   ` [PATCH 4/5] ASoC: tegra+wm8903: Use devm_gpio_request_one Stephen Warren
  2012-05-22 22:08   ` [PATCH 5/5] ASoC: tegra+wm8903: unconditionally free jack GPIOs in remove Stephen Warren
  3 siblings, 0 replies; 6+ messages in thread
From: Stephen Warren @ 2012-05-22 22:08 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren

From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Now that deferred probe exists, we can parse device tree and request
GPIOs from probe(), rather than deferring this to the DAI link's init().

Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 sound/soc/tegra/tegra_wm8903.c |  162 ++++++++++++++++++++-------------------
 1 files changed, 83 insertions(+), 79 deletions(-)

diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index f33fe7c..c38f09e 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -245,80 +245,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 	struct snd_soc_card *card = codec->card;
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
 	struct tegra_wm8903_platform_data *pdata = &machine->pdata;
-	struct device_node *np = card->dev->of_node;
-	int ret;
-
-	if (card->dev->platform_data) {
-		memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
-	} else if (np) {
-		/*
-		 * This part must be in init() rather than probe() in order to
-		 * guarantee that the WM8903 has been probed, and hence its
-		 * GPIO controller registered, which is a pre-condition for
-		 * of_get_named_gpio() to be able to map the phandles in the
-		 * properties to the controller node. Given this, all
-		 * pdata handling is in init() for consistency.
-		 */
-		pdata->gpio_spkr_en = of_get_named_gpio(np,
-						"nvidia,spkr-en-gpios", 0);
-		pdata->gpio_hp_mute = of_get_named_gpio(np,
-						"nvidia,hp-mute-gpios", 0);
-		pdata->gpio_hp_det = of_get_named_gpio(np,
-						"nvidia,hp-det-gpios", 0);
-		pdata->gpio_int_mic_en = of_get_named_gpio(np,
-						"nvidia,int-mic-en-gpios", 0);
-		pdata->gpio_ext_mic_en = of_get_named_gpio(np,
-						"nvidia,ext-mic-en-gpios", 0);
-	} else {
-		dev_err(card->dev, "No platform data supplied\n");
-		return -EINVAL;
-	}
-
-	if (gpio_is_valid(pdata->gpio_spkr_en)) {
-		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
-		if (ret) {
-			dev_err(card->dev, "cannot get spkr_en gpio\n");
-			return ret;
-		}
-		machine->gpio_requested |= GPIO_SPKR_EN;
-
-		gpio_direction_output(pdata->gpio_spkr_en, 0);
-	}
-
-	if (gpio_is_valid(pdata->gpio_hp_mute)) {
-		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
-		if (ret) {
-			dev_err(card->dev, "cannot get hp_mute gpio\n");
-			return ret;
-		}
-		machine->gpio_requested |= GPIO_HP_MUTE;
-
-		gpio_direction_output(pdata->gpio_hp_mute, 1);
-	}
-
-	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
-		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
-		if (ret) {
-			dev_err(card->dev, "cannot get int_mic_en gpio\n");
-			return ret;
-		}
-		machine->gpio_requested |= GPIO_INT_MIC_EN;
-
-		/* Disable int mic; enable signal is active-high */
-		gpio_direction_output(pdata->gpio_int_mic_en, 0);
-	}
-
-	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
-		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
-		if (ret) {
-			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
-			return ret;
-		}
-		machine->gpio_requested |= GPIO_EXT_MIC_EN;
-
-		/* Enable ext mic; enable signal is active-low */
-		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
-	}
 
 	if (gpio_is_valid(pdata->gpio_hp_det)) {
 		tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
@@ -372,8 +298,10 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = {
 
 static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct snd_soc_card *card = &snd_soc_tegra_wm8903;
 	struct tegra_wm8903 *machine;
+	struct tegra_wm8903_platform_data *pdata;
 	int ret;
 
 	if (!pdev->dev.platform_data && !pdev->dev.of_node) {
@@ -388,12 +316,42 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 		ret = -ENOMEM;
 		goto err;
 	}
+	pdata = &machine->pdata;
 
 	card->dev = &pdev->dev;
 	platform_set_drvdata(pdev, card);
 	snd_soc_card_set_drvdata(card, machine);
 
-	if (pdev->dev.of_node) {
+	if (pdev->dev.platform_data) {
+		memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
+	} else if (np) {
+		pdata->gpio_spkr_en = of_get_named_gpio(np,
+						"nvidia,spkr-en-gpios", 0);
+		if (pdata->gpio_spkr_en == -ENODEV)
+			return -EPROBE_DEFER;
+
+		pdata->gpio_hp_mute = of_get_named_gpio(np,
+						"nvidia,hp-mute-gpios", 0);
+		if (pdata->gpio_hp_mute == -ENODEV)
+			return -EPROBE_DEFER;
+
+		pdata->gpio_hp_det = of_get_named_gpio(np,
+						"nvidia,hp-det-gpios", 0);
+		if (pdata->gpio_hp_det == -ENODEV)
+			return -EPROBE_DEFER;
+
+		pdata->gpio_int_mic_en = of_get_named_gpio(np,
+						"nvidia,int-mic-en-gpios", 0);
+		if (pdata->gpio_int_mic_en == -ENODEV)
+			return -EPROBE_DEFER;
+
+		pdata->gpio_ext_mic_en = of_get_named_gpio(np,
+						"nvidia,ext-mic-en-gpios", 0);
+		if (pdata->gpio_ext_mic_en == -ENODEV)
+			return -EPROBE_DEFER;
+	}
+
+	if (np) {
 		ret = snd_soc_of_parse_card_name(card, "nvidia,model");
 		if (ret)
 			goto err;
@@ -404,8 +362,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 			goto err;
 
 		tegra_wm8903_dai.codec_name = NULL;
-		tegra_wm8903_dai.codec_of_node = of_parse_phandle(
-				pdev->dev.of_node, "nvidia,audio-codec", 0);
+		tegra_wm8903_dai.codec_of_node = of_parse_phandle(np,
+				"nvidia,audio-codec", 0);
 		if (!tegra_wm8903_dai.codec_of_node) {
 			dev_err(&pdev->dev,
 				"Property 'nvidia,audio-codec' missing or invalid\n");
@@ -414,8 +372,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 		}
 
 		tegra_wm8903_dai.cpu_dai_name = NULL;
-		tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(
-				pdev->dev.of_node, "nvidia,i2s-controller", 0);
+		tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(np,
+				"nvidia,i2s-controller", 0);
 		if (!tegra_wm8903_dai.cpu_dai_of_node) {
 			dev_err(&pdev->dev,
 				"Property 'nvidia,i2s-controller' missing or invalid\n");
@@ -442,6 +400,52 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (gpio_is_valid(pdata->gpio_spkr_en)) {
+		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
+		if (ret) {
+			dev_err(card->dev, "cannot get spkr_en gpio\n");
+			return ret;
+		}
+		machine->gpio_requested |= GPIO_SPKR_EN;
+
+		gpio_direction_output(pdata->gpio_spkr_en, 0);
+	}
+
+	if (gpio_is_valid(pdata->gpio_hp_mute)) {
+		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
+		if (ret) {
+			dev_err(card->dev, "cannot get hp_mute gpio\n");
+			return ret;
+		}
+		machine->gpio_requested |= GPIO_HP_MUTE;
+
+		gpio_direction_output(pdata->gpio_hp_mute, 1);
+	}
+
+	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
+		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
+		if (ret) {
+			dev_err(card->dev, "cannot get int_mic_en gpio\n");
+			return ret;
+		}
+		machine->gpio_requested |= GPIO_INT_MIC_EN;
+
+		/* Disable int mic; enable signal is active-high */
+		gpio_direction_output(pdata->gpio_int_mic_en, 0);
+	}
+
+	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
+		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
+		if (ret) {
+			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
+			return ret;
+		}
+		machine->gpio_requested |= GPIO_EXT_MIC_EN;
+
+		/* Enable ext mic; enable signal is active-low */
+		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
+	}
+
 	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
 	if (ret)
 		goto err;
-- 
1.7.0.4

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

* [PATCH 4/5] ASoC: tegra+wm8903: Use devm_gpio_request_one
       [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2012-05-22 22:08   ` [PATCH 2/5] ASoC: tegra+wm8903: simplify gpio tests in widget callbacks Stephen Warren
  2012-05-22 22:08   ` [PATCH 3/5] ASoC: tegra+wm8903: move all GPIO setup into probe Stephen Warren
@ 2012-05-22 22:08   ` Stephen Warren
  2012-05-22 22:08   ` [PATCH 5/5] ASoC: tegra+wm8903: unconditionally free jack GPIOs in remove Stephen Warren
  3 siblings, 0 replies; 6+ messages in thread
From: Stephen Warren @ 2012-05-22 22:08 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren

From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

By using this function, the driver no longer needs to explicitly free
the GPIOs. Hence, we can also remove the flags we use to track whether
we allocated these GPIOs.

Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 sound/soc/tegra/tegra_wm8903.c |   42 +++++++++------------------------------
 1 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index c38f09e..d78556a 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -50,10 +50,6 @@
 
 #define DRV_NAME "tegra-snd-wm8903"
 
-#define GPIO_SPKR_EN    BIT(0)
-#define GPIO_HP_MUTE    BIT(1)
-#define GPIO_INT_MIC_EN BIT(2)
-#define GPIO_EXT_MIC_EN BIT(3)
 #define GPIO_HP_DET     BIT(4)
 
 struct tegra_wm8903 {
@@ -401,49 +397,41 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 	}
 
 	if (gpio_is_valid(pdata->gpio_spkr_en)) {
-		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
+		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en,
+					    GPIOF_OUT_INIT_LOW, "spkr_en");
 		if (ret) {
 			dev_err(card->dev, "cannot get spkr_en gpio\n");
 			return ret;
 		}
-		machine->gpio_requested |= GPIO_SPKR_EN;
-
-		gpio_direction_output(pdata->gpio_spkr_en, 0);
 	}
 
 	if (gpio_is_valid(pdata->gpio_hp_mute)) {
-		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
+		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute,
+					    GPIOF_OUT_INIT_HIGH, "hp_mute");
 		if (ret) {
 			dev_err(card->dev, "cannot get hp_mute gpio\n");
 			return ret;
 		}
-		machine->gpio_requested |= GPIO_HP_MUTE;
-
-		gpio_direction_output(pdata->gpio_hp_mute, 1);
 	}
 
 	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
-		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
+		/* Disable int mic; enable signal is active-high */
+		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en,
+					    GPIOF_OUT_INIT_LOW, "int_mic_en");
 		if (ret) {
 			dev_err(card->dev, "cannot get int_mic_en gpio\n");
 			return ret;
 		}
-		machine->gpio_requested |= GPIO_INT_MIC_EN;
-
-		/* Disable int mic; enable signal is active-high */
-		gpio_direction_output(pdata->gpio_int_mic_en, 0);
 	}
 
 	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
-		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
+		/* Enable ext mic; enable signal is active-low */
+		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en,
+					    GPIOF_OUT_INIT_LOW, "ext_mic_en");
 		if (ret) {
 			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
 			return ret;
 		}
-		machine->gpio_requested |= GPIO_EXT_MIC_EN;
-
-		/* Enable ext mic; enable signal is active-low */
-		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
 	}
 
 	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
@@ -469,21 +457,11 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
-	struct tegra_wm8903_platform_data *pdata = &machine->pdata;
 
 	if (machine->gpio_requested & GPIO_HP_DET)
 		snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack,
 					1,
 					&tegra_wm8903_hp_jack_gpio);
-	if (machine->gpio_requested & GPIO_EXT_MIC_EN)
-		gpio_free(pdata->gpio_ext_mic_en);
-	if (machine->gpio_requested & GPIO_INT_MIC_EN)
-		gpio_free(pdata->gpio_int_mic_en);
-	if (machine->gpio_requested & GPIO_HP_MUTE)
-		gpio_free(pdata->gpio_hp_mute);
-	if (machine->gpio_requested & GPIO_SPKR_EN)
-		gpio_free(pdata->gpio_spkr_en);
-	machine->gpio_requested = 0;
 
 	snd_soc_unregister_card(card);
 
-- 
1.7.0.4

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

* [PATCH 5/5] ASoC: tegra+wm8903: unconditionally free jack GPIOs in remove
       [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
                     ` (2 preceding siblings ...)
  2012-05-22 22:08   ` [PATCH 4/5] ASoC: tegra+wm8903: Use devm_gpio_request_one Stephen Warren
@ 2012-05-22 22:08   ` Stephen Warren
  3 siblings, 0 replies; 6+ messages in thread
From: Stephen Warren @ 2012-05-22 22:08 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren

From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

The headphone jack GPIOs are added/initialized in the DAI link's init()
method, and hence in theory may not always have been added before remove()
is called in some unusual cases. In order to prevent calling
snd_soc_jack_free_gpios() if snd_soc_jack_add_gpios() had not been, the
code kept track of the initialization state to avoid the free call when
necessary.

However, it appears that snd_soc_jack_free_gpios() is robust in the face
of being called without snd_soc_jack_add_gpios() first succeeding, so
there is little point manually tracking this information. Hence, remove
the tracking code. Almost all other machine drivers already operate this
way.

Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 sound/soc/tegra/tegra_wm8903.c |   10 ++--------
 1 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index d78556a..1fd6a41 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -50,12 +50,9 @@
 
 #define DRV_NAME "tegra-snd-wm8903"
 
-#define GPIO_HP_DET     BIT(4)
-
 struct tegra_wm8903 {
 	struct tegra_wm8903_platform_data pdata;
 	struct tegra_asoc_utils_data util_data;
-	int gpio_requested;
 };
 
 static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
@@ -252,7 +249,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 		snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
 					1,
 					&tegra_wm8903_hp_jack_gpio);
-		machine->gpio_requested |= GPIO_HP_DET;
 	}
 
 	snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
@@ -458,10 +454,8 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
 
-	if (machine->gpio_requested & GPIO_HP_DET)
-		snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack,
-					1,
-					&tegra_wm8903_hp_jack_gpio);
+	snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1,
+				&tegra_wm8903_hp_jack_gpio);
 
 	snd_soc_unregister_card(card);
 
-- 
1.7.0.4

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

* Re: [PATCH 1/5] ASoC: WM8903: init GPIOs during I2C probe not codec probe
  2012-05-22 22:08 [PATCH 1/5] ASoC: WM8903: init GPIOs during I2C probe not codec probe Stephen Warren
       [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-05-23 11:20 ` Mark Brown
  1 sibling, 0 replies; 6+ messages in thread
From: Mark Brown @ 2012-05-23 11:20 UTC (permalink / raw)
  To: Stephen Warren; +Cc: linux-tegra, alsa-devel, Stephen Warren, Liam Girdwood


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

On Tue, May 22, 2012 at 04:08:52PM -0600, Stephen Warren wrote:

> This allows the GPIOs to be available as soon as the I2C device has

Applied all, thanks.

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

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



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

end of thread, other threads:[~2012-05-23 11:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-22 22:08 [PATCH 1/5] ASoC: WM8903: init GPIOs during I2C probe not codec probe Stephen Warren
     [not found] ` <1337724536-12349-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-05-22 22:08   ` [PATCH 2/5] ASoC: tegra+wm8903: simplify gpio tests in widget callbacks Stephen Warren
2012-05-22 22:08   ` [PATCH 3/5] ASoC: tegra+wm8903: move all GPIO setup into probe Stephen Warren
2012-05-22 22:08   ` [PATCH 4/5] ASoC: tegra+wm8903: Use devm_gpio_request_one Stephen Warren
2012-05-22 22:08   ` [PATCH 5/5] ASoC: tegra+wm8903: unconditionally free jack GPIOs in remove Stephen Warren
2012-05-23 11:20 ` [PATCH 1/5] ASoC: WM8903: init GPIOs during I2C probe not codec probe 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.