"SPKVDD2",
 };
 
+static const char *wm8958_main_supplies[] = {
+       "DBVDD1",
+       "DBVDD2",
+       "DBVDD3",
+       "DCVDD",
+       "AVDD1",
+       "AVDD2",
+       "CPVDD",
+       "SPKVDD1",
+       "SPKVDD2",
+};
+
 #ifdef CONFIG_PM
 static int wm8994_device_suspend(struct device *dev)
 {
        if (ret < 0)
                dev_err(dev, "Failed to save LDO registers: %d\n", ret);
 
-       ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+       ret = regulator_bulk_disable(wm8994->num_supplies,
                                     wm8994->supplies);
        if (ret != 0) {
                dev_err(dev, "Failed to disable supplies: %d\n", ret);
        struct wm8994 *wm8994 = dev_get_drvdata(dev);
        int ret;
 
-       ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+       ret = regulator_bulk_enable(wm8994->num_supplies,
                                    wm8994->supplies);
        if (ret != 0) {
                dev_err(dev, "Failed to enable supplies: %d\n", ret);
 /*
  * Instantiate the generic non-control parts of the device.
  */
-static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
+static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 {
        struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+       const char *devname;
        int ret, i;
 
        mutex_init(&wm8994->io_lock);
                goto err;
        }
 
+       switch (wm8994->type) {
+       case WM8994:
+               wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
+               break;
+       case WM8958:
+               wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies);
+               break;
+       default:
+               BUG();
+               return -EINVAL;
+       }
+
        wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
-                                  ARRAY_SIZE(wm8994_main_supplies),
+                                  wm8994->num_supplies,
                                   GFP_KERNEL);
        if (!wm8994->supplies) {
                ret = -ENOMEM;
                goto err;
        }
 
-       for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
-               wm8994->supplies[i].supply = wm8994_main_supplies[i];
-
-       ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies),
+       switch (wm8994->type) {
+       case WM8994:
+               for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
+                       wm8994->supplies[i].supply = wm8994_main_supplies[i];
+               break;
+       case WM8958:
+               for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++)
+                       wm8994->supplies[i].supply = wm8958_main_supplies[i];
+               break;
+       default:
+               BUG();
+               return -EINVAL;
+       }
+               
+       ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
                                 wm8994->supplies);
        if (ret != 0) {
                dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
                goto err_supplies;
        }
 
-       ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+       ret = regulator_bulk_enable(wm8994->num_supplies,
                                    wm8994->supplies);
        if (ret != 0) {
                dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
                dev_err(wm8994->dev, "Failed to read ID register\n");
                goto err_enable;
        }
-       if (ret != 0x8994) {
+       switch (ret) {
+       case 0x8994:
+               devname = "WM8994";
+               if (wm8994->type != WM8994)
+                       dev_warn(wm8994->dev, "Device registered as type %d\n",
+                                wm8994->type);
+               wm8994->type = WM8994;
+               break;
+       case 0x8958:
+               devname = "WM8958";
+               if (wm8994->type != WM8958)
+                       dev_warn(wm8994->dev, "Device registered as type %d\n",
+                                wm8994->type);
+               wm8994->type = WM8958;
+               break;
+       default:
                dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
                        ret);
                ret = -EINVAL;
        switch (ret) {
        case 0:
        case 1:
-               dev_warn(wm8994->dev, "revision %c not fully supported\n",
-                       'A' + ret);
+               if (wm8994->type == WM8994)
+                       dev_warn(wm8994->dev,
+                                "revision %c not fully supported\n",
+                                'A' + ret);
                break;
        default:
-               dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
                break;
        }
 
+       dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret);
 
        if (pdata) {
                wm8994->irq_base = pdata->irq_base;
 err_irq:
        wm8994_irq_exit(wm8994);
 err_enable:
-       regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+       regulator_bulk_disable(wm8994->num_supplies,
                               wm8994->supplies);
 err_get:
-       regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+       regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
 err_supplies:
        kfree(wm8994->supplies);
 err:
 {
        mfd_remove_devices(wm8994->dev);
        wm8994_irq_exit(wm8994);
-       regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+       regulator_bulk_disable(wm8994->num_supplies,
                               wm8994->supplies);
-       regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+       regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
        kfree(wm8994->supplies);
        kfree(wm8994);
 }
        wm8994->read_dev = wm8994_i2c_read_device;
        wm8994->write_dev = wm8994_i2c_write_device;
        wm8994->irq = i2c->irq;
+       wm8994->type = id->driver_data;
 
-       return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
+       return wm8994_device_init(wm8994, i2c->irq);
 }
 
 static int wm8994_i2c_remove(struct i2c_client *i2c)
 #endif
 
 static const struct i2c_device_id wm8994_i2c_id[] = {
-       { "wm8994", 0 },
+       { "wm8994", WM8994 },
+       { "wm8958", WM8958 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);