From c589c4b50ffe1965eaf99869275de5b0581e5f91 Mon Sep 17 00:00:00 2001 From: Vaibhav Agarwal Date: Wed, 21 Mar 2012 00:54:45 +0530 Subject: [PATCH] Audio: Add different handler for button_press GPIO BZ: 26377 Currently, only single handler is used for HP_DET, BUTTON_PRESS interrupt line. However, it should be handled differently. Thus, no interrupts are reported for button press event(s). The solution is to register seperate handlers for different GPIO lines and handle each event appropriately. Signed-off-by: Vaibhav Agarwal Change-Id: I8262487d423a10f49d93ca24be7a43cbac894738 Reviewed-on: http://android.intel.com:8080/39834 Reviewed-by: Kp, Jeeja Reviewed-by: Koul, Vinod Reviewed-by: M, Arulselvan Tested-by: M, Arulselvan Reviewed-by: buildbot Tested-by: buildbot --- sound/soc/codecs/cs42l73.c | 38 +++++++++++++++++++++-------- sound/soc/codecs/cs42l73.h | 2 ++ sound/soc/mid-x86/clv_machine.c | 54 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 64dc63b..1557305 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1131,18 +1131,44 @@ static int cs42l73_set_mic_bias(struct snd_soc_codec *codec, int state) return 0; } -void cs42l73_hp_detection(struct snd_soc_codec *codec, +void cs42l73_bp_detection(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int plug_status) { unsigned int status; + unsigned int reg; + unsigned int mask = SND_JACK_BTN_0 | SND_JACK_HEADSET; + + if (plug_status) { + pr_err("%s: Invalid interrupt\n", __func__); + return; + } else { + snd_soc_update_bits(codec, CS42L73_IM1, MIC2_SDET, MIC2_SDET); + reg = snd_soc_read(codec, CS42L73_IS1); + if (reg & MIC2_SDET) { /*button pressed */ + pr_debug("%s:Button Pressed\n", __func__); + status = SND_JACK_HEADSET | SND_JACK_BTN_0; + } else { + pr_debug("%s:Button Released\n", __func__); + status = SND_JACK_HEADSET; + } + } + snd_soc_jack_report(jack, status, mask); +} +EXPORT_SYMBOL_GPL(cs42l73_bp_detection); + +void cs42l73_hp_detection(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, + int plug_status) +{ + unsigned int status = 0; unsigned int micbias = 0; int hs_status = 0; unsigned int reg; unsigned int mask = SND_JACK_BTN_0 | SND_JACK_HEADSET; if (plug_status) { - pr_debug("In cs42l73_hp_detection disable micbias\n"); + pr_debug("%s: Jack removed - disable micbias\n", __func__); cs42l73_set_mic_bias(codec, MIC_BIAS_DISABLE); } else { micbias = snd_soc_read(codec, CS42L73_PWRCTL2); @@ -1153,7 +1179,6 @@ void cs42l73_hp_detection(struct snd_soc_codec *codec, } snd_soc_update_bits(codec, CS42L73_IM1, MIC2_SDET, MIC2_SDET); - mdelay(1000); reg = snd_soc_read(codec, CS42L73_IS1); pr_debug("Mic detect = %x ISI =%x\n", micbias, reg); @@ -1166,11 +1191,6 @@ void cs42l73_hp_detection(struct snd_soc_codec *codec, status = SND_JACK_HEADSET; pr_debug("Headset detected\n"); } - } else { - if (reg & MIC2_SDET) /*button pressed */ - status = SND_JACK_HEADSET | SND_JACK_BTN_0; - else - status = SND_JACK_HEADSET; } } snd_soc_jack_report(jack, status, mask); @@ -1286,8 +1306,6 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, static __devexit int cs42l73_i2c_remove(struct i2c_client *client) { - struct cs42l73_private *cs42l73 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); /* No need for kfree(cs42l73), as it'll be automatically freed diff --git a/sound/soc/codecs/cs42l73.h b/sound/soc/codecs/cs42l73.h index 0e844d5..cd31959 100644 --- a/sound/soc/codecs/cs42l73.h +++ b/sound/soc/codecs/cs42l73.h @@ -226,6 +226,8 @@ #define CS42L73_MMCC(id) (CS42L73_XSPMMCC + (id << 1)) #define CS42L73_SPFS(id) ((id == CS42L73_ASP) ? CS42L73_ASPC : CS42L73_VXSPFS) +extern void cs42l73_bp_detection(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, int plug_status); extern void cs42l73_hp_detection(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int plug_status); diff --git a/sound/soc/mid-x86/clv_machine.c b/sound/soc/mid-x86/clv_machine.c index 7297cf0..ca9c80c 100644 --- a/sound/soc/mid-x86/clv_machine.c +++ b/sound/soc/mid-x86/clv_machine.c @@ -162,6 +162,40 @@ static struct snd_soc_jack_gpio hs_button_gpio = { .report = SND_JACK_BTN_0, .debounce_time = 100, }; + +static void clv_soc_jack_gpio_detect_bp(struct snd_soc_jack_gpio *gpio) +{ + int enable; + struct snd_soc_jack *jack = gpio->jack; + struct snd_soc_codec *codec = jack->codec; + + enable = gpio_get_value(gpio->gpio); + if (gpio->invert) + enable = !enable; + pr_debug("%s: gpio->%d=0x%x\n", __func__, gpio->gpio, enable); + cs42l73_bp_detection(codec, jack, enable); +} + +/* irq handler for button_press gpio pin */ +static irqreturn_t clv_gpio_handler_bp(int irq, void *data) +{ + struct snd_soc_jack_gpio *gpio = data; + + schedule_delayed_work(&gpio->work, + msecs_to_jiffies(gpio->debounce_time)); + + return IRQ_HANDLED; +} + +/* gpio work */ +static void clv_gpio_work_bp(struct work_struct *work) +{ + struct snd_soc_jack_gpio *gpio; + + gpio = container_of(work, struct snd_soc_jack_gpio, work.work); + clv_soc_jack_gpio_detect_bp(gpio); +} + static void clv_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) { int enable; @@ -170,6 +204,7 @@ static void clv_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) enable = gpio_get_value(gpio->gpio); if (gpio->invert) enable = !enable; + pr_debug("%s:gpio->%d=0x%d\n", __func__, gpio->gpio, enable); cs42l73_hp_detection(codec, jack, enable); } @@ -224,11 +259,21 @@ int clv_soc_jack_add_gpio(struct snd_soc_jack *jack, if (ret) goto err; - INIT_DELAYED_WORK(&gpio->work, clv_gpio_work); - gpio->jack = jack; + if (gpio->gpio == CS42L73_HPSENSE_GPIO) { + + INIT_DELAYED_WORK(&gpio->work, clv_gpio_work); + gpio->jack = jack; + + ret = request_irq(gpio_to_irq(gpio->gpio), clv_gpio_handler, + IRQF_TRIGGER_FALLING, codec->name, gpio); + } else { + INIT_DELAYED_WORK(&gpio->work, clv_gpio_work_bp); + gpio->jack = jack; + + ret = request_irq(gpio_to_irq(gpio->gpio), clv_gpio_handler_bp, + IRQF_TRIGGER_FALLING, codec->name, gpio); - ret = request_irq(gpio_to_irq(gpio->gpio), clv_gpio_handler, - IRQF_TRIGGER_FALLING, codec->name, gpio); + } if (ret) goto err; @@ -239,6 +284,7 @@ int clv_soc_jack_add_gpio(struct snd_soc_jack *jack, /* Update initial jack status */ if (gpio->gpio == CS42L73_HPSENSE_GPIO) clv_soc_jack_gpio_detect(gpio); + return 0; err: -- 2.7.4