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);
}
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);
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);
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
#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);
.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;
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);
}
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;
/* Update initial jack status */
if (gpio->gpio == CS42L73_HPSENSE_GPIO)
clv_soc_jack_gpio_detect(gpio);
+
return 0;
err: