* [PATCH 0/11] extcon-arizona updates
@ 2013-01-10 12:02 Mark Brown
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
2013-01-11 1:58 ` [PATCH 0/11] extcon-arizona updates Chanwoo Choi
0 siblings, 2 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:02 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2044 bytes --]
The following changes since commit 9931faca02c604c22335f5a935a501bb2ace6e20:
Linux 3.8-rc3 (2013-01-09 18:59:55 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git tags/extcon-arizona-3.8rc3
for you to fetch changes up to 708f5b582ea16b60701e275fe5233ec4c57859cd:
mfd: wm5102: Add microphone clamp control registers (2013-01-10 11:35:42 +0000)
----------------------------------------------------------------
extcon: arizona: Updates to arizona extcon driver
This patch series adds a number of new features to the arizona driver:
- Headphone measurements.
- Alternative detection mechanism for non-default system designs.
- Microphone clamp integration.
- Support for additional detection pin.
- MICBIAS rise time configuration.
There's one trivial MFD patch which is here because it depends on
register definitions from the new features.
----------------------------------------------------------------
Mark Brown (11):
extcon: arizona: Convert to devm_input_allocate_device()
extcon: arizona: Remove duplicate mic ramp configuration
extcon: arizona: Only set GPIO if it has been requested
extcon: arizona: Allow configuration of MICBIAS rise time
extcon: arizona: Use microphone clamp function if available
extcon: arizona: Support use of GPIO5 as an input to jack detection
extcon: arizona: Enable basic headphone identification
extcon: arizona: Move start and stop mic functions earlier
extcon: arizona: Support HPDET based accessory identification
extcon: arizona: Support direct microphone measurement via HPDET
mfd: wm5102: Add microphone clamp control registers
drivers/extcon/extcon-arizona.c | 634 ++++++++++++++++++++++++++++++---
drivers/mfd/wm5102-tables.c | 10 +
include/linux/mfd/arizona/core.h | 4 +-
include/linux/mfd/arizona/pdata.h | 12 +
include/linux/mfd/arizona/registers.h | 48 +++
5 files changed, 658 insertions(+), 50 deletions(-)
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device()
2013-01-10 12:02 [PATCH 0/11] extcon-arizona updates Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 02/11] extcon: arizona: Remove duplicate mic ramp configuration Mark Brown
` (9 more replies)
2013-01-11 1:58 ` [PATCH 0/11] extcon-arizona updates Chanwoo Choi
1 sibling, 10 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 414aed5..4454d2d 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -418,7 +418,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
arizona_extcon_set_mode(info, 0);
- info->input = input_allocate_device();
+ info->input = devm_input_allocate_device(&pdev->dev);
if (!info->input) {
dev_err(arizona->dev, "Can't allocate input dev\n");
ret = -ENOMEM;
@@ -510,7 +510,6 @@ err_rise_wake:
err_rise:
arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info);
err_input:
- input_free_device(info->input);
err_register:
pm_runtime_disable(&pdev->dev);
extcon_dev_unregister(&info->edev);
@@ -533,7 +532,6 @@ static int arizona_extcon_remove(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
ARIZONA_JD1_ENA, 0);
arizona_clk32k_disable(arizona);
- input_unregister_device(info->input);
extcon_dev_unregister(&info->edev);
return 0;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/11] extcon: arizona: Remove duplicate mic ramp configuration
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 03/11] extcon: arizona: Only set GPIO if it has been requested Mark Brown
` (8 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Now this is configured by platform data remove the defualt configuration
the driver had.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 4454d2d..7dbefe8 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -473,9 +473,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
}
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
- ARIZONA_MICD_BIAS_STARTTIME_MASK |
ARIZONA_MICD_RATE_MASK,
- 7 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT |
8 << ARIZONA_MICD_RATE_SHIFT);
arizona_clk32k_enable(arizona);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/11] extcon: arizona: Only set GPIO if it has been requested
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
2013-01-10 12:04 ` [PATCH 02/11] extcon: arizona: Remove duplicate mic ramp configuration Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 04/11] extcon: arizona: Allow configuration of MICBIAS rise time Mark Brown
` (7 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
The micd_pol GPIO is only requested if we've specified one greater than 0
so apply the same test before we set it.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 7dbefe8..9e1d104 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -85,8 +85,9 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
{
struct arizona *arizona = info->arizona;
- gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
- info->micd_modes[mode].gpio);
+ if (arizona->pdata.micd_pol_gpio > 0)
+ gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
+ info->micd_modes[mode].gpio);
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
ARIZONA_MICD_BIAS_SRC_MASK,
info->micd_modes[mode].bias);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/11] extcon: arizona: Allow configuration of MICBIAS rise time
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
2013-01-10 12:04 ` [PATCH 02/11] extcon: arizona: Remove duplicate mic ramp configuration Mark Brown
2013-01-10 12:04 ` [PATCH 03/11] extcon: arizona: Only set GPIO if it has been requested Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 05/11] extcon: arizona: Use microphone clamp function if available Mark Brown
` (6 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Allow configuration of the rise time for MICBIAS via platform data, the
delay required depends on things like the external component selection.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>
---
drivers/extcon/extcon-arizona.c | 6 ++++++
include/linux/mfd/arizona/pdata.h | 3 +++
2 files changed, 9 insertions(+)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 9e1d104..635b707 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -417,6 +417,12 @@ static int arizona_extcon_probe(struct platform_device *pdev)
}
}
+ if (arizona->pdata.micd_bias_start_time)
+ regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
+ ARIZONA_MICD_BIAS_STARTTIME_MASK,
+ arizona->pdata.micd_bias_start_time
+ << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
+
arizona_extcon_set_mode(info, 0);
info->input = devm_input_allocate_device(&pdev->dev);
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 8b1d1da..5b05088 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -99,6 +99,9 @@ struct arizona_pdata {
/** GPIO for mic detection polarity */
int micd_pol_gpio;
+ /** Mic detect ramp rate */
+ int micd_bias_start_time;
+
/** Headset polarity configurations */
struct arizona_micd_config *micd_configs;
int num_micd_configs;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 05/11] extcon: arizona: Use microphone clamp function if available
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (2 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 04/11] extcon: arizona: Allow configuration of MICBIAS rise time Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 06/11] extcon: arizona: Support use of GPIO5 as an input to jack detection Mark Brown
` (5 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Newer Arizona devices include a microphone clamp function which is tied to
jack detect. Activate this feature when present in order to ensure best
performance of the subsystem.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 19 +++++++++++++++++++
include/linux/mfd/arizona/core.h | 4 +++-
include/linux/mfd/arizona/registers.h | 28 ++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 635b707..3ef3bee 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -45,6 +45,7 @@ struct arizona_extcon_info {
int micd_num_modes;
bool micd_reva;
+ bool micd_clamp;
bool mic;
bool detecting;
@@ -375,6 +376,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
info->micd_reva = true;
break;
default:
+ info->micd_clamp = true;
break;
}
break;
@@ -423,6 +425,19 @@ static int arizona_extcon_probe(struct platform_device *pdev)
arizona->pdata.micd_bias_start_time
<< ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
+ /*
+ * If we have a clamp use it.
+ */
+ if (info->micd_clamp) {
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_MICD_CLAMP_CONTROL,
+ ARIZONA_MICD_CLAMP_MODE_MASK, 4);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_JACK_DETECT_DEBOUNCE,
+ ARIZONA_MICD_CLAMP_DB,
+ ARIZONA_MICD_CLAMP_DB);
+ }
+
arizona_extcon_set_mode(info, 0);
info->input = devm_input_allocate_device(&pdev->dev);
@@ -529,6 +544,10 @@ static int arizona_extcon_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_MICD_CLAMP_CONTROL,
+ ARIZONA_MICD_CLAMP_MODE_MASK, 0);
+
arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0);
arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0);
arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index a580363..a710255 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -75,8 +75,10 @@ enum arizona_type {
#define ARIZONA_IRQ_DCS_HP_DONE 47
#define ARIZONA_IRQ_FLL2_CLOCK_OK 48
#define ARIZONA_IRQ_FLL1_CLOCK_OK 49
+#define ARIZONA_IRQ_MICD_CLAMP_RISE 50
+#define ARIZONA_IRQ_MICD_CLAMP_FALL 51
-#define ARIZONA_NUM_IRQ 50
+#define ARIZONA_NUM_IRQ 52
struct snd_soc_dapm_context;
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index 1f6fe31..f3211f0 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -119,6 +119,7 @@
#define ARIZONA_ACCESSORY_DETECT_MODE_1 0x293
#define ARIZONA_HEADPHONE_DETECT_1 0x29B
#define ARIZONA_HEADPHONE_DETECT_2 0x29C
+#define ARIZONA_MICD_CLAMP_CONTROL 0x2A2
#define ARIZONA_MIC_DETECT_1 0x2A3
#define ARIZONA_MIC_DETECT_2 0x2A4
#define ARIZONA_MIC_DETECT_3 0x2A5
@@ -2070,6 +2071,13 @@
#define ARIZONA_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
/*
+ * R674 (0x2A2) - MICD clamp control
+ */
+#define ARIZONA_MICD_CLAMP_MODE_MASK 0x000F /* MICD_CLAMP_MODE - [3:0] */
+#define ARIZONA_MICD_CLAMP_MODE_SHIFT 0 /* MICD_CLAMP_MODE - [3:0] */
+#define ARIZONA_MICD_CLAMP_MODE_WIDTH 4 /* MICD_CLAMP_MODE - [3:0] */
+
+/*
* R675 (0x2A3) - Mic Detect 1
*/
#define ARIZONA_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
@@ -5267,6 +5275,12 @@
/*
* R3409 (0xD51) - AOD IRQ1
*/
+#define ARIZONA_MICD_CLAMP_FALL_EINT1 0x0080 /* MICD_CLAMP_FALL_EINT1 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT1_MASK 0x0080 /* MICD_CLAMP_FALL_EINT1 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT1_SHIFT 7 /* MICD_CLAMP_FALL_EINT1 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT1 0x0040 /* MICD_CLAMP_RISE_EINT1 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT1_MASK 0x0040 /* MICD_CLAMP_RISE_EINT1 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT1_SHIFT 6 /* MICD_CLAMP_RISE_EINT1 */
#define ARIZONA_GP5_FALL_EINT1 0x0020 /* GP5_FALL_EINT1 */
#define ARIZONA_GP5_FALL_EINT1_MASK 0x0020 /* GP5_FALL_EINT1 */
#define ARIZONA_GP5_FALL_EINT1_SHIFT 5 /* GP5_FALL_EINT1 */
@@ -5295,6 +5309,12 @@
/*
* R3410 (0xD52) - AOD IRQ2
*/
+#define ARIZONA_MICD_CLAMP_FALL_EINT2 0x0080 /* MICD_CLAMP_FALL_EINT2 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT2_MASK 0x0080 /* MICD_CLAMP_FALL_EINT2 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT2_SHIFT 7 /* MICD_CLAMP_FALL_EINT2 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT2 0x0040 /* MICD_CLAMP_RISE_EINT2 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT2_MASK 0x0040 /* MICD_CLAMP_RISE_EINT2 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT2_SHIFT 6 /* MICD_CLAMP_RISE_EINT2 */
#define ARIZONA_GP5_FALL_EINT2 0x0020 /* GP5_FALL_EINT2 */
#define ARIZONA_GP5_FALL_EINT2_MASK 0x0020 /* GP5_FALL_EINT2 */
#define ARIZONA_GP5_FALL_EINT2_SHIFT 5 /* GP5_FALL_EINT2 */
@@ -5379,6 +5399,10 @@
/*
* R3413 (0xD55) - AOD IRQ Raw Status
*/
+#define ARIZONA_MICD_CLAMP_STS 0x0008 /* MICD_CLAMP_STS */
+#define ARIZONA_MICD_CLAMP_STS_MASK 0x0008 /* MICD_CLAMP_STS */
+#define ARIZONA_MICD_CLAMP_STS_SHIFT 3 /* MICD_CLAMP_STS */
+#define ARIZONA_MICD_CLAMP_STS_WIDTH 1 /* MICD_CLAMP_STS */
#define ARIZONA_GP5_STS 0x0004 /* GP5_STS */
#define ARIZONA_GP5_STS_MASK 0x0004 /* GP5_STS */
#define ARIZONA_GP5_STS_SHIFT 2 /* GP5_STS */
@@ -5395,6 +5419,10 @@
/*
* R3414 (0xD56) - Jack detect debounce
*/
+#define ARIZONA_MICD_CLAMP_DB 0x0008 /* MICD_CLAMP_DB */
+#define ARIZONA_MICD_CLAMP_DB_MASK 0x0008 /* MICD_CLAMP_DB */
+#define ARIZONA_MICD_CLAMP_DB_SHIFT 3 /* MICD_CLAMP_DB */
+#define ARIZONA_MICD_CLAMP_DB_WIDTH 1 /* MICD_CLAMP_DB */
#define ARIZONA_JD2_DB 0x0002 /* JD2_DB */
#define ARIZONA_JD2_DB_MASK 0x0002 /* JD2_DB */
#define ARIZONA_JD2_DB_SHIFT 1 /* JD2_DB */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 06/11] extcon: arizona: Support use of GPIO5 as an input to jack detection
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (3 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 05/11] extcon: arizona: Use microphone clamp function if available Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 07/11] extcon: arizona: Enable basic headphone identification Mark Brown
` (4 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Some system designs provide an input on GPIO5 which in conjunction with
the jack detection feature indicates the presence of an accessory.
Support such systems, using the microphone clamp feature to minimise
wakeups of the processor.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 76 ++++++++++++++++++++++++++++---------
include/linux/mfd/arizona/pdata.h | 3 ++
2 files changed, 61 insertions(+), 18 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 3ef3bee..b5190a8 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -290,13 +290,21 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
{
struct arizona_extcon_info *info = data;
struct arizona *arizona = info->arizona;
- unsigned int val;
+ unsigned int val, present, mask;
int ret, i;
pm_runtime_get_sync(info->dev);
mutex_lock(&info->lock);
+ if (arizona->pdata.jd_gpio5) {
+ mask = ARIZONA_MICD_CLAMP_STS;
+ present = 0;
+ } else {
+ mask = ARIZONA_JD1_STS;
+ present = ARIZONA_JD1_STS;
+ }
+
ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
if (ret != 0) {
dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
@@ -306,7 +314,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
return IRQ_NONE;
}
- if (val & ARIZONA_JD1_STS) {
+ if ((val & mask) == present) {
dev_dbg(arizona->dev, "Detected jack\n");
ret = extcon_set_cable_state_(&info->edev,
ARIZONA_CABLE_MECHANICAL, true);
@@ -321,6 +329,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
arizona_stop_mic(info);
+
for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
input_report_key(info->input,
arizona_lvl_to_key[i].report, 0);
@@ -345,6 +354,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
struct arizona_pdata *pdata;
struct arizona_extcon_info *info;
+ int jack_irq_fall, jack_irq_rise;
int ret, mode, i;
pdata = dev_get_platdata(arizona->dev);
@@ -426,12 +436,24 @@ static int arizona_extcon_probe(struct platform_device *pdev)
<< ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
/*
- * If we have a clamp use it.
+ * If we have a clamp use it, activating in conjunction with
+ * GPIO5 if that is connected for jack detect operation.
*/
if (info->micd_clamp) {
- regmap_update_bits(arizona->regmap,
- ARIZONA_MICD_CLAMP_CONTROL,
- ARIZONA_MICD_CLAMP_MODE_MASK, 4);
+ if (arizona->pdata.jd_gpio5) {
+ /* Put the GPIO into input mode */
+ regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
+ 0xc101);
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_MICD_CLAMP_CONTROL,
+ ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
+ } else {
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_MICD_CLAMP_CONTROL,
+ ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
+ }
+
regmap_update_bits(arizona->regmap,
ARIZONA_JACK_DETECT_DEBOUNCE,
ARIZONA_MICD_CLAMP_DB,
@@ -458,7 +480,15 @@ static int arizona_extcon_probe(struct platform_device *pdev)
pm_runtime_idle(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
- ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_RISE,
+ if (arizona->pdata.jd_gpio5) {
+ jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
+ jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
+ } else {
+ jack_irq_rise = ARIZONA_IRQ_JD_RISE;
+ jack_irq_fall = ARIZONA_IRQ_JD_FALL;
+ }
+
+ ret = arizona_request_irq(arizona, jack_irq_rise,
"JACKDET rise", arizona_jackdet, info);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
@@ -466,21 +496,21 @@ static int arizona_extcon_probe(struct platform_device *pdev)
goto err_input;
}
- ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1);
+ ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
ret);
goto err_rise;
}
- ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_FALL,
+ ret = arizona_request_irq(arizona, jack_irq_fall,
"JACKDET fall", arizona_jackdet, info);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
goto err_rise_wake;
}
- ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 1);
+ ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
ret);
@@ -522,13 +552,13 @@ static int arizona_extcon_probe(struct platform_device *pdev)
err_micdet:
arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
err_fall_wake:
- arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0);
+ arizona_set_irq_wake(arizona, jack_irq_fall, 0);
err_fall:
- arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info);
+ arizona_free_irq(arizona, jack_irq_fall, info);
err_rise_wake:
- arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0);
+ arizona_set_irq_wake(arizona, jack_irq_rise, 0);
err_rise:
- arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info);
+ arizona_free_irq(arizona, jack_irq_rise, info);
err_input:
err_register:
pm_runtime_disable(&pdev->dev);
@@ -541,6 +571,7 @@ static int arizona_extcon_remove(struct platform_device *pdev)
{
struct arizona_extcon_info *info = platform_get_drvdata(pdev);
struct arizona *arizona = info->arizona;
+ int jack_irq_rise, jack_irq_fall;
pm_runtime_disable(&pdev->dev);
@@ -548,11 +579,20 @@ static int arizona_extcon_remove(struct platform_device *pdev)
ARIZONA_MICD_CLAMP_CONTROL,
ARIZONA_MICD_CLAMP_MODE_MASK, 0);
- arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0);
- arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0);
+ if (arizona->pdata.jd_gpio5) {
+ jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
+ jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
+ } else {
+ jack_irq_rise = ARIZONA_IRQ_JD_RISE;
+ jack_irq_fall = ARIZONA_IRQ_JD_FALL;
+ }
+
+ arizona_set_irq_wake(arizona, jack_irq_rise, 0);
+ arizona_set_irq_wake(arizona, jack_irq_fall, 0);
+ arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
- arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info);
- arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info);
+ arizona_free_irq(arizona, jack_irq_rise, info);
+ arizona_free_irq(arizona, jack_irq_fall, info);
regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
ARIZONA_JD1_ENA, 0);
arizona_clk32k_disable(arizona);
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 5b05088..0fc26a48 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -96,6 +96,9 @@ struct arizona_pdata {
/** Pin state for GPIO pins */
int gpio_defaults[ARIZONA_MAX_GPIO];
+ /** GPIO5 is used for jack detection */
+ bool jd_gpio5;
+
/** GPIO for mic detection polarity */
int micd_pol_gpio;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/11] extcon: arizona: Enable basic headphone identification
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (4 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 06/11] extcon: arizona: Support use of GPIO5 as an input to jack detection Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 08/11] extcon: arizona: Move start and stop mic functions earlier Mark Brown
` (3 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Use the headphone detection to identify if the accessory is a headphone or
line load. There are two different revisions of the IP with different
register layouts, support both.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 341 +++++++++++++++++++++++++++++++--
drivers/mfd/wm5102-tables.c | 3 +
include/linux/mfd/arizona/registers.h | 12 ++
3 files changed, 335 insertions(+), 21 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index b5190a8..cc258a8 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -31,8 +31,14 @@
#include <linux/mfd/arizona/pdata.h>
#include <linux/mfd/arizona/registers.h>
+#define ARIZONA_DEFAULT_HP 32
+
#define ARIZONA_NUM_BUTTONS 6
+#define ARIZONA_ACCDET_MODE_MIC 0
+#define ARIZONA_ACCDET_MODE_HPL 1
+#define ARIZONA_ACCDET_MODE_HPR 2
+
struct arizona_extcon_info {
struct device *dev;
struct arizona *arizona;
@@ -47,10 +53,14 @@ struct arizona_extcon_info {
bool micd_reva;
bool micd_clamp;
+ bool hpdet_active;
+
bool mic;
bool detecting;
int jack_flips;
+ int hpdet_ip;
+
struct extcon_dev edev;
};
@@ -74,11 +84,13 @@ static struct {
#define ARIZONA_CABLE_MECHANICAL 0
#define ARIZONA_CABLE_MICROPHONE 1
#define ARIZONA_CABLE_HEADPHONE 2
+#define ARIZONA_CABLE_LINEOUT 3
static const char *arizona_cable[] = {
"Mechanical",
"Microphone",
"Headphone",
+ "Line-out",
NULL,
};
@@ -100,6 +112,290 @@ 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 struct {
+ unsigned int factor_a;
+ unsigned int factor_b;
+} arizona_hpdet_b_ranges[] = {
+ { 5528, 362464 },
+ { 11084, 6186851 },
+ { 11065, 65460395 },
+};
+
+static struct {
+ int min;
+ int max;
+} arizona_hpdet_c_ranges[] = {
+ { 0, 30 },
+ { 8, 100 },
+ { 100, 1000 },
+ { 1000, 10000 },
+};
+
+static int arizona_hpdet_read(struct arizona_extcon_info *info)
+{
+ struct arizona *arizona = info->arizona;
+ unsigned int val, range;
+ int ret;
+
+ ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
+ ret);
+ return ret;
+ }
+
+ switch (info->hpdet_ip) {
+ case 0:
+ if (!(val & ARIZONA_HP_DONE)) {
+ dev_err(arizona->dev, "HPDET did not complete: %x\n",
+ val);
+ val = ARIZONA_DEFAULT_HP;
+ }
+
+ val &= ARIZONA_HP_LVL_MASK;
+ break;
+
+ case 1:
+ if (!(val & ARIZONA_HP_DONE_B)) {
+ dev_err(arizona->dev, "HPDET did not complete: %x\n",
+ val);
+ return ARIZONA_DEFAULT_HP;
+ }
+
+ ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to read HP value: %d\n",
+ ret);
+ return ARIZONA_DEFAULT_HP;
+ }
+
+ regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
+ &range);
+ range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
+ >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
+
+ if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
+ (val < 100 || val > 0x3fb)) {
+ range++;
+ dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
+ range);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_IMPEDANCE_RANGE_MASK,
+ range <<
+ ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
+ return -EAGAIN;
+ }
+
+ /* If we go out of range report top of range */
+ if (val < 100 || val > 0x3fb) {
+ dev_dbg(arizona->dev, "Measurement out of range\n");
+ return 10000;
+ }
+
+ dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
+ val, range);
+
+ val = arizona_hpdet_b_ranges[range].factor_b
+ / ((val * 100) -
+ arizona_hpdet_b_ranges[range].factor_a);
+ break;
+
+ default:
+ dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
+ info->hpdet_ip);
+ case 2:
+ if (!(val & ARIZONA_HP_DONE_B)) {
+ dev_err(arizona->dev, "HPDET did not complete: %x\n",
+ val);
+ return ARIZONA_DEFAULT_HP;
+ }
+
+ val &= ARIZONA_HP_LVL_B_MASK;
+
+ regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
+ &range);
+ range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
+ >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
+
+ /* Skip up or down a range? */
+ if (range && (val < arizona_hpdet_c_ranges[range].min)) {
+ range--;
+ dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
+ arizona_hpdet_c_ranges[range].min,
+ arizona_hpdet_c_ranges[range].max);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_IMPEDANCE_RANGE_MASK,
+ range <<
+ ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
+ return -EAGAIN;
+ }
+
+ if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
+ (val >= arizona_hpdet_c_ranges[range].max)) {
+ range++;
+ dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
+ arizona_hpdet_c_ranges[range].min,
+ arizona_hpdet_c_ranges[range].max);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_IMPEDANCE_RANGE_MASK,
+ range <<
+ ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
+ return -EAGAIN;
+ }
+ }
+
+ dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
+ return val;
+}
+
+static irqreturn_t arizona_hpdet_irq(int irq, void *data)
+{
+ struct arizona_extcon_info *info = data;
+ struct arizona *arizona = info->arizona;
+ int report = ARIZONA_CABLE_HEADPHONE;
+ int ret;
+
+ mutex_lock(&info->lock);
+
+ /* If we got a spurious IRQ for some reason then ignore it */
+ if (!info->hpdet_active) {
+ dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
+ mutex_unlock(&info->lock);
+ return IRQ_NONE;
+ }
+
+ /* If the cable was removed while measuring ignore the result */
+ ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL);
+ if (ret < 0) {
+ dev_err(arizona->dev, "Failed to check cable state: %d\n",
+ ret);
+ goto out;
+ } else if (!ret) {
+ dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
+ goto done;
+ }
+
+ ret = arizona_hpdet_read(info);
+ if (ret == -EAGAIN) {
+ goto out;
+ } else if (ret < 0) {
+ goto done;
+ }
+
+ /* Reset back to starting range */
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_IMPEDANCE_RANGE_MASK, 0);
+
+ /* Report high impedence cables as line outputs */
+ if (ret >= 5000)
+ report = ARIZONA_CABLE_LINEOUT;
+ else
+ report = ARIZONA_CABLE_HEADPHONE;
+
+ ret = extcon_set_cable_state_(&info->edev, report, true);
+ if (ret != 0)
+ dev_err(arizona->dev, "Failed to report HP/line: %d\n",
+ ret);
+
+ ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0);
+ if (ret != 0)
+ dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret);
+
+ ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0);
+ if (ret != 0)
+ dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret);
+
+done:
+ regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_POLL, 0);
+
+ /* Revert back to MICDET mode */
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
+
+ /* If we have a mic then reenable MICDET */
+ if (info->mic)
+ arizona_start_mic(info);
+
+ if (info->hpdet_active) {
+ pm_runtime_put_autosuspend(info->dev);
+ info->hpdet_active = false;
+ }
+
+out:
+ mutex_unlock(&info->lock);
+
+ return IRQ_HANDLED;
+}
+
+static void arizona_identify_headphone(struct arizona_extcon_info *info)
+{
+ struct arizona *arizona = info->arizona;
+ int ret;
+
+ dev_dbg(arizona->dev, "Starting HPDET\n");
+
+ /* Make sure we keep the device enabled during the measurement */
+ pm_runtime_get(info->dev);
+
+ info->hpdet_active = true;
+
+ if (info->mic)
+ arizona_stop_mic(info);
+
+ ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000);
+ if (ret != 0)
+ dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
+
+ ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
+ if (ret != 0)
+ dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
+
+ ret = regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK,
+ ARIZONA_ACCDET_MODE_HPL);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
+ goto err;
+ }
+
+ ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_POLL, ARIZONA_HP_POLL);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
+ ret);
+ goto err;
+ }
+
+ return;
+
+err:
+ regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
+
+ /* Just report headphone */
+ ret = extcon_update_state(&info->edev,
+ 1 << ARIZONA_CABLE_HEADPHONE,
+ 1 << ARIZONA_CABLE_HEADPHONE);
+ if (ret != 0)
+ dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
+
+ if (info->mic)
+ arizona_start_mic(info);
+
+ info->hpdet_active = false;
+}
+ }
+
+ info->hpdet_active = false;
+}
+
static void arizona_start_mic(struct arizona_extcon_info *info)
{
struct arizona *arizona = info->arizona;
@@ -125,6 +421,10 @@ static void arizona_start_mic(struct arizona_extcon_info *info)
regmap_write(arizona->regmap, 0x80, 0x0);
}
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
+
regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
&change);
@@ -189,11 +489,11 @@ static irqreturn_t arizona_micdet(int irq, void *data)
/* If we got a high impedence we should have a headset, report it. */
if (info->detecting && (val & 0x400)) {
+ arizona_identify_headphone(info);
+
ret = extcon_update_state(&info->edev,
- 1 << ARIZONA_CABLE_MICROPHONE |
- 1 << ARIZONA_CABLE_HEADPHONE,
- 1 << ARIZONA_CABLE_MICROPHONE |
- 1 << ARIZONA_CABLE_HEADPHONE);
+ 1 << ARIZONA_CABLE_MICROPHONE,
+ 1 << ARIZONA_CABLE_MICROPHONE);
if (ret != 0)
dev_err(arizona->dev, "Headset report failed: %d\n",
@@ -214,17 +514,12 @@ static irqreturn_t arizona_micdet(int irq, void *data)
info->jack_flips++;
if (info->jack_flips >= info->micd_num_modes) {
- dev_dbg(arizona->dev, "Detected headphone\n");
+ dev_dbg(arizona->dev, "Detected HP/line\n");
+ arizona_identify_headphone(info);
+
info->detecting = false;
- arizona_stop_mic(info);
- ret = extcon_set_cable_state_(&info->edev,
- ARIZONA_CABLE_HEADPHONE,
- true);
- if (ret != 0)
- dev_err(arizona->dev,
- "Headphone report failed: %d\n",
- ret);
+ arizona_stop_mic(info);
} else {
info->micd_mode++;
if (info->micd_mode == info->micd_num_modes)
@@ -260,13 +555,7 @@ static irqreturn_t arizona_micdet(int irq, void *data)
info->detecting = false;
arizona_stop_mic(info);
- ret = extcon_set_cable_state_(&info->edev,
- ARIZONA_CABLE_HEADPHONE,
- true);
- if (ret != 0)
- dev_err(arizona->dev,
- "Headphone report failed: %d\n",
- ret);
+ arizona_identify_headphone(info);
} else {
dev_warn(arizona->dev, "Button with no mic: %x\n",
val);
@@ -387,6 +676,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
break;
default:
info->micd_clamp = true;
+ info->hpdet_ip = 1;
break;
}
break;
@@ -524,6 +814,13 @@ static int arizona_extcon_probe(struct platform_device *pdev)
goto err_fall_wake;
}
+ ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
+ "HPDET", arizona_hpdet_irq, info);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
+ goto err_micdet;
+ }
+
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
ARIZONA_MICD_RATE_MASK,
8 << ARIZONA_MICD_RATE_SHIFT);
@@ -544,11 +841,13 @@ static int arizona_extcon_probe(struct platform_device *pdev)
ret = input_register_device(info->input);
if (ret) {
dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
- goto err_micdet;
+ goto err_hpdet;
}
return 0;
+err_hpdet:
+ arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
err_micdet:
arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
err_fall_wake:
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 088872a..311cc36 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -1106,6 +1106,8 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_ACCESSORY_DETECT_MODE_1:
case ARIZONA_HEADPHONE_DETECT_1:
case ARIZONA_HEADPHONE_DETECT_2:
+ case ARIZONA_HP_DACVAL:
+ case ARIZONA_MICD_CLAMP_CONTROL:
case ARIZONA_MIC_DETECT_1:
case ARIZONA_MIC_DETECT_2:
case ARIZONA_MIC_DETECT_3:
@@ -1875,6 +1877,7 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_DSP1_STATUS_2:
case ARIZONA_DSP1_STATUS_3:
case ARIZONA_HEADPHONE_DETECT_2:
+ case ARIZONA_HP_DACVAL:
case ARIZONA_MIC_DETECT_3:
return true;
default:
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index f3211f0..e915053 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -119,6 +119,7 @@
#define ARIZONA_ACCESSORY_DETECT_MODE_1 0x293
#define ARIZONA_HEADPHONE_DETECT_1 0x29B
#define ARIZONA_HEADPHONE_DETECT_2 0x29C
+#define ARIZONA_HP_DACVAL 0x29F
#define ARIZONA_MICD_CLAMP_CONTROL 0x2A2
#define ARIZONA_MIC_DETECT_1 0x2A3
#define ARIZONA_MIC_DETECT_2 0x2A4
@@ -2036,6 +2037,9 @@
/*
* R667 (0x29B) - Headphone Detect 1
*/
+#define ARIZONA_HP_IMPEDANCE_RANGE_MASK 0x0600 /* HP_IMPEDANCE_RANGE - [10:9] */
+#define ARIZONA_HP_IMPEDANCE_RANGE_SHIFT 9 /* HP_IMPEDANCE_RANGE - [10:9] */
+#define ARIZONA_HP_IMPEDANCE_RANGE_WIDTH 2 /* HP_IMPEDANCE_RANGE - [10:9] */
#define ARIZONA_HP_STEP_SIZE 0x0100 /* HP_STEP_SIZE */
#define ARIZONA_HP_STEP_SIZE_MASK 0x0100 /* HP_STEP_SIZE */
#define ARIZONA_HP_STEP_SIZE_SHIFT 8 /* HP_STEP_SIZE */
@@ -2070,6 +2074,14 @@
#define ARIZONA_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
#define ARIZONA_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
+#define ARIZONA_HP_DONE_B 0x8000 /* HP_DONE */
+#define ARIZONA_HP_DONE_B_MASK 0x8000 /* HP_DONE */
+#define ARIZONA_HP_DONE_B_SHIFT 15 /* HP_DONE */
+#define ARIZONA_HP_DONE_B_WIDTH 1 /* HP_DONE */
+#define ARIZONA_HP_LVL_B_MASK 0x7FFF /* HP_LVL - [14:0] */
+#define ARIZONA_HP_LVL_B_SHIFT 0 /* HP_LVL - [14:0] */
+#define ARIZONA_HP_LVL_B_WIDTH 15 /* HP_LVL - [14:0] */
+
/*
* R674 (0x2A2) - MICD clamp control
*/
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/11] extcon: arizona: Move start and stop mic functions earlier
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (5 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 07/11] extcon: arizona: Enable basic headphone identification Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification Mark Brown
` (2 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Simple code motion supporting future work.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 120 +++++++++++++++++++--------------------
1 file changed, 60 insertions(+), 60 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index cc258a8..dab4584 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -112,6 +112,66 @@ 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_start_mic(struct arizona_extcon_info *info)
+{
+ struct arizona *arizona = info->arizona;
+ bool change;
+ int ret;
+
+ info->detecting = true;
+ info->mic = false;
+ info->jack_flips = 0;
+
+ /* Microphone detection can't use idle mode */
+ pm_runtime_get(info->dev);
+
+ ret = regulator_enable(info->micvdd);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
+ ret);
+ }
+
+ if (info->micd_reva) {
+ regmap_write(arizona->regmap, 0x80, 0x3);
+ regmap_write(arizona->regmap, 0x294, 0);
+ regmap_write(arizona->regmap, 0x80, 0x0);
+ }
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
+
+ regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
+ ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
+ &change);
+ if (!change) {
+ regulator_disable(info->micvdd);
+ pm_runtime_put_autosuspend(info->dev);
+ }
+}
+
+static void arizona_stop_mic(struct arizona_extcon_info *info)
+{
+ struct arizona *arizona = info->arizona;
+ bool change;
+
+ regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
+ ARIZONA_MICD_ENA, 0,
+ &change);
+
+ if (info->micd_reva) {
+ regmap_write(arizona->regmap, 0x80, 0x3);
+ regmap_write(arizona->regmap, 0x294, 2);
+ regmap_write(arizona->regmap, 0x80, 0x0);
+ }
+
+ if (change) {
+ regulator_disable(info->micvdd);
+ pm_runtime_mark_last_busy(info->dev);
+ pm_runtime_put_autosuspend(info->dev);
+ }
+}
+
static struct {
unsigned int factor_a;
unsigned int factor_b;
@@ -396,66 +456,6 @@ err:
info->hpdet_active = false;
}
-static void arizona_start_mic(struct arizona_extcon_info *info)
-{
- struct arizona *arizona = info->arizona;
- bool change;
- int ret;
-
- info->detecting = true;
- info->mic = false;
- info->jack_flips = 0;
-
- /* Microphone detection can't use idle mode */
- pm_runtime_get(info->dev);
-
- ret = regulator_enable(info->micvdd);
- if (ret != 0) {
- dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
- ret);
- }
-
- if (info->micd_reva) {
- regmap_write(arizona->regmap, 0x80, 0x3);
- regmap_write(arizona->regmap, 0x294, 0);
- regmap_write(arizona->regmap, 0x80, 0x0);
- }
-
- regmap_update_bits(arizona->regmap,
- ARIZONA_ACCESSORY_DETECT_MODE_1,
- ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
-
- regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
- ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
- &change);
- if (!change) {
- regulator_disable(info->micvdd);
- pm_runtime_put_autosuspend(info->dev);
- }
-}
-
-static void arizona_stop_mic(struct arizona_extcon_info *info)
-{
- struct arizona *arizona = info->arizona;
- bool change;
-
- regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
- ARIZONA_MICD_ENA, 0,
- &change);
-
- if (info->micd_reva) {
- regmap_write(arizona->regmap, 0x80, 0x3);
- regmap_write(arizona->regmap, 0x294, 2);
- regmap_write(arizona->regmap, 0x80, 0x0);
- }
-
- if (change) {
- regulator_disable(info->micvdd);
- pm_runtime_mark_last_busy(info->dev);
- pm_runtime_put_autosuspend(info->dev);
- }
-}
-
static irqreturn_t arizona_micdet(int irq, void *data)
{
struct arizona_extcon_info *info = data;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (6 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 08/11] extcon: arizona: Move start and stop mic functions earlier Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-11 2:00 ` Chanwoo Choi
2013-01-10 12:04 ` [PATCH 10/11] extcon: arizona: Support direct microphone measurement via HPDET Mark Brown
2013-01-10 12:04 ` [PATCH 11/11] mfd: wm5102: Add microphone clamp control registers Mark Brown
9 siblings, 1 reply; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
The accessory detection functionality in Arizona devices is flexible and
supports several system designs in addition to the default one implemented
by the existing driver. One such design uses the HPDET feature to determine
what kind of accessory is present by comparing measurements taken with the
two headphone grounds available on the device, implement that if selected
by platform data.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 159 ++++++++++++++++++++++++++++++++++---
include/linux/mfd/arizona/pdata.h | 3 +
2 files changed, 150 insertions(+), 12 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index dab4584..ba9525e 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -55,6 +55,9 @@ struct arizona_extcon_info {
bool hpdet_active;
+ int num_hpdet_res;
+ unsigned int hpdet_res[2];
+
bool mic;
bool detecting;
int jack_flips;
@@ -65,8 +68,8 @@ struct arizona_extcon_info {
};
static const struct arizona_micd_config micd_default_modes[] = {
- { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
{ 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
+ { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
};
static struct {
@@ -118,10 +121,6 @@ static void arizona_start_mic(struct arizona_extcon_info *info)
bool change;
int ret;
- info->detecting = true;
- info->mic = false;
- info->jack_flips = 0;
-
/* Microphone detection can't use idle mode */
pm_runtime_get(info->dev);
@@ -311,12 +310,80 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
return val;
}
+static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
+{
+ struct arizona *arizona = info->arizona;
+ int ret;
+
+ /*
+ * If we're using HPDET for accessory identification we need
+ * to take multiple measurements, step through them in sequence.
+ */
+ if (arizona->pdata.hpdet_acc_id) {
+ info->hpdet_res[info->num_hpdet_res++] = *reading;
+
+ /*
+ * If the impedence is too high don't measure the
+ * second ground.
+ */
+ if (info->num_hpdet_res == 1 && *reading >= 45) {
+ dev_dbg(arizona->dev, "Skipping ground flip\n");
+ info->hpdet_res[info->num_hpdet_res++] = *reading;
+ }
+
+ if (info->num_hpdet_res == 1) {
+ dev_dbg(arizona->dev, "Flipping ground\n");
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_SRC,
+ ~info->micd_modes[0].src);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_POLL, 0);
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_POLL, ARIZONA_HP_POLL);
+ return -EAGAIN;
+ }
+
+ /* OK, got both. Now, compare... */
+ dev_dbg(arizona->dev, "HPDET measured %d %d\n",
+ info->hpdet_res[0], info->hpdet_res[1]);
+
+ if (info->hpdet_res[0] > info->hpdet_res[1] * 2) {
+ dev_dbg(arizona->dev, "Detected mic\n");
+ info->mic = true;
+ ret = extcon_set_cable_state_(&info->edev,
+ ARIZONA_CABLE_MICROPHONE,
+ true);
+ if (ret != 0) {
+ dev_err(arizona->dev,
+ "Failed to report mic: %d\n", ret);
+ }
+
+ /* Take the headphone impedance for the main report */
+ *reading = info->hpdet_res[1];
+ } else {
+ dev_dbg(arizona->dev, "Detected headphone\n");
+ }
+
+ /* Make sure everything is reset back to the real polarity */
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_SRC,
+ info->micd_modes[0].src);
+ }
+
+ return 0;
+}
+
static irqreturn_t arizona_hpdet_irq(int irq, void *data)
{
struct arizona_extcon_info *info = data;
struct arizona *arizona = info->arizona;
int report = ARIZONA_CABLE_HEADPHONE;
- int ret;
+ int ret, reading;
mutex_lock(&info->lock);
@@ -344,14 +411,23 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
} else if (ret < 0) {
goto done;
}
+ reading = ret;
/* Reset back to starting range */
regmap_update_bits(arizona->regmap,
ARIZONA_HEADPHONE_DETECT_1,
- ARIZONA_HP_IMPEDANCE_RANGE_MASK, 0);
+ ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
+ 0);
+
+ ret = arizona_hpdet_do_id(info, &reading);
+ if (ret == -EAGAIN) {
+ goto out;
+ } else if (ret < 0) {
+ goto done;
+ }
/* Report high impedence cables as line outputs */
- if (ret >= 5000)
+ if (reading >= 5000)
report = ARIZONA_CABLE_LINEOUT;
else
report = ARIZONA_CABLE_HEADPHONE;
@@ -370,8 +446,6 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret);
done:
- regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
- ARIZONA_HP_POLL, 0);
/* Revert back to MICDET mode */
regmap_update_bits(arizona->regmap,
@@ -451,8 +525,58 @@ err:
info->hpdet_active = false;
}
+
+static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
+{
+ struct arizona *arizona = info->arizona;
+ int ret;
+
+ dev_dbg(arizona->dev, "Starting identification via HPDET\n");
+
+ /* Make sure we keep the device enabled during the measurement */
+ pm_runtime_get(info->dev);
+
+ info->hpdet_active = true;
+
+ ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000);
+ if (ret != 0)
+ dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
+
+ ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
+ if (ret != 0)
+ dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
+
+ ret = regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
+ info->micd_modes[0].src |
+ ARIZONA_ACCDET_MODE_HPL);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
+ goto err;
}
+ ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
+ ARIZONA_HP_POLL, ARIZONA_HP_POLL);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
+ ret);
+ goto err;
+ }
+
+ return;
+
+err:
+ regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
+
+ /* Just report headphone */
+ ret = extcon_update_state(&info->edev,
+ 1 << ARIZONA_CABLE_HEADPHONE,
+ 1 << ARIZONA_CABLE_HEADPHONE);
+ if (ret != 0)
+ dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
+
info->hpdet_active = false;
}
@@ -612,12 +736,24 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
dev_err(arizona->dev, "Mechanical report failed: %d\n",
ret);
- arizona_start_mic(info);
+ if (!arizona->pdata.hpdet_acc_id) {
+ info->detecting = true;
+ info->mic = false;
+ info->jack_flips = 0;
+
+ arizona_start_mic(info);
+ } else {
+ arizona_start_hpdet_acc_id(info);
+ }
} else {
dev_dbg(arizona->dev, "Detected jack removal\n");
arizona_stop_mic(info);
+ info->num_hpdet_res = 0;
+ for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
+ info->hpdet_res[i] = 0;
+ info->mic = false;
for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
input_report_key(info->input,
@@ -665,7 +801,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
mutex_init(&info->lock);
info->arizona = arizona;
info->dev = &pdev->dev;
- info->detecting = true;
platform_set_drvdata(pdev, info);
switch (arizona->type) {
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 0fc26a48..7c08787 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -99,6 +99,9 @@ struct arizona_pdata {
/** GPIO5 is used for jack detection */
bool jd_gpio5;
+ /** Use the headphone detect circuit to identify the accessory */
+ bool hpdet_acc_id;
+
/** GPIO for mic detection polarity */
int micd_pol_gpio;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 10/11] extcon: arizona: Support direct microphone measurement via HPDET
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (7 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
2013-01-10 12:04 ` [PATCH 11/11] mfd: wm5102: Add microphone clamp control registers Mark Brown
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
With some GPIO control it is possible to detect microphones in a wider
range of configurations by directly measuring the microphone impedance
when the HPDET method cannot distinguish between the behaviour of the
two grounds. Allow a GPIO to be provided in platform data and use it to
implement this behaviour.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/extcon/extcon-arizona.c | 50 +++++++++++++++++++++++++++++++++----
include/linux/mfd/arizona/pdata.h | 3 +++
2 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index ba9525e..de141f7 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -56,7 +56,7 @@ struct arizona_extcon_info {
bool hpdet_active;
int num_hpdet_res;
- unsigned int hpdet_res[2];
+ unsigned int hpdet_res[3];
bool mic;
bool detecting;
@@ -313,6 +313,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
{
struct arizona *arizona = info->arizona;
+ int id_gpio = arizona->pdata.hpdet_id_gpio;
int ret;
/*
@@ -338,9 +339,27 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
ARIZONA_ACCESSORY_DETECT_MODE_1,
ARIZONA_ACCDET_SRC,
~info->micd_modes[0].src);
+
regmap_update_bits(arizona->regmap,
ARIZONA_HEADPHONE_DETECT_1,
- ARIZONA_HP_POLL, 0);
+ ARIZONA_HP_POLL, ARIZONA_HP_POLL);
+ return -EAGAIN;
+ }
+
+ /* Only check the mic directly if we didn't already ID it */
+ if (id_gpio && info->num_hpdet_res == 2 &&
+ !((info->hpdet_res[0] > info->hpdet_res[1] * 2))) {
+ dev_dbg(arizona->dev, "Measuring mic\n");
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ACCESSORY_DETECT_MODE_1,
+ ARIZONA_ACCDET_MODE_MASK |
+ ARIZONA_ACCDET_SRC,
+ ARIZONA_ACCDET_MODE_HPR |
+ info->micd_modes[0].src);
+
+ gpio_set_value_cansleep(id_gpio, 1);
+
regmap_update_bits(arizona->regmap,
ARIZONA_HEADPHONE_DETECT_1,
ARIZONA_HP_POLL, ARIZONA_HP_POLL);
@@ -348,10 +367,16 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
}
/* OK, got both. Now, compare... */
- dev_dbg(arizona->dev, "HPDET measured %d %d\n",
- info->hpdet_res[0], info->hpdet_res[1]);
+ dev_dbg(arizona->dev, "HPDET measured %d %d %d\n",
+ info->hpdet_res[0], info->hpdet_res[1],
+ info->hpdet_res[2]);
- if (info->hpdet_res[0] > info->hpdet_res[1] * 2) {
+ /*
+ * Either the two grounds measure differently or we
+ * measure the mic as high impedance.
+ */
+ if ((info->hpdet_res[0] > info->hpdet_res[1] * 2) ||
+ (id_gpio && info->hpdet_res[2] > 10)) {
dev_dbg(arizona->dev, "Detected mic\n");
info->mic = true;
ret = extcon_set_cable_state_(&info->edev,
@@ -382,6 +407,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
{
struct arizona_extcon_info *info = data;
struct arizona *arizona = info->arizona;
+ int id_gpio = arizona->pdata.hpdet_id_gpio;
int report = ARIZONA_CABLE_HEADPHONE;
int ret, reading;
@@ -446,6 +472,8 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret);
done:
+ if (id_gpio)
+ gpio_set_value_cansleep(id_gpio, 0);
/* Revert back to MICDET mode */
regmap_update_bits(arizona->regmap,
@@ -854,6 +882,18 @@ static int arizona_extcon_probe(struct platform_device *pdev)
}
}
+ if (arizona->pdata.hpdet_id_gpio > 0) {
+ ret = devm_gpio_request_one(&pdev->dev,
+ arizona->pdata.hpdet_id_gpio,
+ GPIOF_OUT_INIT_LOW,
+ "HPDET");
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
+ arizona->pdata.hpdet_id_gpio, ret);
+ goto err_register;
+ }
+ }
+
if (arizona->pdata.micd_bias_start_time)
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
ARIZONA_MICD_BIAS_STARTTIME_MASK,
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 7c08787..bcbe4fd 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -102,6 +102,9 @@ struct arizona_pdata {
/** Use the headphone detect circuit to identify the accessory */
bool hpdet_acc_id;
+ /** GPIO used for mic isolation with HPDET */
+ int hpdet_id_gpio;
+
/** GPIO for mic detection polarity */
int micd_pol_gpio;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 11/11] mfd: wm5102: Add microphone clamp control registers
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
` (8 preceding siblings ...)
2013-01-10 12:04 ` [PATCH 10/11] extcon: arizona: Support direct microphone measurement via HPDET Mark Brown
@ 2013-01-10 12:04 ` Mark Brown
9 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-10 12:04 UTC (permalink / raw)
To: MyungJoo Ham, Chanwoo Choi, Greg Kroah-Hartman
Cc: Samuel Ortiz, patches, linux-kernel, Mark Brown
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/mfd/wm5102-tables.c | 7 +++++++
include/linux/mfd/arizona/registers.h | 8 ++++++++
2 files changed, 15 insertions(+)
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 311cc36..a396a3a 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -84,6 +84,12 @@ int wm5102_patch(struct arizona *arizona)
}
static const struct regmap_irq wm5102_aod_irqs[ARIZONA_NUM_IRQ] = {
+ [ARIZONA_IRQ_MICD_CLAMP_FALL] = {
+ .mask = ARIZONA_MICD_CLAMP_FALL_EINT1
+ },
+ [ARIZONA_IRQ_MICD_CLAMP_RISE] = {
+ .mask = ARIZONA_MICD_CLAMP_RISE_EINT1
+ },
[ARIZONA_IRQ_GP5_FALL] = { .mask = ARIZONA_GP5_FALL_EINT1 },
[ARIZONA_IRQ_GP5_RISE] = { .mask = ARIZONA_GP5_RISE_EINT1 },
[ARIZONA_IRQ_JD_FALL] = { .mask = ARIZONA_JD1_FALL_EINT1 },
@@ -312,6 +318,7 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */
{ 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */
{ 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */
+ { 0x000002A2, 0x0000 }, /* R674 - Micd clamp control */
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
{ 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index e915053..79e9dd4 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -1196,6 +1196,14 @@
/*
* R64 (0x40) - Wake control
*/
+#define ARIZONA_WKUP_MICD_CLAMP_FALL 0x0080 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_FALL_MASK 0x0080 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_FALL_SHIFT 7 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_FALL_WIDTH 1 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE 0x0040 /* WKUP_MICD_CLAMP_RISE */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE_MASK 0x0040 /* WKUP_MICD_CLAMP_RISE */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE_SHIFT 6 /* WKUP_MICD_CLAMP_RISE */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE_WIDTH 1 /* WKUP_MICD_CLAMP_RISE */
#define ARIZONA_WKUP_GP5_FALL 0x0020 /* WKUP_GP5_FALL */
#define ARIZONA_WKUP_GP5_FALL_MASK 0x0020 /* WKUP_GP5_FALL */
#define ARIZONA_WKUP_GP5_FALL_SHIFT 5 /* WKUP_GP5_FALL */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 0/11] extcon-arizona updates
2013-01-10 12:02 [PATCH 0/11] extcon-arizona updates Mark Brown
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
@ 2013-01-11 1:58 ` Chanwoo Choi
2013-01-14 7:59 ` Mark Brown
1 sibling, 1 reply; 20+ messages in thread
From: Chanwoo Choi @ 2013-01-11 1:58 UTC (permalink / raw)
To: Mark Brown
Cc: MyungJoo Ham, Greg Kroah-Hartman, Samuel Ortiz, patches,
linux-kernel
On 01/10/2013 09:02 PM, Mark Brown wrote:
> The following changes since commit 9931faca02c604c22335f5a935a501bb2ace6e20:
>
> Linux 3.8-rc3 (2013-01-09 18:59:55 -0800)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git tags/extcon-arizona-3.8rc3
>
> for you to fetch changes up to 708f5b582ea16b60701e275fe5233ec4c57859cd:
>
> mfd: wm5102: Add microphone clamp control registers (2013-01-10 11:35:42 +0000)
>
> ----------------------------------------------------------------
> extcon: arizona: Updates to arizona extcon driver
>
> This patch series adds a number of new features to the arizona driver:
>
> - Headphone measurements.
> - Alternative detection mechanism for non-default system designs.
> - Microphone clamp integration.
> - Support for additional detection pin.
> - MICBIAS rise time configuration.
>
> There's one trivial MFD patch which is here because it depends on
> register definitions from the new features.
>
> ----------------------------------------------------------------
> Mark Brown (11):
> extcon: arizona: Convert to devm_input_allocate_device()
> extcon: arizona: Remove duplicate mic ramp configuration
> extcon: arizona: Only set GPIO if it has been requested
> extcon: arizona: Allow configuration of MICBIAS rise time
> extcon: arizona: Use microphone clamp function if available
> extcon: arizona: Support use of GPIO5 as an input to jack detection
> extcon: arizona: Enable basic headphone identification
> extcon: arizona: Move start and stop mic functions earlier
> extcon: arizona: Support HPDET based accessory identification
> extcon: arizona: Support direct microphone measurement via HPDET
> mfd: wm5102: Add microphone clamp control registers
>
> drivers/extcon/extcon-arizona.c | 634 ++++++++++++++++++++++++++++++---
> drivers/mfd/wm5102-tables.c | 10 +
> include/linux/mfd/arizona/core.h | 4 +-
> include/linux/mfd/arizona/pdata.h | 12 +
> include/linux/mfd/arizona/registers.h | 48 +++
> 5 files changed, 658 insertions(+), 50 deletions(-)
Applied this patch set.
You can check this on extcon git repository:
http://git.kernel.org/?p=linux/kernel/git/chanwoo/extcon.git;a=shortlog;h=refs/heads/for-next
Thank you,
Chanwoo Choi
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification
2013-01-10 12:04 ` [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification Mark Brown
@ 2013-01-11 2:00 ` Chanwoo Choi
2013-01-11 11:53 ` Mark Brown
0 siblings, 1 reply; 20+ messages in thread
From: Chanwoo Choi @ 2013-01-11 2:00 UTC (permalink / raw)
To: Mark Brown
Cc: MyungJoo Ham, Greg Kroah-Hartman, Samuel Ortiz, patches,
linux-kernel
> + }
> +
> + /* OK, got both. Now, compare... */
Is is correct comment?
> + dev_dbg(arizona->dev, "HPDET measured %d %d\n",
> + info->hpdet_res[0], info->hpdet_res[1]);
> +
Thank you,
Chanwoo Choi
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification
2013-01-11 2:00 ` Chanwoo Choi
@ 2013-01-11 11:53 ` Mark Brown
0 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-11 11:53 UTC (permalink / raw)
To: Chanwoo Choi
Cc: MyungJoo Ham, Greg Kroah-Hartman, Samuel Ortiz, patches,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 244 bytes --]
On Fri, Jan 11, 2013 at 11:00:24AM +0900, Chanwoo Choi wrote:
> > + /* OK, got both. Now, compare... */
> Is is correct comment?
I think so but that doesn't mean I'm not mistaken or there's nothing
that could be improved - why do you ask?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/11] extcon-arizona updates
2013-01-11 1:58 ` [PATCH 0/11] extcon-arizona updates Chanwoo Choi
@ 2013-01-14 7:59 ` Mark Brown
2013-01-14 14:29 ` Greg Kroah-Hartman
0 siblings, 1 reply; 20+ messages in thread
From: Mark Brown @ 2013-01-14 7:59 UTC (permalink / raw)
To: Chanwoo Choi
Cc: MyungJoo Ham, Greg Kroah-Hartman, Samuel Ortiz, patches,
linux-kernel
On Fri, Jan 11, 2013 at 10:58:27AM +0900, Chanwoo Choi wrote:
> Applied this patch set.
> You can check this on extcon git repository:
> http://git.kernel.org/?p=linux/kernel/git/chanwoo/extcon.git;a=shortlog;h=refs/heads/for-next
Looks good. It does seem this tree isn't in -next, though - if this
tree ends up getting sent to Linus (via Greg I guess?) it'd make sense
to do that so we get integration testing for it as soon as possible.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/11] extcon-arizona updates
2013-01-14 7:59 ` Mark Brown
@ 2013-01-14 14:29 ` Greg Kroah-Hartman
2013-01-14 22:08 ` Chanwoo Choi
2013-01-14 22:41 ` Chanwoo Choi
0 siblings, 2 replies; 20+ messages in thread
From: Greg Kroah-Hartman @ 2013-01-14 14:29 UTC (permalink / raw)
To: Mark Brown
Cc: Chanwoo Choi, MyungJoo Ham, Samuel Ortiz, patches, linux-kernel
On Mon, Jan 14, 2013 at 04:59:25PM +0900, Mark Brown wrote:
> On Fri, Jan 11, 2013 at 10:58:27AM +0900, Chanwoo Choi wrote:
>
> > Applied this patch set.
>
> > You can check this on extcon git repository:
> > http://git.kernel.org/?p=linux/kernel/git/chanwoo/extcon.git;a=shortlog;h=refs/heads/for-next
>
> Looks good. It does seem this tree isn't in -next, though - if this
> tree ends up getting sent to Linus (via Greg I guess?) it'd make sense
> to do that so we get integration testing for it as soon as possible.
It would be good if Chanwoo sent me pull requests, I thought that was
going to happen but I have not seen any yet...
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/11] extcon-arizona updates
2013-01-14 14:29 ` Greg Kroah-Hartman
@ 2013-01-14 22:08 ` Chanwoo Choi
2013-01-15 2:07 ` Mark Brown
2013-01-14 22:41 ` Chanwoo Choi
1 sibling, 1 reply; 20+ messages in thread
From: Chanwoo Choi @ 2013-01-14 22:08 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Mark Brown, MyungJoo Ham, Samuel Ortiz, patches, linux-kernel
On 01/14/2013 11:29 PM, Greg Kroah-Hartman wrote:
> On Mon, Jan 14, 2013 at 04:59:25PM +0900, Mark Brown wrote:
>> On Fri, Jan 11, 2013 at 10:58:27AM +0900, Chanwoo Choi wrote:
>>
>>> Applied this patch set.
>>
>>> You can check this on extcon git repository:
>>> http://git.kernel.org/?p=linux/kernel/git/chanwoo/extcon.git;a=shortlog;h=refs/heads/for-next
>>
>> Looks good. It does seem this tree isn't in -next, though - if this
>> tree ends up getting sent to Linus (via Greg I guess?) it'd make sense
>> to do that so we get integration testing for it as soon as possible.
>
> It would be good if Chanwoo sent me pull requests, I thought that was
> going to happen but I have not seen any yet...
>
OK, I will send pull request to GregKH for extcon immediately.
Best Regards,
Chanwoo Choi
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/11] extcon-arizona updates
2013-01-14 14:29 ` Greg Kroah-Hartman
2013-01-14 22:08 ` Chanwoo Choi
@ 2013-01-14 22:41 ` Chanwoo Choi
1 sibling, 0 replies; 20+ messages in thread
From: Chanwoo Choi @ 2013-01-14 22:41 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Mark Brown, MyungJoo Ham, Samuel Ortiz, patches, linux-kernel,
cwchoi00
On 01/14/2013 11:29 PM, Greg Kroah-Hartman wrote:
> On Mon, Jan 14, 2013 at 04:59:25PM +0900, Mark Brown wrote:
>> On Fri, Jan 11, 2013 at 10:58:27AM +0900, Chanwoo Choi wrote:
>>
>>> Applied this patch set.
>>
>>> You can check this on extcon git repository:
>>> http://git.kernel.org/?p=linux/kernel/git/chanwoo/extcon.git;a=shortlog;h=refs/heads/for-next
>>
>> Looks good. It does seem this tree isn't in -next, though - if this
>> tree ends up getting sent to Linus (via Greg I guess?) it'd make sense
>> to do that so we get integration testing for it as soon as possible.
>
> It would be good if Chanwoo sent me pull requests, I thought that was
> going to happen but I have not seen any yet...
>
OK, I will send pull request to GregKH for extcon immediately.
Thank you,
Chanwoo Choi
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/11] extcon-arizona updates
2013-01-14 22:08 ` Chanwoo Choi
@ 2013-01-15 2:07 ` Mark Brown
0 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2013-01-15 2:07 UTC (permalink / raw)
To: Chanwoo Choi
Cc: Greg Kroah-Hartman, MyungJoo Ham, Samuel Ortiz, patches,
linux-kernel
On Tue, Jan 15, 2013 at 07:08:53AM +0900, Chanwoo Choi wrote:
> OK, I will send pull request to GregKH for extcon immediately.
Thanks. Like I say if you're doing this it's probably also worth asking
to get the tree in -next, the build coverage (especially from Fenguang's
awesome build farm!) and merge test coverage are both worth it.
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2013-01-15 2:07 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-10 12:02 [PATCH 0/11] extcon-arizona updates Mark Brown
2013-01-10 12:04 ` [PATCH 01/11] extcon: arizona: Convert to devm_input_allocate_device() Mark Brown
2013-01-10 12:04 ` [PATCH 02/11] extcon: arizona: Remove duplicate mic ramp configuration Mark Brown
2013-01-10 12:04 ` [PATCH 03/11] extcon: arizona: Only set GPIO if it has been requested Mark Brown
2013-01-10 12:04 ` [PATCH 04/11] extcon: arizona: Allow configuration of MICBIAS rise time Mark Brown
2013-01-10 12:04 ` [PATCH 05/11] extcon: arizona: Use microphone clamp function if available Mark Brown
2013-01-10 12:04 ` [PATCH 06/11] extcon: arizona: Support use of GPIO5 as an input to jack detection Mark Brown
2013-01-10 12:04 ` [PATCH 07/11] extcon: arizona: Enable basic headphone identification Mark Brown
2013-01-10 12:04 ` [PATCH 08/11] extcon: arizona: Move start and stop mic functions earlier Mark Brown
2013-01-10 12:04 ` [PATCH 09/11] extcon: arizona: Support HPDET based accessory identification Mark Brown
2013-01-11 2:00 ` Chanwoo Choi
2013-01-11 11:53 ` Mark Brown
2013-01-10 12:04 ` [PATCH 10/11] extcon: arizona: Support direct microphone measurement via HPDET Mark Brown
2013-01-10 12:04 ` [PATCH 11/11] mfd: wm5102: Add microphone clamp control registers Mark Brown
2013-01-11 1:58 ` [PATCH 0/11] extcon-arizona updates Chanwoo Choi
2013-01-14 7:59 ` Mark Brown
2013-01-14 14:29 ` Greg Kroah-Hartman
2013-01-14 22:08 ` Chanwoo Choi
2013-01-15 2:07 ` Mark Brown
2013-01-14 22:41 ` Chanwoo Choi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).