0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/mfd/rohm-generic.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/regulator/driver.h>
0017
0018 #include <linux/mfd/bd9571mwv.h>
0019
0020 struct bd9571mwv_reg {
0021 struct regmap *regmap;
0022
0023
0024 u8 bkup_mode_cnt_keepon;
0025 u8 bkup_mode_cnt_saved;
0026 bool bkup_mode_enabled;
0027
0028
0029 bool rstbmode_level;
0030 bool rstbmode_pulse;
0031 };
0032
0033 enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS };
0034
0035 #define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\
0036 { \
0037 .name = _name, \
0038 .of_match = of_match_ptr(_of), \
0039 .regulators_node = "regulators", \
0040 .id = _id, \
0041 .ops = &_ops, \
0042 .n_voltages = _nv, \
0043 .type = REGULATOR_VOLTAGE, \
0044 .owner = THIS_MODULE, \
0045 .vsel_reg = _vr, \
0046 .vsel_mask = _vm, \
0047 .min_uV = _min, \
0048 .uV_step = _step, \
0049 .linear_min_sel = _lmin, \
0050 }
0051
0052 static int bd9571mwv_avs_get_moni_state(struct regulator_dev *rdev)
0053 {
0054 unsigned int val;
0055 int ret;
0056
0057 ret = regmap_read(rdev->regmap, BD9571MWV_AVS_SET_MONI, &val);
0058 if (ret != 0)
0059 return ret;
0060
0061 return val & BD9571MWV_AVS_SET_MONI_MASK;
0062 }
0063
0064 static int bd9571mwv_avs_set_voltage_sel_regmap(struct regulator_dev *rdev,
0065 unsigned int sel)
0066 {
0067 int ret;
0068
0069 ret = bd9571mwv_avs_get_moni_state(rdev);
0070 if (ret < 0)
0071 return ret;
0072
0073 return regmap_write_bits(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret),
0074 rdev->desc->vsel_mask, sel);
0075 }
0076
0077 static int bd9571mwv_avs_get_voltage_sel_regmap(struct regulator_dev *rdev)
0078 {
0079 unsigned int val;
0080 int ret;
0081
0082 ret = bd9571mwv_avs_get_moni_state(rdev);
0083 if (ret < 0)
0084 return ret;
0085
0086 ret = regmap_read(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), &val);
0087 if (ret != 0)
0088 return ret;
0089
0090 val &= rdev->desc->vsel_mask;
0091 val >>= ffs(rdev->desc->vsel_mask) - 1;
0092
0093 return val;
0094 }
0095
0096 static int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev,
0097 unsigned int sel)
0098 {
0099 return regmap_write_bits(rdev->regmap, BD9571MWV_DVFS_SETVID,
0100 rdev->desc->vsel_mask, sel);
0101 }
0102
0103
0104 static const struct regulator_ops avs_ops = {
0105 .set_voltage_sel = bd9571mwv_avs_set_voltage_sel_regmap,
0106 .map_voltage = regulator_map_voltage_linear,
0107 .get_voltage_sel = bd9571mwv_avs_get_voltage_sel_regmap,
0108 .list_voltage = regulator_list_voltage_linear,
0109 };
0110
0111
0112 static const struct regulator_ops reg_ops = {
0113 .set_voltage_sel = bd9571mwv_reg_set_voltage_sel_regmap,
0114 .map_voltage = regulator_map_voltage_linear,
0115 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0116 .list_voltage = regulator_list_voltage_linear,
0117 };
0118
0119
0120 static const struct regulator_ops vid_ops = {
0121 .map_voltage = regulator_map_voltage_linear,
0122 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0123 .list_voltage = regulator_list_voltage_linear,
0124 };
0125
0126 static const struct regulator_desc regulators[] = {
0127 BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f,
0128 0x6f, 600000, 10000, 0x3c),
0129 BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf,
0130 16, 1625000, 25000, 0),
0131 BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf,
0132 16, 2150000, 50000, 0),
0133 BD9571MWV_REG("VD33", "vd33", VD33, vid_ops, BD9571MWV_VD33_VID, 0xf,
0134 11, 2800000, 100000, 0),
0135 BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops,
0136 BD9571MWV_DVFS_MONIVDAC, 0x7f,
0137 0x6f, 600000, 10000, 0x3c),
0138 };
0139
0140 #ifdef CONFIG_PM_SLEEP
0141 static int bd9571mwv_bkup_mode_read(struct bd9571mwv_reg *bdreg,
0142 unsigned int *mode)
0143 {
0144 int ret;
0145
0146 ret = regmap_read(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
0147 if (ret) {
0148 dev_err(regmap_get_device(bdreg->regmap),
0149 "failed to read backup mode (%d)\n", ret);
0150 return ret;
0151 }
0152
0153 return 0;
0154 }
0155
0156 static int bd9571mwv_bkup_mode_write(struct bd9571mwv_reg *bdreg,
0157 unsigned int mode)
0158 {
0159 int ret;
0160
0161 ret = regmap_write(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
0162 if (ret) {
0163 dev_err(regmap_get_device(bdreg->regmap),
0164 "failed to configure backup mode 0x%x (%d)\n",
0165 mode, ret);
0166 return ret;
0167 }
0168
0169 return 0;
0170 }
0171
0172 static ssize_t backup_mode_show(struct device *dev,
0173 struct device_attribute *attr, char *buf)
0174 {
0175 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
0176
0177 return sysfs_emit(buf, "%s\n", bdreg->bkup_mode_enabled ? "on" : "off");
0178 }
0179
0180 static ssize_t backup_mode_store(struct device *dev,
0181 struct device_attribute *attr,
0182 const char *buf, size_t count)
0183 {
0184 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
0185 unsigned int mode;
0186 int ret;
0187
0188 if (!count)
0189 return 0;
0190
0191 ret = kstrtobool(buf, &bdreg->bkup_mode_enabled);
0192 if (ret)
0193 return ret;
0194
0195 if (!bdreg->rstbmode_level)
0196 return count;
0197
0198
0199
0200
0201
0202 ret = bd9571mwv_bkup_mode_read(bdreg, &mode);
0203 if (ret)
0204 return ret;
0205
0206 mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
0207 if (bdreg->bkup_mode_enabled)
0208 mode |= bdreg->bkup_mode_cnt_keepon;
0209
0210 ret = bd9571mwv_bkup_mode_write(bdreg, mode);
0211 if (ret)
0212 return ret;
0213
0214 return count;
0215 }
0216
0217 static DEVICE_ATTR_RW(backup_mode);
0218
0219 static int bd9571mwv_suspend(struct device *dev)
0220 {
0221 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
0222 unsigned int mode;
0223 int ret;
0224
0225 if (!bdreg->bkup_mode_enabled)
0226 return 0;
0227
0228
0229 ret = bd9571mwv_bkup_mode_read(bdreg, &mode);
0230 if (ret)
0231 return ret;
0232
0233 bdreg->bkup_mode_cnt_saved = mode;
0234
0235 if (!bdreg->rstbmode_pulse)
0236 return 0;
0237
0238
0239 mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
0240 mode |= bdreg->bkup_mode_cnt_keepon;
0241
0242 if (mode != bdreg->bkup_mode_cnt_saved)
0243 return bd9571mwv_bkup_mode_write(bdreg, mode);
0244
0245 return 0;
0246 }
0247
0248 static int bd9571mwv_resume(struct device *dev)
0249 {
0250 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
0251
0252 if (!bdreg->bkup_mode_enabled)
0253 return 0;
0254
0255
0256 return bd9571mwv_bkup_mode_write(bdreg, bdreg->bkup_mode_cnt_saved);
0257 }
0258
0259 static const struct dev_pm_ops bd9571mwv_pm = {
0260 SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
0261 };
0262
0263 static int bd9571mwv_regulator_remove(struct platform_device *pdev)
0264 {
0265 device_remove_file(&pdev->dev, &dev_attr_backup_mode);
0266 return 0;
0267 }
0268 #define DEV_PM_OPS &bd9571mwv_pm
0269 #else
0270 #define DEV_PM_OPS NULL
0271 #define bd9571mwv_regulator_remove NULL
0272 #endif
0273
0274 static int bd9571mwv_regulator_probe(struct platform_device *pdev)
0275 {
0276 struct regulator_config config = { };
0277 struct bd9571mwv_reg *bdreg;
0278 struct regulator_dev *rdev;
0279 unsigned int val;
0280 int i;
0281 enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
0282
0283 bdreg = devm_kzalloc(&pdev->dev, sizeof(*bdreg), GFP_KERNEL);
0284 if (!bdreg)
0285 return -ENOMEM;
0286
0287 bdreg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0288
0289 platform_set_drvdata(pdev, bdreg);
0290
0291 config.dev = &pdev->dev;
0292 config.dev->of_node = pdev->dev.parent->of_node;
0293 config.driver_data = bdreg;
0294 config.regmap = bdreg->regmap;
0295
0296 for (i = 0; i < ARRAY_SIZE(regulators); i++) {
0297
0298 if (chip == ROHM_CHIP_TYPE_BD9574 && regulators[i].id != DVFS)
0299 continue;
0300 rdev = devm_regulator_register(&pdev->dev, ®ulators[i],
0301 &config);
0302 if (IS_ERR(rdev)) {
0303 dev_err(&pdev->dev, "failed to register %s regulator\n",
0304 regulators[i].name);
0305 return PTR_ERR(rdev);
0306 }
0307 }
0308
0309 val = 0;
0310 of_property_read_u32(config.dev->of_node, "rohm,ddr-backup-power", &val);
0311 if (val & ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK) {
0312 dev_err(&pdev->dev, "invalid %s mode %u\n",
0313 "rohm,ddr-backup-power", val);
0314 return -EINVAL;
0315 }
0316 bdreg->bkup_mode_cnt_keepon = val;
0317
0318 bdreg->rstbmode_level = of_property_read_bool(config.dev->of_node,
0319 "rohm,rstbmode-level");
0320 bdreg->rstbmode_pulse = of_property_read_bool(config.dev->of_node,
0321 "rohm,rstbmode-pulse");
0322 if (bdreg->rstbmode_level && bdreg->rstbmode_pulse) {
0323 dev_err(&pdev->dev, "only one rohm,rstbmode-* may be specified");
0324 return -EINVAL;
0325 }
0326
0327 #ifdef CONFIG_PM_SLEEP
0328 if (bdreg->bkup_mode_cnt_keepon) {
0329 int ret;
0330
0331
0332
0333
0334
0335 bdreg->bkup_mode_enabled = bdreg->rstbmode_pulse;
0336
0337 ret = device_create_file(&pdev->dev, &dev_attr_backup_mode);
0338 if (ret)
0339 return ret;
0340 }
0341 #endif
0342
0343 return 0;
0344 }
0345
0346 static const struct platform_device_id bd9571mwv_regulator_id_table[] = {
0347 { "bd9571mwv-regulator", ROHM_CHIP_TYPE_BD9571 },
0348 { "bd9574mwf-regulator", ROHM_CHIP_TYPE_BD9574 },
0349 { }
0350 };
0351 MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table);
0352
0353 static struct platform_driver bd9571mwv_regulator_driver = {
0354 .driver = {
0355 .name = "bd9571mwv-regulator",
0356 .pm = DEV_PM_OPS,
0357 },
0358 .probe = bd9571mwv_regulator_probe,
0359 .remove = bd9571mwv_regulator_remove,
0360 .id_table = bd9571mwv_regulator_id_table,
0361 };
0362 module_platform_driver(bd9571mwv_regulator_driver);
0363
0364 MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
0365 MODULE_DESCRIPTION("BD9571MWV Regulator driver");
0366 MODULE_LICENSE("GPL v2");