#define PFUZE100_STANDBY_OFFSET 1
#define PFUZE100_MODE_OFFSET 3
#define PFUZE100_CONF_OFFSET 4
+/*
+ * below regs will lost after exit from LPSR mode(PFUZE3000), need to be saved
+ * and restored:
+ * 0x20~0x40: 33
+ * 0x66~0x71: 12
+ * 0x7f: 1
+ * total 46 registers.
+ */
+#define PFUZE100_REG_SAVED_NUM (33 + 12 + 1)
#define PFUZE100_DEVICEID 0x0
#define PFUZE100_REVID 0x3
int chip_id;
struct regmap *regmap;
struct device *dev;
+ bool need_restore;
+ unsigned int reg_save_array[PFUZE100_REG_SAVED_NUM];
struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
struct regulator_dev *regulators[PFUZE100_MAX_REGULATOR];
struct pfuze_regulator *pfuze_regulators;
}
}
+
+ if (of_get_property(client->dev.of_node, "fsl,lpsr-mode", NULL))
+ pfuze_chip->need_restore = true;
+
return 0;
}
+static int pfuze_reg_save_restore(struct pfuze_chip *pfuze_chip, int start,
+ int end, int index, bool save)
+{
+ int i, ret;
+
+ for (i = 0; i < end - start + 1; i++) {
+ if (save)
+ ret = regmap_read(pfuze_chip->regmap, start + i,
+ &pfuze_chip->reg_save_array[index + i]);
+ else
+ ret = regmap_write(pfuze_chip->regmap, start + i,
+ pfuze_chip->reg_save_array[index + i]);
+
+ if (ret)
+ return ret;
+ }
+
+ return index + i;
+}
+
+static int pfuze_suspend(struct device *dev)
+{
+ struct pfuze_chip *pfuze_chip = i2c_get_clientdata(to_i2c_client(dev));
+ int index = 0;
+
+ if (pfuze_chip->need_restore) {
+ /* 0x20~0x40 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x20, 0x40, index, true);
+ if (index < 0)
+ goto err_ret;
+ /* 0x66~0x71 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x66, 0x71, ++index, true);
+ if (index < 0)
+ goto err_ret;
+ /* 0x7f */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x7f, 0x7f, ++index, true);
+ if (index < 0)
+ goto err_ret;
+ }
+
+ return 0;
+
+err_ret:
+ return index;
+}
+
+static int pfuze_resume(struct device *dev)
+{
+ struct pfuze_chip *pfuze_chip = i2c_get_clientdata(to_i2c_client(dev));
+ int index = 0;
+
+ if (pfuze_chip->need_restore) {
+ /* 0x20~0x40 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x20, 0x40, index, false);
+ if (index < 0)
+ goto err_ret;
+ /* 0x66~0x71 */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x66, 0x71, ++index, false);
+ if (index < 0)
+ goto err_ret;
+ /* 0x7f */
+ index = pfuze_reg_save_restore(pfuze_chip, 0x7f, 0x7f, ++index, false);
+ if (index < 0)
+ goto err_ret;
+ }
+
+ return 0;
+
+err_ret:
+ return index;
+}
+
+static const struct dev_pm_ops pfuze_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pfuze_suspend, pfuze_resume)
+};
+
static struct i2c_driver pfuze_driver = {
.id_table = pfuze_device_id,
.driver = {
.name = "pfuze100-regulator",
.of_match_table = pfuze_dt_ids,
+ .pm = &pfuze_pm_ops,
},
.probe = pfuze100_regulator_probe,
};