--- v2
+++ v1
@@ -1,49 +1,109 @@
-We no longer have users for the set_hs_extmute callback which has been
-replaced by hs_extmute_gpio so the codec driver can handle the external
-mute if it is needed by the board.
+When the kernel has been booted with DT blob the platform data is NULL for
+the driver.
+We need to construct the pdata based on the DT information for runtime use.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
- include/linux/i2c/twl.h | 2 --
- sound/soc/codecs/twl4030.c | 6 ------
- 2 files changed, 0 insertions(+), 8 deletions(-)
+ sound/soc/codecs/twl4030.c | 67 ++++++++++++++++++++++++++++++++++++++-----
+ 1 files changed, 59 insertions(+), 8 deletions(-)
-diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
-index 2040309..a4885a6 100644
---- a/include/linux/i2c/twl.h
-+++ b/include/linux/i2c/twl.h
-@@ -667,8 +667,6 @@ struct twl4030_codec_data {
- unsigned int check_defaults:1;
- unsigned int reset_registers:1;
- unsigned int hs_extmute:1;
-- void (*set_hs_extmute)(int mute); /* Deprecated, use hs_extmute_gpio and
-- hs_extmute_disable_level */
- int hs_extmute_gpio;
- };
-
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
-index 5fc271a..27ccea4 100644
+index bf0240d..68495a2 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
-@@ -767,9 +767,6 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
- if (pdata && pdata->hs_extmute) {
- if (gpio_is_valid(pdata->hs_extmute_gpio)) {
- gpio_set_value(pdata->hs_extmute_gpio, 1);
-- } else if (pdata->set_hs_extmute) {
-- dev_warn(codec->dev, "set_hs_extmute is deprecated\n");
-- pdata->set_hs_extmute(1);
- } else {
- hs_pop |= TWL4030_EXTMUTE;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
-@@ -808,9 +805,6 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
- if (pdata && pdata->hs_extmute) {
- if (gpio_is_valid(pdata->hs_extmute_gpio)) {
- gpio_set_value(pdata->hs_extmute_gpio, 0);
-- } else if (pdata->set_hs_extmute) {
-- dev_warn(codec->dev, "set_hs_extmute is deprecated\n");
-- pdata->set_hs_extmute(0);
- } else {
- hs_pop &= ~TWL4030_EXTMUTE;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+@@ -26,6 +26,7 @@
+ #include <linux/pm.h>
+ #include <linux/i2c.h>
+ #include <linux/platform_device.h>
++#include <linux/of.h>
+ #include <linux/i2c/twl.h>
+ #include <linux/slab.h>
+ #include <linux/gpio.h>
+@@ -295,13 +296,70 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
+
+ }
+
+-static void twl4030_init_chip(struct snd_soc_codec *codec)
++static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
++ struct device_node *node)
++{
++ int value;
++
++ of_property_read_u32(node, "ti,digimic_delay",
++ &pdata->digimic_delay);
++ of_property_read_u32(node, "ti,ramp_delay_value",
++ &pdata->ramp_delay_value);
++ of_property_read_u32(node, "ti,offset_cncl_path",
++ &pdata->offset_cncl_path);
++ if (!of_property_read_u32(node, "ti,hs_extmute", &value))
++ pdata->hs_extmute = value;
++ else
++ pdata->hs_extmute = 0;
++
++ if (pdata->hs_extmute) {
++ int ret = of_property_read_u32(node, "ti,hs_extmute_gpio",
++ &pdata->hs_extmute_gpio);
++ if (!ret) {
++ if (!of_property_read_u32(node,
++ "ti,hs_extmute_disable_level",
++ &value)) {
++ pdata->hs_extmute_disable_level = value;
++ }
++ } else {
++ pdata->hs_extmute_gpio = -1;
++ }
++ }
++}
++
++static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
+ {
+ struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
++ struct device_node *twl4030_codec_node = NULL;
++
++#ifdef CONFIG_OF
++ twl4030_codec_node = of_find_node_by_name(codec->dev->parent->of_node,
++ "codec");
++#endif
++
++ if (!pdata && twl4030_codec_node) {
++ pdata = devm_kzalloc(codec->dev,
++ sizeof(struct twl4030_codec_data),
++ GFP_KERNEL);
++ if (!pdata) {
++ dev_err(codec->dev, "Can not allocate memory\n");
++ return NULL;
++ }
++ twl4030_setup_pdata_of(pdata, twl4030_codec_node);
++ }
++
++ return pdata;
++}
++
++static void twl4030_init_chip(struct snd_soc_codec *codec)
++{
++ struct twl4030_codec_data *pdata;
+ struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+ u8 reg, byte;
+ int i = 0;
+
++ pdata = twl4030_get_pdata(codec);
++
+ if (pdata && pdata->hs_extmute &&
+ gpio_is_valid(pdata->hs_extmute_gpio)) {
+ int ret, level;
+@@ -2288,13 +2346,6 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
+
+ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
+ {
+- struct twl4030_codec_data *pdata = pdev->dev.platform_data;
+-
+- if (!pdata) {
+- dev_err(&pdev->dev, "platform_data is missing\n");
+- return -EINVAL;
+- }
+-
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
+ twl4030_dai, ARRAY_SIZE(twl4030_dai));
+ }
--
1.7.8.6