|
@@ -19,6 +19,9 @@
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/mfd/core.h>
|
|
|
+#include <linux/of.h>
|
|
|
+#include <linux/of_device.h>
|
|
|
+#include <linux/of_gpio.h>
|
|
|
#include <linux/pm_runtime.h>
|
|
|
#include <linux/regmap.h>
|
|
|
#include <linux/regulator/consumer.h>
|
|
@@ -396,6 +399,60 @@ static const struct reg_default wm1811_reva_patch[] = {
|
|
|
{ 0x102, 0x0 },
|
|
|
};
|
|
|
|
|
|
+#ifdef CONFIG_OF
|
|
|
+static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)
|
|
|
+{
|
|
|
+ struct device_node *np = wm8994->dev->of_node;
|
|
|
+ struct wm8994_pdata *pdata = &wm8994->pdata;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (!np)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (of_property_read_u32_array(np, "wlf,gpio-cfg", pdata->gpio_defaults,
|
|
|
+ ARRAY_SIZE(pdata->gpio_defaults)) >= 0) {
|
|
|
+ for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
|
|
|
+ if (wm8994->pdata.gpio_defaults[i] == 0)
|
|
|
+ pdata->gpio_defaults[i]
|
|
|
+ = WM8994_CONFIGURE_GPIO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ of_property_read_u32_array(np, "wlf,micbias-cfg", pdata->micbias,
|
|
|
+ ARRAY_SIZE(pdata->micbias));
|
|
|
+
|
|
|
+ pdata->lineout1_diff = true;
|
|
|
+ pdata->lineout2_diff = true;
|
|
|
+ if (of_find_property(np, "wlf,lineout1-se", NULL))
|
|
|
+ pdata->lineout1_diff = false;
|
|
|
+ if (of_find_property(np, "wlf,lineout2-se", NULL))
|
|
|
+ pdata->lineout2_diff = false;
|
|
|
+
|
|
|
+ if (of_find_property(np, "wlf,lineout1-feedback", NULL))
|
|
|
+ pdata->lineout1fb = true;
|
|
|
+ if (of_find_property(np, "wlf,lineout2-feedback", NULL))
|
|
|
+ pdata->lineout2fb = true;
|
|
|
+
|
|
|
+ if (of_find_property(np, "wlf,ldoena-always-driven", NULL))
|
|
|
+ pdata->lineout2fb = true;
|
|
|
+
|
|
|
+ pdata->ldo[0].enable = of_get_named_gpio(np, "wlf,ldo1ena", 0);
|
|
|
+ if (pdata->ldo[0].enable < 0)
|
|
|
+ pdata->ldo[0].enable = 0;
|
|
|
+
|
|
|
+ pdata->ldo[1].enable = of_get_named_gpio(np, "wlf,ldo2ena", 0);
|
|
|
+ if (pdata->ldo[1].enable < 0)
|
|
|
+ pdata->ldo[1].enable = 0;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#else
|
|
|
+static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Instantiate the generic non-control parts of the device.
|
|
|
*/
|
|
@@ -414,6 +471,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
|
|
}
|
|
|
pdata = &wm8994->pdata;
|
|
|
|
|
|
+ ret = wm8994_set_pdata_from_of(wm8994);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
dev_set_drvdata(wm8994->dev, wm8994);
|
|
|
|
|
|
/* Add the on-chip regulators first for bootstrapping */
|
|
@@ -683,6 +744,7 @@ MODULE_DEVICE_TABLE(of, wm8994_of_match);
|
|
|
static int wm8994_i2c_probe(struct i2c_client *i2c,
|
|
|
const struct i2c_device_id *id)
|
|
|
{
|
|
|
+ const struct of_device_id *of_id;
|
|
|
struct wm8994 *wm8994;
|
|
|
int ret;
|
|
|
|
|
@@ -693,7 +755,14 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
|
|
|
i2c_set_clientdata(i2c, wm8994);
|
|
|
wm8994->dev = &i2c->dev;
|
|
|
wm8994->irq = i2c->irq;
|
|
|
- wm8994->type = id->driver_data;
|
|
|
+
|
|
|
+ if (i2c->dev.of_node) {
|
|
|
+ of_id = of_match_device(wm8994_of_match, &i2c->dev);
|
|
|
+ if (of_id)
|
|
|
+ wm8994->type = (int)of_id->data;
|
|
|
+ } else {
|
|
|
+ wm8994->type = id->driver_data;
|
|
|
+ }
|
|
|
|
|
|
wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config);
|
|
|
if (IS_ERR(wm8994->regmap)) {
|
|
@@ -733,7 +802,7 @@ static struct i2c_driver wm8994_i2c_driver = {
|
|
|
.name = "wm8994",
|
|
|
.owner = THIS_MODULE,
|
|
|
.pm = &wm8994_pm_ops,
|
|
|
- .of_match_table = wm8994_of_match,
|
|
|
+ .of_match_table = of_match_ptr(wm8994_of_match),
|
|
|
},
|
|
|
.probe = wm8994_i2c_probe,
|
|
|
.remove = wm8994_i2c_remove,
|