summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>2017-03-17 06:05:18 -0400
committerLee Jones <lee.jones@linaro.org>2017-03-23 07:45:50 -0400
commitf6dd8449cd50de25881b76cecf1086bebeb11fe8 (patch)
treefa757139b73dc9a8e79e46952d93db19dd5e8068
parentc1ae3cfa0e89fa1a7ecc4c99031f5e9ae99d9201 (diff)
mfd: wm831x: Add basic device tree binding
Add the basic ability to register the device through device tree, more work is needed to get each individual sub-driver functioning correctly but this is enough to get the device to probe from device tree. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/wm831x-core.c29
-rw-r--r--drivers/mfd/wm831x-i2c.c19
-rw-r--r--drivers/mfd/wm831x-irq.c6
-rw-r--r--drivers/mfd/wm831x-spi.c18
-rw-r--r--include/linux/mfd/wm831x/core.h9
5 files changed, 66 insertions, 15 deletions
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 3e0e99ec5836..13a4c1190dca 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -19,6 +19,8 @@
19#include <linux/mfd/core.h> 19#include <linux/mfd/core.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/of.h>
23#include <linux/of_device.h>
22 24
23#include <linux/mfd/wm831x/core.h> 25#include <linux/mfd/wm831x/core.h>
24#include <linux/mfd/wm831x/pdata.h> 26#include <linux/mfd/wm831x/pdata.h>
@@ -1613,12 +1615,24 @@ struct regmap_config wm831x_regmap_config = {
1613}; 1615};
1614EXPORT_SYMBOL_GPL(wm831x_regmap_config); 1616EXPORT_SYMBOL_GPL(wm831x_regmap_config);
1615 1617
1618const struct of_device_id wm831x_of_match[] = {
1619 { .compatible = "wlf,wm8310", .data = (void *)WM8310 },
1620 { .compatible = "wlf,wm8311", .data = (void *)WM8311 },
1621 { .compatible = "wlf,wm8312", .data = (void *)WM8312 },
1622 { .compatible = "wlf,wm8320", .data = (void *)WM8320 },
1623 { .compatible = "wlf,wm8321", .data = (void *)WM8321 },
1624 { .compatible = "wlf,wm8325", .data = (void *)WM8325 },
1625 { .compatible = "wlf,wm8326", .data = (void *)WM8326 },
1626 { },
1627};
1628EXPORT_SYMBOL_GPL(wm831x_of_match);
1629
1616/* 1630/*
1617 * Instantiate the generic non-control parts of the device. 1631 * Instantiate the generic non-control parts of the device.
1618 */ 1632 */
1619int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) 1633int wm831x_device_init(struct wm831x *wm831x, int irq)
1620{ 1634{
1621 struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev); 1635 struct wm831x_pdata *pdata = &wm831x->pdata;
1622 int rev, wm831x_num; 1636 int rev, wm831x_num;
1623 enum wm831x_parent parent; 1637 enum wm831x_parent parent;
1624 int ret, i; 1638 int ret, i;
@@ -1627,8 +1641,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1627 mutex_init(&wm831x->key_lock); 1641 mutex_init(&wm831x->key_lock);
1628 dev_set_drvdata(wm831x->dev, wm831x); 1642 dev_set_drvdata(wm831x->dev, wm831x);
1629 1643
1630 if (pdata) 1644 wm831x->soft_shutdown = pdata->soft_shutdown;
1631 wm831x->soft_shutdown = pdata->soft_shutdown;
1632 1645
1633 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); 1646 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1634 if (ret < 0) { 1647 if (ret < 0) {
@@ -1663,7 +1676,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1663 */ 1676 */
1664 if (ret == 0) { 1677 if (ret == 0) {
1665 dev_info(wm831x->dev, "Device is an engineering sample\n"); 1678 dev_info(wm831x->dev, "Device is an engineering sample\n");
1666 ret = id; 1679 ret = wm831x->type;
1667 } 1680 }
1668 1681
1669 switch (ret) { 1682 switch (ret) {
@@ -1736,9 +1749,9 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1736 /* This will need revisiting in future but is OK for all 1749 /* This will need revisiting in future but is OK for all
1737 * current parts. 1750 * current parts.
1738 */ 1751 */
1739 if (parent != id) 1752 if (parent != wm831x->type)
1740 dev_warn(wm831x->dev, "Device was registered as a WM%lx\n", 1753 dev_warn(wm831x->dev, "Device was registered as a WM%x\n",
1741 id); 1754 wm831x->type);
1742 1755
1743 /* Bootstrap the user key */ 1756 /* Bootstrap the user key */
1744 ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY); 1757 ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index 824bcbaa9624..781af060f32d 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -19,6 +19,8 @@
19#include <linux/mfd/core.h> 19#include <linux/mfd/core.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/of.h>
23#include <linux/of_device.h>
22#include <linux/regmap.h> 24#include <linux/regmap.h>
23 25
24#include <linux/mfd/wm831x/core.h> 26#include <linux/mfd/wm831x/core.h>
@@ -27,15 +29,26 @@
27static int wm831x_i2c_probe(struct i2c_client *i2c, 29static int wm831x_i2c_probe(struct i2c_client *i2c,
28 const struct i2c_device_id *id) 30 const struct i2c_device_id *id)
29{ 31{
32 struct wm831x_pdata *pdata = dev_get_platdata(&i2c->dev);
33 const struct of_device_id *of_id;
30 struct wm831x *wm831x; 34 struct wm831x *wm831x;
35 enum wm831x_parent type;
31 int ret; 36 int ret;
32 37
38 if (i2c->dev.of_node) {
39 of_id = of_match_device(wm831x_of_match, &i2c->dev);
40 type = (enum wm831x_parent)of_id->data;
41 } else {
42 type = (enum wm831x_parent)id->driver_data;
43 }
44
33 wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL); 45 wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL);
34 if (wm831x == NULL) 46 if (wm831x == NULL)
35 return -ENOMEM; 47 return -ENOMEM;
36 48
37 i2c_set_clientdata(i2c, wm831x); 49 i2c_set_clientdata(i2c, wm831x);
38 wm831x->dev = &i2c->dev; 50 wm831x->dev = &i2c->dev;
51 wm831x->type = type;
39 52
40 wm831x->regmap = devm_regmap_init_i2c(i2c, &wm831x_regmap_config); 53 wm831x->regmap = devm_regmap_init_i2c(i2c, &wm831x_regmap_config);
41 if (IS_ERR(wm831x->regmap)) { 54 if (IS_ERR(wm831x->regmap)) {
@@ -45,7 +58,10 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
45 return ret; 58 return ret;
46 } 59 }
47 60
48 return wm831x_device_init(wm831x, id->driver_data, i2c->irq); 61 if (pdata)
62 memcpy(&wm831x->pdata, pdata, sizeof(*pdata));
63
64 return wm831x_device_init(wm831x, i2c->irq);
49} 65}
50 66
51static int wm831x_i2c_remove(struct i2c_client *i2c) 67static int wm831x_i2c_remove(struct i2c_client *i2c)
@@ -94,6 +110,7 @@ static struct i2c_driver wm831x_i2c_driver = {
94 .driver = { 110 .driver = {
95 .name = "wm831x", 111 .name = "wm831x",
96 .pm = &wm831x_pm_ops, 112 .pm = &wm831x_pm_ops,
113 .of_match_table = of_match_ptr(wm831x_of_match),
97 }, 114 },
98 .probe = wm831x_i2c_probe, 115 .probe = wm831x_i2c_probe,
99 .remove = wm831x_i2c_remove, 116 .remove = wm831x_i2c_remove,
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index dfea8b9c2fe6..c01239a600db 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -564,7 +564,7 @@ static const struct irq_domain_ops wm831x_irq_domain_ops = {
564 564
565int wm831x_irq_init(struct wm831x *wm831x, int irq) 565int wm831x_irq_init(struct wm831x *wm831x, int irq)
566{ 566{
567 struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev); 567 struct wm831x_pdata *pdata = &wm831x->pdata;
568 struct irq_domain *domain; 568 struct irq_domain *domain;
569 int i, ret, irq_base; 569 int i, ret, irq_base;
570 570
@@ -579,7 +579,7 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
579 } 579 }
580 580
581 /* Try to dynamically allocate IRQs if no base is specified */ 581 /* Try to dynamically allocate IRQs if no base is specified */
582 if (pdata && pdata->irq_base) { 582 if (pdata->irq_base) {
583 irq_base = irq_alloc_descs(pdata->irq_base, 0, 583 irq_base = irq_alloc_descs(pdata->irq_base, 0,
584 WM831X_NUM_IRQS, 0); 584 WM831X_NUM_IRQS, 0);
585 if (irq_base < 0) { 585 if (irq_base < 0) {
@@ -608,7 +608,7 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
608 return -EINVAL; 608 return -EINVAL;
609 } 609 }
610 610
611 if (pdata && pdata->irq_cmos) 611 if (pdata->irq_cmos)
612 i = 0; 612 i = 0;
613 else 613 else
614 i = WM831X_IRQ_OD; 614 i = WM831X_IRQ_OD;
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 80482aeb246a..c332e2885b26 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -14,6 +14,8 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/of_device.h>
17#include <linux/pm.h> 19#include <linux/pm.h>
18#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
19#include <linux/regmap.h> 21#include <linux/regmap.h>
@@ -23,12 +25,19 @@
23 25
24static int wm831x_spi_probe(struct spi_device *spi) 26static int wm831x_spi_probe(struct spi_device *spi)
25{ 27{
28 struct wm831x_pdata *pdata = dev_get_platdata(&spi->dev);
26 const struct spi_device_id *id = spi_get_device_id(spi); 29 const struct spi_device_id *id = spi_get_device_id(spi);
30 const struct of_device_id *of_id;
27 struct wm831x *wm831x; 31 struct wm831x *wm831x;
28 enum wm831x_parent type; 32 enum wm831x_parent type;
29 int ret; 33 int ret;
30 34
31 type = (enum wm831x_parent)id->driver_data; 35 if (spi->dev.of_node) {
36 of_id = of_match_device(wm831x_of_match, &spi->dev);
37 type = (enum wm831x_parent)of_id->data;
38 } else {
39 type = (enum wm831x_parent)id->driver_data;
40 }
32 41
33 wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL); 42 wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL);
34 if (wm831x == NULL) 43 if (wm831x == NULL)
@@ -38,6 +47,7 @@ static int wm831x_spi_probe(struct spi_device *spi)
38 47
39 spi_set_drvdata(spi, wm831x); 48 spi_set_drvdata(spi, wm831x);
40 wm831x->dev = &spi->dev; 49 wm831x->dev = &spi->dev;
50 wm831x->type = type;
41 51
42 wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config); 52 wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config);
43 if (IS_ERR(wm831x->regmap)) { 53 if (IS_ERR(wm831x->regmap)) {
@@ -47,7 +57,10 @@ static int wm831x_spi_probe(struct spi_device *spi)
47 return ret; 57 return ret;
48 } 58 }
49 59
50 return wm831x_device_init(wm831x, type, spi->irq); 60 if (pdata)
61 memcpy(&wm831x->pdata, pdata, sizeof(*pdata));
62
63 return wm831x_device_init(wm831x, spi->irq);
51} 64}
52 65
53static int wm831x_spi_remove(struct spi_device *spi) 66static int wm831x_spi_remove(struct spi_device *spi)
@@ -97,6 +110,7 @@ static struct spi_driver wm831x_spi_driver = {
97 .driver = { 110 .driver = {
98 .name = "wm831x", 111 .name = "wm831x",
99 .pm = &wm831x_spi_pm, 112 .pm = &wm831x_spi_pm,
113 .of_match_table = of_match_ptr(wm831x_of_match),
100 }, 114 },
101 .id_table = wm831x_spi_ids, 115 .id_table = wm831x_spi_ids,
102 .probe = wm831x_spi_probe, 116 .probe = wm831x_spi_probe,
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 76c22648436f..b49fa67612f1 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -21,6 +21,8 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/regmap.h> 22#include <linux/regmap.h>
23#include <linux/mfd/wm831x/auxadc.h> 23#include <linux/mfd/wm831x/auxadc.h>
24#include <linux/mfd/wm831x/pdata.h>
25#include <linux/of.h>
24 26
25/* 27/*
26 * Register values. 28 * Register values.
@@ -367,6 +369,9 @@ struct wm831x {
367 369
368 struct regmap *regmap; 370 struct regmap *regmap;
369 371
372 struct wm831x_pdata pdata;
373 enum wm831x_parent type;
374
370 int irq; /* Our chip IRQ */ 375 int irq; /* Our chip IRQ */
371 struct mutex irq_lock; 376 struct mutex irq_lock;
372 struct irq_domain *irq_domain; 377 struct irq_domain *irq_domain;
@@ -412,7 +417,7 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
412int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg, 417int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
413 int count, u16 *buf); 418 int count, u16 *buf);
414 419
415int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq); 420int wm831x_device_init(struct wm831x *wm831x, int irq);
416void wm831x_device_exit(struct wm831x *wm831x); 421void wm831x_device_exit(struct wm831x *wm831x);
417int wm831x_device_suspend(struct wm831x *wm831x); 422int wm831x_device_suspend(struct wm831x *wm831x);
418void wm831x_device_shutdown(struct wm831x *wm831x); 423void wm831x_device_shutdown(struct wm831x *wm831x);
@@ -427,4 +432,6 @@ static inline int wm831x_irq(struct wm831x *wm831x, int irq)
427 432
428extern struct regmap_config wm831x_regmap_config; 433extern struct regmap_config wm831x_regmap_config;
429 434
435extern const struct of_device_id wm831x_of_match[];
436
430#endif 437#endif