#include <linux/mfd/core.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
 };
 EXPORT_SYMBOL_GPL(wm831x_regmap_config);
 
+const struct of_device_id wm831x_of_match[] = {
+       { .compatible = "wlf,wm8310", .data = (void *)WM8310 },
+       { .compatible = "wlf,wm8311", .data = (void *)WM8311 },
+       { .compatible = "wlf,wm8312", .data = (void *)WM8312 },
+       { .compatible = "wlf,wm8320", .data = (void *)WM8320 },
+       { .compatible = "wlf,wm8321", .data = (void *)WM8321 },
+       { .compatible = "wlf,wm8325", .data = (void *)WM8325 },
+       { .compatible = "wlf,wm8326", .data = (void *)WM8326 },
+       { },
+};
+EXPORT_SYMBOL_GPL(wm831x_of_match);
+
 /*
  * Instantiate the generic non-control parts of the device.
  */
-int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
+int wm831x_device_init(struct wm831x *wm831x, int irq)
 {
-       struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
+       struct wm831x_pdata *pdata = &wm831x->pdata;
        int rev, wm831x_num;
        enum wm831x_parent parent;
        int ret, i;
        mutex_init(&wm831x->key_lock);
        dev_set_drvdata(wm831x->dev, wm831x);
 
-       if (pdata)
-               wm831x->soft_shutdown = pdata->soft_shutdown;
+       wm831x->soft_shutdown = pdata->soft_shutdown;
 
        ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
        if (ret < 0) {
         */
        if (ret == 0) {
                dev_info(wm831x->dev, "Device is an engineering sample\n");
-               ret = id;
+               ret = wm831x->type;
        }
 
        switch (ret) {
        /* This will need revisiting in future but is OK for all
         * current parts.
         */
-       if (parent != id)
-               dev_warn(wm831x->dev, "Device was registered as a WM%lx\n",
-                        id);
+       if (parent != wm831x->type)
+               dev_warn(wm831x->dev, "Device was registered as a WM%x\n",
+                        wm831x->type);
 
        /* Bootstrap the user key */
        ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
 
 #include <linux/mfd/core.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/regmap.h>
 
 #include <linux/mfd/wm831x/core.h>
 static int wm831x_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
+       struct wm831x_pdata *pdata = dev_get_platdata(&i2c->dev);
+       const struct of_device_id *of_id;
        struct wm831x *wm831x;
+       enum wm831x_parent type;
        int ret;
 
+       if (i2c->dev.of_node) {
+               of_id = of_match_device(wm831x_of_match, &i2c->dev);
+               type = (enum wm831x_parent)of_id->data;
+       } else {
+               type = (enum wm831x_parent)id->driver_data;
+       }
+
        wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL);
        if (wm831x == NULL)
                return -ENOMEM;
 
        i2c_set_clientdata(i2c, wm831x);
        wm831x->dev = &i2c->dev;
+       wm831x->type = type;
 
        wm831x->regmap = devm_regmap_init_i2c(i2c, &wm831x_regmap_config);
        if (IS_ERR(wm831x->regmap)) {
                return ret;
        }
 
-       return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
+       if (pdata)
+               memcpy(&wm831x->pdata, pdata, sizeof(*pdata));
+
+       return wm831x_device_init(wm831x, i2c->irq);
 }
 
 static int wm831x_i2c_remove(struct i2c_client *i2c)
        .driver = {
                .name = "wm831x",
                .pm = &wm831x_pm_ops,
+               .of_match_table = of_match_ptr(wm831x_of_match),
        },
        .probe = wm831x_i2c_probe,
        .remove = wm831x_i2c_remove,
 
 
 int wm831x_irq_init(struct wm831x *wm831x, int irq)
 {
-       struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
+       struct wm831x_pdata *pdata = &wm831x->pdata;
        struct irq_domain *domain;
        int i, ret, irq_base;
 
        }
 
        /* Try to dynamically allocate IRQs if no base is specified */
-       if (pdata && pdata->irq_base) {
+       if (pdata->irq_base) {
                irq_base = irq_alloc_descs(pdata->irq_base, 0,
                                           WM831X_NUM_IRQS, 0);
                if (irq_base < 0) {
                return -EINVAL;
        }
 
-       if (pdata && pdata->irq_cmos)
+       if (pdata->irq_cmos)
                i = 0;
        else
                i = WM831X_IRQ_OD;
 
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/pm.h>
 #include <linux/spi/spi.h>
 #include <linux/regmap.h>
 
 static int wm831x_spi_probe(struct spi_device *spi)
 {
+       struct wm831x_pdata *pdata = dev_get_platdata(&spi->dev);
        const struct spi_device_id *id = spi_get_device_id(spi);
+       const struct of_device_id *of_id;
        struct wm831x *wm831x;
        enum wm831x_parent type;
        int ret;
 
-       type = (enum wm831x_parent)id->driver_data;
+       if (spi->dev.of_node) {
+               of_id = of_match_device(wm831x_of_match, &spi->dev);
+               type = (enum wm831x_parent)of_id->data;
+       } else {
+               type = (enum wm831x_parent)id->driver_data;
+       }
 
        wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL);
        if (wm831x == NULL)
 
        spi_set_drvdata(spi, wm831x);
        wm831x->dev = &spi->dev;
+       wm831x->type = type;
 
        wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config);
        if (IS_ERR(wm831x->regmap)) {
                return ret;
        }
 
-       return wm831x_device_init(wm831x, type, spi->irq);
+       if (pdata)
+               memcpy(&wm831x->pdata, pdata, sizeof(*pdata));
+
+       return wm831x_device_init(wm831x, spi->irq);
 }
 
 static int wm831x_spi_remove(struct spi_device *spi)
        .driver = {
                .name   = "wm831x",
                .pm     = &wm831x_spi_pm,
+               .of_match_table = of_match_ptr(wm831x_of_match),
        },
        .id_table       = wm831x_spi_ids,
        .probe          = wm831x_spi_probe,
 
 #include <linux/list.h>
 #include <linux/regmap.h>
 #include <linux/mfd/wm831x/auxadc.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/of.h>
 
 /*
  * Register values.
 
        struct regmap *regmap;
 
+       struct wm831x_pdata pdata;
+       enum wm831x_parent type;
+
        int irq;  /* Our chip IRQ */
        struct mutex irq_lock;
        struct irq_domain *irq_domain;
 int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
                     int count, u16 *buf);
 
-int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
+int wm831x_device_init(struct wm831x *wm831x, int irq);
 void wm831x_device_exit(struct wm831x *wm831x);
 int wm831x_device_suspend(struct wm831x *wm831x);
 void wm831x_device_shutdown(struct wm831x *wm831x);
 
 extern struct regmap_config wm831x_regmap_config;
 
+extern const struct of_device_id wm831x_of_match[];
+
 #endif