[alsa-devel] [PATCHv2 6/7] ASoC: TWL6030: Enable audio interrupt
Lopez Cruz, Misael
x0052729 at ti.com
Sat Sep 26 04:03:41 CEST 2009
NAUDINT interrupt line is provided by the TWL6030 codec to signal
externally events like headset plug/unplug, hook, power-up sequence
completion, etc.
Signed-off-by: Misael Lopez Cruz <x0052729 at ti.com>
---
sound/soc/codecs/twl6030.c | 78 +++++++++++++++++++++++++++++++++++++++++++-
sound/soc/codecs/twl6030.h | 10 ++++++
2 files changed, 87 insertions(+), 1 deletions(-)
diff --git a/sound/soc/codecs/twl6030.c b/sound/soc/codecs/twl6030.c
index 032619d..5cf2099 100644
--- a/sound/soc/codecs/twl6030.c
+++ b/sound/soc/codecs/twl6030.c
@@ -47,6 +47,7 @@ struct twl6030_data {
struct snd_soc_codec codec;
int codec_powered;
unsigned int sysclk;
+ struct work_struct audint_work;
};
/*
@@ -329,6 +330,58 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
return 0;
}
+/* audio interrupt handler */
+irqreturn_t twl6030_naudint_handler(int irq, void *data)
+{
+ struct snd_soc_codec *codec = data;
+ struct twl6030_data *priv = codec->private_data;
+
+ schedule_work(&priv->audint_work);
+
+ /* disable audint irq to let workqueue to execute */
+ disable_irq_nosync(irq);
+
+ return IRQ_HANDLED;
+}
+
+void twl6030_naudint_work(struct work_struct *work)
+{
+ struct twl_codec_data *twl_codec;
+ struct snd_soc_codec *codec;
+ struct twl6030_data *priv;
+ u8 intid;
+
+ priv = container_of(work, struct twl6030_data, audint_work);
+ codec = &priv->codec;
+ twl_codec = codec->control_data;
+
+ twl_i2c_read_u8(TWL6030_MODULE_AUDIO, &intid, TWL6030_REG_INTID);
+
+ switch (intid) {
+ case TWL6030_THINT:
+ dev_alert(codec->dev, "die temp over-limit detection\n");
+ break;
+ case TWL6030_PLUGINT:
+ case TWL6030_UNPLUGINT:
+ case TWL6030_HOOKINT:
+ break;
+ case TWL6030_HFINT:
+ dev_alert(codec->dev, "hf drivers over current detection\n");
+ break;
+ case TWL6030_VIBINT:
+ dev_alert(codec->dev, "vib drivers over current detection\n");
+ break;
+ case TWL6030_READYINT:
+ dev_alert(codec->dev, "codec is ready\n");
+ break;
+ default:
+ dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
+ break;
+ }
+
+ enable_irq(twl_codec->naudint_irq);
+}
+
/*
* MICATT volume control:
* from -6 to 0 dB in 6 dB steps
@@ -610,6 +663,7 @@ static int twl6030_set_bias_level(struct snd_soc_codec *codec,
priv->codec_powered = 0;
break;
}
+
codec->bias_level = level;
return 0;
@@ -954,8 +1008,15 @@ static int __devinit twl6030_codec_probe(struct platform_device *pdev)
struct twl6030_data *priv;
struct snd_soc_codec *codec;
int audpwron_gpio = twl_codec->audpwron_gpio;
+ int naudint_irq = twl_codec->naudint_irq;
int ret = 0;
+ /* prerequisites */
+ if (!naudint_irq) {
+ dev_err(&pdev->dev, "no audio interrupt irq supplied\n");
+ return -EINVAL;
+ }
+
priv = kzalloc(sizeof(struct twl6030_data), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
@@ -998,6 +1059,17 @@ static int __devinit twl6030_codec_probe(struct platform_device *pdev)
priv->codec_powered = 0;
}
+ /* audio interrupt */
+ INIT_WORK(&priv->audint_work, twl6030_naudint_work);
+
+ ret = request_irq(naudint_irq,
+ twl6030_naudint_handler,
+ IRQF_TRIGGER_LOW | IRQF_DISABLED,
+ "twl6030-codec",
+ codec);
+ if (ret)
+ goto gpio2_err;
+
/* init vio registers */
twl6030_init_vio_regs(codec);
@@ -1006,7 +1078,7 @@ static int __devinit twl6030_codec_probe(struct platform_device *pdev)
ret = snd_soc_register_codec(codec);
if (ret)
- goto gpio2_err;
+ goto reg_err;
twl6030_codec = codec;
@@ -1019,6 +1091,8 @@ static int __devinit twl6030_codec_probe(struct platform_device *pdev)
dai_err:
snd_soc_unregister_codec(codec);
twl6030_codec = NULL;
+reg_err:
+ free_irq(naudint_irq, twl_codec);
gpio2_err:
if (gpio_is_valid(audpwron_gpio))
gpio_free(audpwron_gpio);
@@ -1036,6 +1110,8 @@ static int __devexit twl6030_codec_remove(struct platform_device *pdev)
if (gpio_is_valid(twl_codec->audpwron_gpio))
gpio_free(twl_codec->audpwron_gpio);
+ free_irq(twl_codec->naudint_irq, twl6030_codec);
+
snd_soc_unregister_dai(&twl6030_dai);
snd_soc_unregister_codec(twl6030_codec);
diff --git a/sound/soc/codecs/twl6030.h b/sound/soc/codecs/twl6030.h
index 15d3e1b..8a106f2 100644
--- a/sound/soc/codecs/twl6030.h
+++ b/sound/soc/codecs/twl6030.h
@@ -67,6 +67,16 @@
#define TWL6030_VIOREGNUM 18
#define TWL6030_VDDREGNUM 21
+/* INTID (0x03) fields */
+
+#define TWL6030_THINT 0x01
+#define TWL6030_PLUGINT 0x02
+#define TWL6030_UNPLUGINT 0x04
+#define TWL6030_HOOKINT 0x08
+#define TWL6030_HFINT 0x10
+#define TWL6030_VIBINT 0x20
+#define TWL6030_READYINT 0x40
+
/* NCPCTL (0x05) fields */
#define TWL6030_NCPENA 0x01
--
1.5.4.3
More information about the Alsa-devel
mailing list