public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] extcon: arizona: Use regulated mode for microphone supply when detecting
@ 2013-01-25  9:16 Mark Brown
  2013-01-26  2:57 ` Chanwoo Choi
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Brown @ 2013-01-25  9:16 UTC (permalink / raw)
  To: MyungJoo Ham, Chanwoo Choi; +Cc: linux-kernel, patches, Mark Brown

When starting microphone detection some headsets should be exposed to
the fully regulated microphone bias in order to ensure that they behave
in an optimal fashion.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/extcon/Kconfig          |    2 +-
 drivers/extcon/extcon-arizona.c |   62 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index 07122a9..9377050 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -47,7 +47,7 @@ config EXTCON_MAX8997
 
 config EXTCON_ARIZONA
 	tristate "Wolfson Arizona EXTCON support"
-	depends on MFD_ARIZONA && INPUT
+	depends on MFD_ARIZONA && INPUT && SND_SOC
 	help
 	  Say Y here to enable support for external accessory detection
 	  with Wolfson Arizona devices. These are audio CODECs with
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index d7e1047..3aacacc 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -27,6 +27,8 @@
 #include <linux/regulator/consumer.h>
 #include <linux/extcon.h>
 
+#include <sound/soc.h>
+
 #include <linux/mfd/arizona/core.h>
 #include <linux/mfd/arizona/pdata.h>
 #include <linux/mfd/arizona/registers.h>
@@ -113,6 +115,40 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
 	dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
 }
 
+static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
+{
+	struct arizona *arizona = info->arizona;
+	const char *widget;
+	int ret;
+
+	if (arizona->dapm) {
+		switch (info->micd_modes[0].bias) {
+		case 1:
+			widget = "MICBIAS1";
+			break;
+		case 2:
+			widget = "MICBIAS2";
+			break;
+		case 3:
+			widget = "MICBIAS3";
+			break;
+		default:
+			widget = "MICVDD";
+			break;
+		}
+
+		ret = snd_soc_dapm_force_enable_pin(arizona->dapm, widget);
+		if (ret != 0)
+			dev_warn(arizona->dev, "Failed to enable %s: %d\n",
+				 widget, ret);
+
+		ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
+		if (ret != 0)
+			dev_warn(arizona->dev, "Failed to disable %s: %d\n",
+				 widget, ret);
+	}
+}
+
 static void arizona_start_mic(struct arizona_extcon_info *info)
 {
 	struct arizona *arizona = info->arizona;
@@ -122,6 +158,15 @@ static void arizona_start_mic(struct arizona_extcon_info *info)
 	/* Microphone detection can't use idle mode */
 	pm_runtime_get(info->dev);
 
+	if (info->detecting) {
+		ret = regulator_allow_bypass(info->micvdd, false);
+		if (ret != 0) {
+			dev_err(arizona->dev,
+				"Failed to regulate MICVDD: %d\n",
+				ret);
+		}
+	}
+
 	ret = regulator_enable(info->micvdd);
 	if (ret != 0) {
 		dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
@@ -151,6 +196,7 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
 {
 	struct arizona *arizona = info->arizona;
 	bool change;
+	int ret;
 
 	regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
 				 ARIZONA_MICD_ENA, 0,
@@ -162,6 +208,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
 		regmap_write(arizona->regmap, 0x80, 0x0);
 	}
 
+	ret = regulator_allow_bypass(info->micvdd, true);
+	if (ret != 0) {
+		dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
+			ret);
+	}
+
 	if (change) {
 		regulator_disable(info->micvdd);
 		pm_runtime_mark_last_busy(info->dev);
@@ -564,6 +616,8 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
 
 	info->hpdet_active = true;
 
+	arizona_extcon_pulse_micbias(info);
+
 	ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000);
 	if (ret != 0)
 		dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
@@ -649,6 +703,13 @@ static irqreturn_t arizona_micdet(int irq, void *data)
 			dev_err(arizona->dev, "Headset report failed: %d\n",
 				ret);
 
+		/* Don't need to regulate for button detection */
+		ret = regulator_allow_bypass(info->micvdd, false);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
+				ret);
+		}
+
 		info->mic = true;
 		info->detecting = false;
 		goto handled;
@@ -716,6 +777,7 @@ static irqreturn_t arizona_micdet(int irq, void *data)
 			input_report_key(info->input,
 					 arizona_lvl_to_key[i].report, 0);
 		input_sync(info->input);
+		arizona_extcon_pulse_micbias(info);
 	}
 
 handled:
-- 
1.7.10.4


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

* Re: [PATCH] extcon: arizona: Use regulated mode for microphone supply when detecting
  2013-01-25  9:16 [PATCH] extcon: arizona: Use regulated mode for microphone supply when detecting Mark Brown
@ 2013-01-26  2:57 ` Chanwoo Choi
  0 siblings, 0 replies; 2+ messages in thread
From: Chanwoo Choi @ 2013-01-26  2:57 UTC (permalink / raw)
  To: Mark Brown; +Cc: MyungJoo Ham, linux-kernel, patches

On 01/25/2013 06:16 PM, Mark Brown wrote:
> When starting microphone detection some headsets should be exposed to
> the fully regulated microphone bias in order to ensure that they behave
> in an optimal fashion.
>
> Signed-off-by: Mark Brown<broonie@opensource.wolfsonmicro.com>
> ---
>   drivers/extcon/Kconfig          |    2 +-
>   drivers/extcon/extcon-arizona.c |   62 +++++++++++++++++++++++++++++++++++++++
>   2 files changed, 63 insertions(+), 1 deletion(-)
Applied it.

Thanks,
Chanwoo Choi

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

end of thread, other threads:[~2013-01-26  2:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-25  9:16 [PATCH] extcon: arizona: Use regulated mode for microphone supply when detecting Mark Brown
2013-01-26  2:57 ` Chanwoo Choi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox