bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C"
        select MFD_CORE
        select MFD_WM831X
+       select REGMAP_I2C
        depends on I2C=y && GENERIC_HARDIRQS
        help
          Support for the Wolfson Microelecronics WM831x and WM832x PMICs
        bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI"
        select MFD_CORE
        select MFD_WM831X
+       select REGMAP_SPI
        depends on SPI_MASTER && GENERIC_HARDIRQS
        help
          Support for the Wolfson Microelecronics WM831x and WM832x PMICs
 
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
 }
 EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
 
-static int wm831x_read(struct wm831x *wm831x, unsigned short reg,
-                      int bytes, void *dest)
-{
-       int ret, i;
-       u16 *buf = dest;
-
-       BUG_ON(bytes % 2);
-       BUG_ON(bytes <= 0);
-
-       ret = wm831x->read_dev(wm831x, reg, bytes, dest);
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < bytes / 2; i++) {
-               buf[i] = be16_to_cpu(buf[i]);
-
-               dev_vdbg(wm831x->dev, "Read %04x from R%d(0x%x)\n",
-                        buf[i], reg + i, reg + i);
-       }
-
-       return 0;
-}
-
 /**
  * wm831x_reg_read: Read a single WM831x register.
  *
  */
 int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
 {
-       unsigned short val;
+       unsigned int val;
        int ret;
 
-       mutex_lock(&wm831x->io_lock);
-
-       ret = wm831x_read(wm831x, reg, 2, &val);
-
-       mutex_unlock(&wm831x->io_lock);
+       ret = regmap_read(wm831x->regmap, reg, &val);
 
        if (ret < 0)
                return ret;
 int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
                     int count, u16 *buf)
 {
-       int ret;
-
-       mutex_lock(&wm831x->io_lock);
-
-       ret = wm831x_read(wm831x, reg, count * 2, buf);
-
-       mutex_unlock(&wm831x->io_lock);
-
-       return ret;
+       return regmap_bulk_read(wm831x->regmap, reg, buf, count);
 }
 EXPORT_SYMBOL_GPL(wm831x_bulk_read);
 
                        int bytes, void *src)
 {
        u16 *buf = src;
-       int i;
+       int i, ret;
 
        BUG_ON(bytes % 2);
        BUG_ON(bytes <= 0);
 
                dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
                         buf[i], reg + i, reg + i);
-
-               buf[i] = cpu_to_be16(buf[i]);
+               ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
        }
 
-       return wm831x->write_dev(wm831x, reg, bytes, src);
+       return 0;
 }
 
 /**
                    unsigned short mask, unsigned short val)
 {
        int ret;
-       u16 r;
 
        mutex_lock(&wm831x->io_lock);
 
-       ret = wm831x_read(wm831x, reg, 2, &r);
-       if (ret < 0)
-               goto out;
-
-       r &= ~mask;
-       r |= val & mask;
-
-       ret = wm831x_write(wm831x, reg, 2, &r);
+       if (!wm831x_reg_locked(wm831x, reg))
+               ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
+       else
+               ret = -EPERM;
 
-out:
        mutex_unlock(&wm831x->io_lock);
 
        return ret;
        },
 };
 
+struct regmap_config wm831x_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 16,
+};
+EXPORT_SYMBOL_GPL(wm831x_regmap_config);
+
 /*
  * Instantiate the generic non-control parts of the device.
  */
        ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
        switch (ret) {
        case 0x6204:
        default:
                dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
                ret = -EINVAL;
-               goto err;
+               goto err_regmap;
        }
 
        ret = wm831x_reg_read(wm831x, WM831X_REVISION);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
        rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
 
        ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
 
        /* Some engineering samples do not have the ID set, rely on
        default:
                dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
                ret = -EINVAL;
-               goto err;
+               goto err_regmap;
        }
 
        /* This will need revisiting in future but is OK for all
        ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
        if (ret != 0) {
                dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
                ret = pdata->pre_init(wm831x);
                if (ret != 0) {
                        dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
-                       goto err;
+                       goto err_regmap;
                }
        }
 
 
        ret = wm831x_irq_init(wm831x, irq);
        if (ret != 0)
-               goto err;
+               goto err_regmap;
 
        wm831x_auxadc_init(wm831x);
 
 
 err_irq:
        wm831x_irq_exit(wm831x);
-err:
+err_regmap:
        mfd_remove_devices(wm831x->dev);
+       regmap_exit(wm831x->regmap);
        kfree(wm831x);
        return ret;
 }
        if (wm831x->irq_base)
                free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
        wm831x_irq_exit(wm831x);
+       regmap_exit(wm831x->regmap);
        kfree(wm831x);
 }
 
 
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/regmap.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
 
-static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
-                                 int bytes, void *dest)
-{
-       struct i2c_client *i2c = wm831x->control_data;
-       int ret;
-       u16 r = cpu_to_be16(reg);
-
-       ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
-       if (ret < 0)
-               return ret;
-       if (ret != 2)
-               return -EIO;
-
-       ret = i2c_master_recv(i2c, dest, bytes);
-       if (ret < 0)
-               return ret;
-       if (ret != bytes)
-               return -EIO;
-       return 0;
-}
-
-/* Currently we allocate the write buffer on the stack; this is OK for
- * small writes - if we need to do large writes this will need to be
- * revised.
- */
-static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
-                                  int bytes, void *src)
-{
-       struct i2c_client *i2c = wm831x->control_data;
-       struct i2c_msg xfer[2];
-       int ret;
-
-       reg = cpu_to_be16(reg);
-
-       xfer[0].addr = i2c->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = 2;
-       xfer[0].buf = (char *)®
-
-       xfer[1].addr = i2c->addr;
-       xfer[1].flags = I2C_M_NOSTART;
-       xfer[1].len = bytes;
-       xfer[1].buf = (char *)src;
-
-       ret = i2c_transfer(i2c->adapter, xfer, 2);
-       if (ret < 0)
-               return ret;
-       if (ret != 2)
-               return -EIO;
-
-       return 0;
-}
-
 static int wm831x_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm831x *wm831x;
+       int ret;
 
        wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
        if (wm831x == NULL)
 
        i2c_set_clientdata(i2c, wm831x);
        wm831x->dev = &i2c->dev;
-       wm831x->control_data = i2c;
-       wm831x->read_dev = wm831x_i2c_read_device;
-       wm831x->write_dev = wm831x_i2c_write_device;
+
+       wm831x->regmap = regmap_init_i2c(i2c, &wm831x_regmap_config);
+       if (IS_ERR(wm831x->regmap)) {
+               ret = PTR_ERR(wm831x->regmap);
+               dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               kfree(wm831x);
+               return ret;
+       }
 
        return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
 }
 
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
 
 #include <linux/mfd/wm831x/core.h>
 
-static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
-                                 int bytes, void *dest)
-{
-       u16 tx_val;
-       u16 *d = dest;
-       int r, ret;
-
-       /* Go register at a time */
-       for (r = reg; r < reg + (bytes / 2); r++) {
-               tx_val = r | 0x8000;
-
-               ret = spi_write_then_read(wm831x->control_data,
-                                         (u8 *)&tx_val, 2, (u8 *)d, 2);
-               if (ret != 0)
-                       return ret;
-
-               *d = be16_to_cpu(*d);
-
-               d++;
-       }
-
-       return 0;
-}
-
-static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
-                                  int bytes, void *src)
-{
-       struct spi_device *spi = wm831x->control_data;
-       u16 *s = src;
-       u16 data[2];
-       int ret, r;
-
-       /* Go register at a time */
-       for (r = reg; r < reg + (bytes / 2); r++) {
-               data[0] = r;
-               data[1] = *s++;
-
-               ret = spi_write(spi, (char *)&data, sizeof(data));
-               if (ret != 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
 static int __devinit wm831x_spi_probe(struct spi_device *spi)
 {
        struct wm831x *wm831x;
        enum wm831x_parent type;
+       int ret;
 
        /* Currently SPI support for ID tables is unmerged, we're faking it */
        if (strcmp(spi->modalias, "wm8310") == 0)
 
        dev_set_drvdata(&spi->dev, wm831x);
        wm831x->dev = &spi->dev;
-       wm831x->control_data = spi;
-       wm831x->read_dev = wm831x_spi_read_device;
-       wm831x->write_dev = wm831x_spi_write_device;
+
+       wm831x->regmap = regmap_init_spi(wm831x->dev, &wm831x_regmap_config);
+       if (IS_ERR(wm831x->regmap)) {
+               ret = PTR_ERR(wm831x->regmap);
+               dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               kfree(wm831x);
+               return ret;
+       }
 
        return wm831x_device_init(wm831x, type, spi->irq);
 }
 
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/regmap.h>
 
 /*
  * Register values.
        struct mutex io_lock;
 
        struct device *dev;
-       int (*read_dev)(struct wm831x *wm831x, unsigned short reg,
-                       int bytes, void *dest);
-       int (*write_dev)(struct wm831x *wm831x, unsigned short reg,
-                        int bytes, void *src);
 
-       void *control_data;
+       struct regmap *regmap;
 
        int irq;  /* Our chip IRQ */
        struct mutex irq_lock;
 void wm831x_irq_exit(struct wm831x *wm831x);
 void wm831x_auxadc_init(struct wm831x *wm831x);
 
+extern struct regmap_config wm831x_regmap_config;
+
 #endif