summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2012-09-10 13:46:25 +0300
committerSamuel Ortiz <sameo@linux.intel.com>2012-09-18 15:45:05 +0200
commit019a7e6b7b312b17cd74b45d09d4ec17486c4088 (patch)
tree57fa578d2bae3b906b7082804f008406be41a056
parent1cc44f4354c03d1ebcfa670875478ee1c9368086 (diff)
mfd: twl4030-audio: Add DT support
Support for loading the twl4030 audio module via devicetree. Sub devices for codec and vibra will be created as mfd devices once the core MFD driver is loaded when the kernel is booted with a DT blob. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--Documentation/devicetree/bindings/mfd/twl4030-audio.txt46
-rw-r--r--drivers/mfd/twl4030-audio.c54
2 files changed, 93 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
new file mode 100644
index 000000000000..414d2ae0adf6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
@@ -0,0 +1,46 @@
+Texas Instruments TWL family (twl4030) audio module
+
+The audio module inside the TWL family consist of an audio codec and a vibra
+driver.
+
+Required properties:
+- compatible : must be "ti,twl4030-audio"
+
+Optional properties, nodes:
+
+Audio functionality:
+- codec { }: Need to be present if the audio functionality is used. Within this
+ section the following options can be used:
+- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts
+ from the start of the recorded sample (in ms)
+-ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise
+-ti,hs_extmute: Use external mute for HS pop reduction
+-ti,hs_extmute_gpio: Use external GPIO to control the external mute
+-ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the
+ valid values.
+
+Vibra functionality
+- ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if
+ missing or it is 0, the vibra functionality is disabled.
+
+Example:
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+
+ ti,enable-vibra = <1>;
+
+ codec {
+ ti,ramp_delay_value = <3>;
+ };
+
+ };
+ };
+};
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 31605fa02ca1..5c11acf9e0fd 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -28,6 +28,8 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl4030-audio.h>
@@ -156,15 +158,42 @@ unsigned int twl4030_audio_get_mclk(void)
}
EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
+static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
+ struct device_node *node)
+{
+ if (pdata && pdata->codec)
+ return true;
+
+ if (of_find_node_by_name(node, "codec"))
+ return true;
+
+ return false;
+}
+
+static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
+ struct device_node *node)
+{
+ int vibra;
+
+ if (pdata && pdata->vibra)
+ return true;
+
+ if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra)
+ return true;
+
+ return false;
+}
+
static int __devinit twl4030_audio_probe(struct platform_device *pdev)
{
struct twl4030_audio *audio;
struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+ struct device_node *node = pdev->dev.of_node;
struct mfd_cell *cell = NULL;
int ret, childs = 0;
u8 val;
- if (!pdata) {
+ if (!pdata && !node) {
dev_err(&pdev->dev, "Platform data is missing\n");
return -EINVAL;
}
@@ -202,18 +231,22 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;
- if (pdata->codec) {
+ if (twl4030_audio_has_codec(pdata, node)) {
cell = &audio->cells[childs];
cell->name = "twl4030-codec";
- cell->platform_data = pdata->codec;
- cell->pdata_size = sizeof(*pdata->codec);
+ if (pdata) {
+ cell->platform_data = pdata->codec;
+ cell->pdata_size = sizeof(*pdata->codec);
+ }
childs++;
}
- if (pdata->vibra) {
+ if (twl4030_audio_has_vibra(pdata, node)) {
cell = &audio->cells[childs];
cell->name = "twl4030-vibra";
- cell->platform_data = pdata->vibra;
- cell->pdata_size = sizeof(*pdata->vibra);
+ if (pdata) {
+ cell->platform_data = pdata->vibra;
+ cell->pdata_size = sizeof(*pdata->vibra);
+ }
childs++;
}
@@ -245,10 +278,17 @@ static int __devexit twl4030_audio_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id twl4030_audio_of_match[] = {
+ {.compatible = "ti,twl4030-audio", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, twl4030_audio_of_match);
+
static struct platform_driver twl4030_audio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "twl4030-audio",
+ .of_match_table = twl4030_audio_of_match,
},
.probe = twl4030_audio_probe,
.remove = __devexit_p(twl4030_audio_remove),