diff options
author | Kristoffer KARLSSON <kristoffer.karlsson@stericsson.com> | 2011-12-16 14:55:33 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:03:38 +0200 |
commit | 22f6fcb4ace2e99058078a8d5e2c1db3a29eac4d (patch) | |
tree | 94774cfd537fc052dada39132a6b36c395fc7048 | |
parent | b0fe67b7a7cd0645c43bbca20ea31c8db049db8f (diff) |
input: ab8500-accdet: Add unsupported hs detection
This patch adds support for detection of
headsets with gnd and mic pins switched.
ST-Ericsson Linux next: NA
ST-Ericsson ID: 361921
ST-Ericsson FOSS-OUT ID: Trivial
Depends-On: I01171aa4ce57a25237986cdf2f0ca4e01660fb28
Change-Id: I1e20586940121f4d7da5b3e8b6e132527303076d
Signed-off-by: Kristoffer KARLSSON <kristoffer.karlsson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42939
Reviewed-by: QATOOLS
Reviewed-by: QABUILD
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/include/mach/abx500-accdet.h | 8 | ||||
-rw-r--r-- | drivers/input/misc/ab5500-accdet.c | 9 | ||||
-rw-r--r-- | drivers/input/misc/ab8500-accdet.c | 46 | ||||
-rw-r--r-- | drivers/input/misc/abx500-accdet.c | 81 |
4 files changed, 133 insertions, 11 deletions
diff --git a/arch/arm/mach-ux500/include/mach/abx500-accdet.h b/arch/arm/mach-ux500/include/mach/abx500-accdet.h index 04082b824ae..cdd78cd7d0c 100644 --- a/arch/arm/mach-ux500/include/mach/abx500-accdet.h +++ b/arch/arm/mach-ux500/include/mach/abx500-accdet.h @@ -119,6 +119,7 @@ struct abx500_accdet_platform_data { * detect the actual type. In this mode, possible button events are reported. * @JACK_TYPE_HEADPHONE Headphone type of accessory (spkrs only) connected * @JACK_TYPE_HEADSET Headset type of accessory (mic+spkrs) connected + * @JACK_TYPE_UNSUPPORTED_HEADSET Unsupported headset of type accessory connected * @JACK_TYPE_CARKIT Carkit type of accessory connected * @JACK_TYPE_OPENCABLE Open cable connected * @JACK_TYPE_CVIDEO CVideo type of accessory connected. @@ -129,6 +130,7 @@ enum accessory_jack_type { JACK_TYPE_CONNECTED, JACK_TYPE_HEADPHONE, JACK_TYPE_HEADSET, + JACK_TYPE_UNSUPPORTED_HEADSET, JACK_TYPE_CARKIT, JACK_TYPE_OPENCABLE, JACK_TYPE_CVIDEO @@ -225,6 +227,8 @@ struct accessory_regu_descriptor { * making the decision or can cached voltage be used instead. * @minvol minimum voltage (mV) for decision * @maxvol maximum voltage (mV) for decision + * @alt_minvol minimum alternative voltage (mV) for decision + * @alt_maxvol maximum alternative voltage (mV) for decision */ struct accessory_detect_task { const char *typename; @@ -233,6 +237,8 @@ struct accessory_detect_task { int meas_mv; int minvol; int maxvol; + int alt_minvol; + int alt_maxvol; }; /** @@ -271,6 +277,7 @@ struct accessory_detect_task { * @config_accdetect1_hw: Callback for configuring accdet1 comparator. * @detect_plugged_in: Callback to detect type of accessory connected. * @meas_voltage_stable: Callback to read present accdet voltage. + * @meas_alt_voltage_stable: Callback to read present alt accdet voltage. * @config_hw_test_basic_carkit: Callback to configure hw for carkit * detect. * @turn_of_accdet_comparator: Call back to turn off comparators. @@ -319,6 +326,7 @@ struct abx500_ad { void (*config_accdetect1_hw)(struct abx500_ad *, int); int (*detect_plugged_in)(struct abx500_ad *); int (*meas_voltage_stable)(struct abx500_ad *); + int (*meas_alt_voltage_stable)(struct abx500_ad *); void (*config_hw_test_basic_carkit)(struct abx500_ad *, int); void (*turn_off_accdet_comparator)(struct platform_device *pdev); void (*turn_on_accdet_comparator)(struct platform_device *pdev); diff --git a/drivers/input/misc/ab5500-accdet.c b/drivers/input/misc/ab5500-accdet.c index 828ff29cb1e..280af8ac8be 100644 --- a/drivers/input/misc/ab5500-accdet.c +++ b/drivers/input/misc/ab5500-accdet.c @@ -187,6 +187,14 @@ static int ab5500_meas_voltage_stable(struct abx500_ad *dd) } /* + * not implemented + */ +static int ab5500_meas_alt_voltage_stable(struct abx500_ad *dd) +{ + return -1; +} + +/* * configures HW so that it is possible to make decision whether * accessory is connected or not. */ @@ -262,6 +270,7 @@ struct abx500_ad ab5500_accessory_det_callbacks = { .config_accdetect1_hw = ab5500_config_accdetect1_hw, .detect_plugged_in = ab5500_detect_plugged_in, .meas_voltage_stable = ab5500_meas_voltage_stable, + .meas_alt_voltage_stable = ab5500_meas_alt_voltage_stable, .config_hw_test_basic_carkit = ab5500_config_hw_test_basic_carkit, .turn_off_accdet_comparator = ab5500_turn_off_accdet_comparator, .turn_on_accdet_comparator = ab5500_turn_on_accdet_comparator, diff --git a/drivers/input/misc/ab8500-accdet.c b/drivers/input/misc/ab8500-accdet.c index 2d9c740bc17..0fe60364d54 100644 --- a/drivers/input/misc/ab8500-accdet.c +++ b/drivers/input/misc/ab8500-accdet.c @@ -21,6 +21,9 @@ #include <linux/gpio.h> #include <linux/err.h> #include <mach/abx500-accdet.h> +#ifdef CONFIG_SND_SOC_UX500_AB8500 +#include <sound/ux500_ab8500_ext.h> +#endif #define MAX_DET_COUNT 10 #define MAX_VOLT_DIFF 30 @@ -228,8 +231,38 @@ static int ab8500_detect_plugged_in(struct abx500_ad *dd) return value & BIT_ITSOURCE5_ACCDET1 ? 0 : 1; } +#ifdef CONFIG_SND_SOC_UX500_AB8500 + /* - * mic_line_voltage_stable - measures a relative stable voltage from spec. input + * meas_voltage_stable - measures relative stable voltage from spec. input + */ +static int ab8500_meas_voltage_stable(struct abx500_ad *dd) +{ + int ret, mv; + + ret = ux500_ab8500_audio_gpadc_measure((struct ab8500_gpadc *)dd->gpadc, + ACC_DETECT2, false, &mv); + + return (ret < 0) ? ret : mv; +} + +/* + * meas_alt_voltage_stable - measures relative stable voltage from spec. input + */ +static int ab8500_meas_alt_voltage_stable(struct abx500_ad *dd) +{ + int ret, mv; + + ret = ux500_ab8500_audio_gpadc_measure((struct ab8500_gpadc *)dd->gpadc, + ACC_DETECT2, true, &mv); + + return (ret < 0) ? ret : mv; +} + +#else + +/* + * meas_voltage_stable - measures relative stable voltage from spec. input */ static int ab8500_meas_voltage_stable(struct abx500_ad *dd) { @@ -251,6 +284,16 @@ static int ab8500_meas_voltage_stable(struct abx500_ad *dd) } /* + * not implemented for non soc setups + */ +static int ab8500_meas_alt_voltage_stable(struct abx500_ad *dd) +{ + return -1; +} + +#endif + +/* * configures HW so that it is possible to make decision whether * accessory is connected or not. */ @@ -392,6 +435,7 @@ struct abx500_ad ab8500_accessory_det_callbacks = { .config_accdetect1_hw = ab8500_config_accdetect1_hw, .detect_plugged_in = ab8500_detect_plugged_in, .meas_voltage_stable = ab8500_meas_voltage_stable, + .meas_alt_voltage_stable = ab8500_meas_alt_voltage_stable, .config_hw_test_basic_carkit = ab8500_config_hw_test_basic_carkit, .turn_off_accdet_comparator = ab8500_turn_off_accdet_comparator, .turn_on_accdet_comparator = ab8500_turn_on_accdet_comparator, diff --git a/drivers/input/misc/abx500-accdet.c b/drivers/input/misc/abx500-accdet.c index 92aa69d1176..d716a1d8870 100644 --- a/drivers/input/misc/abx500-accdet.c +++ b/drivers/input/misc/abx500-accdet.c @@ -49,6 +49,10 @@ #define ACCESSORY_DET_VOL_DONTCARE -1 #define ACCESSORY_HEADPHONE_DET_VOL_MIN 0 #define ACCESSORY_HEADPHONE_DET_VOL_MAX 40 +#define ACCESSORY_U_HEADSET_DET_VOL_MIN 47 +#define ACCESSORY_U_HEADSET_DET_VOL_MAX 732 +#define ACCESSORY_U_HEADSET_ALT_DET_VOL_MIN 25 +#define ACCESSORY_U_HEADSET_ALT_DET_VOL_MAX 50 #define ACCESSORY_CVIDEO_DET_VOL_MIN 41 #define ACCESSORY_CVIDEO_DET_VOL_MAX 105 #define ACCESSORY_CARKIT_DET_VOL_MIN 1100 @@ -87,7 +91,9 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 1, .req_det_count = 1, .minvol = ACCESSORY_DET_VOL_DONTCARE, - .maxvol = ACCESSORY_DET_VOL_DONTCARE + .maxvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE }, { .type = JACK_TYPE_HEADPHONE, @@ -95,7 +101,19 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 1, .req_det_count = 1, .minvol = ACCESSORY_HEADPHONE_DET_VOL_MIN, - .maxvol = ACCESSORY_HEADPHONE_DET_VOL_MAX + .maxvol = ACCESSORY_HEADPHONE_DET_VOL_MAX, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE + }, + { + .type = JACK_TYPE_UNSUPPORTED_HEADSET, + .typename = "UNSUPPORTED HEADSET", + .meas_mv = 1, + .req_det_count = 2, + .minvol = ACCESSORY_U_HEADSET_DET_VOL_MIN, + .maxvol = ACCESSORY_U_HEADSET_DET_VOL_MAX, + .alt_minvol = ACCESSORY_U_HEADSET_ALT_DET_VOL_MIN, + .alt_maxvol = ACCESSORY_U_HEADSET_ALT_DET_VOL_MAX }, { .type = JACK_TYPE_CVIDEO, @@ -103,7 +121,9 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 0, .req_det_count = 4, .minvol = ACCESSORY_CVIDEO_DET_VOL_MIN, - .maxvol = ACCESSORY_CVIDEO_DET_VOL_MAX + .maxvol = ACCESSORY_CVIDEO_DET_VOL_MAX, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE }, { .type = JACK_TYPE_OPENCABLE, @@ -111,7 +131,9 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 0, .req_det_count = 4, .minvol = ACCESSORY_OPENCABLE_DET_VOL_MIN, - .maxvol = ACCESSORY_OPENCABLE_DET_VOL_MAX + .maxvol = ACCESSORY_OPENCABLE_DET_VOL_MAX, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE }, { .type = JACK_TYPE_CARKIT, @@ -119,7 +141,9 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 1, .req_det_count = 1, .minvol = ACCESSORY_CARKIT_DET_VOL_MIN, - .maxvol = ACCESSORY_CARKIT_DET_VOL_MAX + .maxvol = ACCESSORY_CARKIT_DET_VOL_MAX, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE }, { .type = JACK_TYPE_HEADSET, @@ -127,7 +151,9 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 0, .req_det_count = 2, .minvol = ACCESSORY_HEADSET_DET_VOL_MIN, - .maxvol = ACCESSORY_HEADSET_DET_VOL_MAX + .maxvol = ACCESSORY_HEADSET_DET_VOL_MAX, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE }, { .type = JACK_TYPE_CONNECTED, @@ -135,7 +161,9 @@ static struct accessory_detect_task detect_ops[] = { .meas_mv = 0, .req_det_count = 4, .minvol = ACCESSORY_DET_VOL_DONTCARE, - .maxvol = ACCESSORY_DET_VOL_DONTCARE + .maxvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_minvol = ACCESSORY_DET_VOL_DONTCARE, + .alt_maxvol = ACCESSORY_DET_VOL_DONTCARE } }; @@ -288,6 +316,10 @@ void report_jack_status(struct abx500_ad *dd) dev_info(&dd->pdev->dev, "Accessory: %s\n", accessory_str(dd->jack_type)); + /* Never report unsupported headset */ + if (dd->jack_type == JACK_TYPE_UNSUPPORTED_HEADSET) + goto out; + if (dd->jack_type != JACK_TYPE_DISCONNECTED && dd->jack_type != JACK_TYPE_UNSPECIFIED) value |= SND_JACK_MECHANICAL; @@ -488,14 +520,28 @@ irqreturn_t button_release_irq_handler(int irq, void *_userdata) * voltage might be re-measured or previously measured voltage is reused. */ static int mic_vol_in_range(struct abx500_ad *dd, - int lo, int hi, int force_read) + int lo, int hi, int alt_lo, int alt_hi, int force_read) { static int mv = MIN_MIC_POWER; + static int alt_mv = MIN_MIC_POWER; - if (mv == -100 || force_read) + if (mv == MIN_MIC_POWER || force_read) mv = dd->meas_voltage_stable(dd); - return (mv >= lo && mv <= hi) ? 1 : 0; + if (mv < lo || mv > hi) + return 0; + + if (ACCESSORY_DET_VOL_DONTCARE == alt_lo && + ACCESSORY_DET_VOL_DONTCARE == alt_hi) + return 1; + + if (alt_mv == MIN_MIC_POWER || force_read) + alt_mv = dd->meas_alt_voltage_stable(dd); + + if (alt_mv < alt_lo || alt_mv > alt_hi) + return 0; + + return 1; } /* @@ -519,10 +565,13 @@ static int detect_hw(struct abx500_ad *dd, case JACK_TYPE_HEADPHONE: case JACK_TYPE_CVIDEO: case JACK_TYPE_HEADSET: + case JACK_TYPE_UNSUPPORTED_HEADSET: case JACK_TYPE_OPENCABLE: status = mic_vol_in_range(dd, task->minvol, task->maxvol, + task->alt_minvol, + task->alt_maxvol, task->meas_mv); break; default: @@ -675,6 +724,18 @@ static void config_accdetect(struct abx500_ad *dd) release_irq(dd, BUTTON_RELEASE_IRQ); break; + case JACK_TYPE_UNSUPPORTED_HEADSET: + dd->config_accdetect1_hw(dd, 1); + dd->config_accdetect2_hw(dd, 1); + + release_irq(dd, PLUG_IRQ); + claim_irq(dd, UNPLUG_IRQ); + release_irq(dd, BUTTON_PRESS_IRQ); + release_irq(dd, BUTTON_RELEASE_IRQ); + if (dd->set_av_switch) + dd->set_av_switch(dd, NOT_SET); + break; + case JACK_TYPE_CONNECTED: case JACK_TYPE_HEADSET: case JACK_TYPE_CARKIT: |