#include <linux/regmap.h>
 #include <linux/slab.h>
 
+/* Under primary I2C address: */
+#define BCM590XX_REG_PMUID             0x1e
+
+#define BCM590XX_REG_PMUREV            0x1f
+#define BCM590XX_PMUREV_DIG_MASK       0xF
+#define BCM590XX_PMUREV_DIG_SHIFT      0
+#define BCM590XX_PMUREV_ANA_MASK       0xF0
+#define BCM590XX_PMUREV_ANA_SHIFT      4
+
 static const struct mfd_cell bcm590xx_devs[] = {
        {
                .name = "bcm590xx-vregs",
        .cache_type     = REGCACHE_MAPLE,
 };
 
+/* Map PMU ID value to model name string */
+static const char * const bcm590xx_names[] = {
+       [BCM590XX_PMUID_BCM59054] = "BCM59054",
+       [BCM590XX_PMUID_BCM59056] = "BCM59056",
+};
+
+static int bcm590xx_parse_version(struct bcm590xx *bcm590xx)
+{
+       unsigned int id, rev;
+       int ret;
+
+       /* Get PMU ID and verify that it matches compatible */
+       ret = regmap_read(bcm590xx->regmap_pri, BCM590XX_REG_PMUID, &id);
+       if (ret) {
+               dev_err(bcm590xx->dev, "failed to read PMU ID: %d\n", ret);
+               return ret;
+       }
+
+       if (id != bcm590xx->pmu_id) {
+               dev_err(bcm590xx->dev, "Incorrect ID for %s: expected %x, got %x.\n",
+                       bcm590xx_names[bcm590xx->pmu_id], bcm590xx->pmu_id, id);
+               return -ENODEV;
+       }
+
+       /* Get PMU revision and store it in the info struct */
+       ret = regmap_read(bcm590xx->regmap_pri, BCM590XX_REG_PMUREV, &rev);
+       if (ret) {
+               dev_err(bcm590xx->dev, "failed to read PMU revision: %d\n", ret);
+               return ret;
+       }
+
+       bcm590xx->rev_digital = (rev & BCM590XX_PMUREV_DIG_MASK) >> BCM590XX_PMUREV_DIG_SHIFT;
+
+       bcm590xx->rev_analog = (rev & BCM590XX_PMUREV_ANA_MASK) >> BCM590XX_PMUREV_ANA_SHIFT;
+
+       dev_dbg(bcm590xx->dev, "PMU ID 0x%x (%s), revision: digital %d, analog %d",
+                id, bcm590xx_names[id], bcm590xx->rev_digital, bcm590xx->rev_analog);
+
+       return 0;
+}
+
 static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
 {
        struct bcm590xx *bcm590xx;
                goto err;
        }
 
+       ret = bcm590xx_parse_version(bcm590xx);
+       if (ret)
+               goto err;
+
        ret = devm_mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
                                   ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
        if (ret < 0) {
 
 #define BCM590XX_PMUID_BCM59054                0x54
 #define BCM590XX_PMUID_BCM59056                0x56
 
+/* Known chip revision IDs */
+#define BCM59054_REV_DIGITAL_A1                1
+#define BCM59054_REV_ANALOG_A1         2
+
+#define BCM59056_REV_DIGITAL_A0                1
+#define BCM59056_REV_ANALOG_A0         1
+
+#define BCM59056_REV_DIGITAL_B0                2
+#define BCM59056_REV_ANALOG_B0         2
+
 /* max register address */
 #define BCM590XX_MAX_REGISTER_PRI      0xe7
 #define BCM590XX_MAX_REGISTER_SEC      0xf0
 
        /* PMU ID value; also used as device type */
        u8 pmu_id;
+
+       /* Chip revision, read from PMUREV reg */
+       u8 rev_digital;
+       u8 rev_analog;
 };
 
 #endif /*  __LINUX_MFD_BCM590XX_H */