Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * ROHM BD9571MWV-M and BD9574MWF-M regulator driver
  4 *
  5 * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
  6 *
  7 * Based on the TPS65086 driver
  8 *
  9 * NOTE: VD09 is missing
 10 */
 11
 12#include <linux/mfd/rohm-generic.h>
 13#include <linux/module.h>
 14#include <linux/of.h>
 15#include <linux/platform_device.h>
 16#include <linux/regulator/driver.h>
 17
 18#include <linux/mfd/bd9571mwv.h>
 19
 20struct bd9571mwv_reg {
 21	struct regmap *regmap;
 22
 23	/* DDR Backup Power */
 24	u8 bkup_mode_cnt_keepon;	/* from "rohm,ddr-backup-power" */
 25	u8 bkup_mode_cnt_saved;
 26	bool bkup_mode_enabled;
 27
 28	/* Power switch type */
 29	bool rstbmode_level;
 30	bool rstbmode_pulse;
 31};
 32
 33enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS };
 34
 35#define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\
 36	{							\
 37		.name			= _name,		\
 38		.of_match		= of_match_ptr(_of),	\
 39		.regulators_node	= "regulators",		\
 40		.id			= _id,			\
 41		.ops			= &_ops,		\
 42		.n_voltages		= _nv,			\
 43		.type			= REGULATOR_VOLTAGE,	\
 44		.owner			= THIS_MODULE,		\
 45		.vsel_reg		= _vr,			\
 46		.vsel_mask		= _vm,			\
 47		.min_uV			= _min,			\
 48		.uV_step		= _step,		\
 49		.linear_min_sel		= _lmin,		\
 50	}
 51
 52static int bd9571mwv_avs_get_moni_state(struct regulator_dev *rdev)
 53{
 54	unsigned int val;
 55	int ret;
 56
 57	ret = regmap_read(rdev->regmap, BD9571MWV_AVS_SET_MONI, &val);
 58	if (ret != 0)
 59		return ret;
 60
 61	return val & BD9571MWV_AVS_SET_MONI_MASK;
 62}
 63
 64static int bd9571mwv_avs_set_voltage_sel_regmap(struct regulator_dev *rdev,
 65						unsigned int sel)
 66{
 67	int ret;
 68
 69	ret = bd9571mwv_avs_get_moni_state(rdev);
 70	if (ret < 0)
 71		return ret;
 72
 73	return regmap_write_bits(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret),
 74				 rdev->desc->vsel_mask, sel);
 75}
 76
 77static int bd9571mwv_avs_get_voltage_sel_regmap(struct regulator_dev *rdev)
 78{
 79	unsigned int val;
 80	int ret;
 81
 82	ret = bd9571mwv_avs_get_moni_state(rdev);
 83	if (ret < 0)
 84		return ret;
 85
 86	ret = regmap_read(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), &val);
 87	if (ret != 0)
 88		return ret;
 89
 90	val &= rdev->desc->vsel_mask;
 91	val >>= ffs(rdev->desc->vsel_mask) - 1;
 92
 93	return val;
 94}
 95
 96static int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev,
 97						unsigned int sel)
 98{
 99	return regmap_write_bits(rdev->regmap, BD9571MWV_DVFS_SETVID,
100				 rdev->desc->vsel_mask, sel);
101}
102
103/* Operations permitted on AVS voltage regulator */
104static const struct regulator_ops avs_ops = {
105	.set_voltage_sel	= bd9571mwv_avs_set_voltage_sel_regmap,
106	.map_voltage		= regulator_map_voltage_linear,
107	.get_voltage_sel	= bd9571mwv_avs_get_voltage_sel_regmap,
108	.list_voltage		= regulator_list_voltage_linear,
109};
110
111/* Operations permitted on voltage regulators */
112static const struct regulator_ops reg_ops = {
113	.set_voltage_sel	= bd9571mwv_reg_set_voltage_sel_regmap,
114	.map_voltage		= regulator_map_voltage_linear,
115	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
116	.list_voltage		= regulator_list_voltage_linear,
117};
118
119/* Operations permitted on voltage monitors */
120static const struct regulator_ops vid_ops = {
121	.map_voltage		= regulator_map_voltage_linear,
122	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
123	.list_voltage		= regulator_list_voltage_linear,
124};
125
126static const struct regulator_desc regulators[] = {
127	BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f,
128		      0x6f, 600000, 10000, 0x3c),
129	BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf,
130		      16, 1625000, 25000, 0),
131	BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf,
132		      16, 2150000, 50000, 0),
133	BD9571MWV_REG("VD33", "vd33", VD33, vid_ops, BD9571MWV_VD33_VID, 0xf,
134		      11, 2800000, 100000, 0),
135	BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops,
136		      BD9571MWV_DVFS_MONIVDAC, 0x7f,
137		      0x6f, 600000, 10000, 0x3c),
138};
139
140#ifdef CONFIG_PM_SLEEP
141static int bd9571mwv_bkup_mode_read(struct bd9571mwv_reg *bdreg,
142				    unsigned int *mode)
143{
144	int ret;
145
146	ret = regmap_read(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
147	if (ret) {
148		dev_err(regmap_get_device(bdreg->regmap),
149			"failed to read backup mode (%d)\n", ret);
150		return ret;
151	}
152
153	return 0;
154}
155
156static int bd9571mwv_bkup_mode_write(struct bd9571mwv_reg *bdreg,
157				     unsigned int mode)
158{
159	int ret;
160
161	ret = regmap_write(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
162	if (ret) {
163		dev_err(regmap_get_device(bdreg->regmap),
164			"failed to configure backup mode 0x%x (%d)\n",
165			mode, ret);
166		return ret;
167	}
168
169	return 0;
170}
171
172static ssize_t backup_mode_show(struct device *dev,
173				struct device_attribute *attr, char *buf)
174{
175	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
176
177	return sysfs_emit(buf, "%s\n", bdreg->bkup_mode_enabled ? "on" : "off");
178}
179
180static ssize_t backup_mode_store(struct device *dev,
181				 struct device_attribute *attr,
182				 const char *buf, size_t count)
183{
184	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
185	unsigned int mode;
186	int ret;
187
188	if (!count)
189		return 0;
190
191	ret = kstrtobool(buf, &bdreg->bkup_mode_enabled);
192	if (ret)
193		return ret;
194
195	if (!bdreg->rstbmode_level)
196		return count;
197
198	/*
199	 * Configure DDR Backup Mode, to change the role of the accessory power
200	 * switch from a power switch to a wake-up switch, or vice versa
201	 */
202	ret = bd9571mwv_bkup_mode_read(bdreg, &mode);
203	if (ret)
204		return ret;
205
206	mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
207	if (bdreg->bkup_mode_enabled)
208		mode |= bdreg->bkup_mode_cnt_keepon;
209
210	ret = bd9571mwv_bkup_mode_write(bdreg, mode);
211	if (ret)
212		return ret;
213
214	return count;
215}
216
217static DEVICE_ATTR_RW(backup_mode);
218
219static int bd9571mwv_suspend(struct device *dev)
220{
221	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
222	unsigned int mode;
223	int ret;
224
225	if (!bdreg->bkup_mode_enabled)
226		return 0;
227
228	/* Save DDR Backup Mode */
229	ret = bd9571mwv_bkup_mode_read(bdreg, &mode);
230	if (ret)
231		return ret;
232
233	bdreg->bkup_mode_cnt_saved = mode;
234
235	if (!bdreg->rstbmode_pulse)
236		return 0;
237
238	/* Enable DDR Backup Mode */
239	mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
240	mode |= bdreg->bkup_mode_cnt_keepon;
241
242	if (mode != bdreg->bkup_mode_cnt_saved)
243		return bd9571mwv_bkup_mode_write(bdreg, mode);
244
245	return 0;
246}
247
248static int bd9571mwv_resume(struct device *dev)
249{
250	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
251
252	if (!bdreg->bkup_mode_enabled)
253		return 0;
254
255	/* Restore DDR Backup Mode */
256	return bd9571mwv_bkup_mode_write(bdreg, bdreg->bkup_mode_cnt_saved);
257}
258
259static const struct dev_pm_ops bd9571mwv_pm  = {
260	SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
261};
262
263static int bd9571mwv_regulator_remove(struct platform_device *pdev)
264{
265	device_remove_file(&pdev->dev, &dev_attr_backup_mode);
266	return 0;
267}
268#define DEV_PM_OPS	&bd9571mwv_pm
269#else
270#define DEV_PM_OPS	NULL
271#define bd9571mwv_regulator_remove	NULL
272#endif /* CONFIG_PM_SLEEP */
273
274static int bd9571mwv_regulator_probe(struct platform_device *pdev)
275{
276	struct regulator_config config = { };
277	struct bd9571mwv_reg *bdreg;
278	struct regulator_dev *rdev;
279	unsigned int val;
280	int i;
281	enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
282
283	bdreg = devm_kzalloc(&pdev->dev, sizeof(*bdreg), GFP_KERNEL);
284	if (!bdreg)
285		return -ENOMEM;
286
287	bdreg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
288
289	platform_set_drvdata(pdev, bdreg);
290
291	config.dev = &pdev->dev;
292	config.dev->of_node = pdev->dev.parent->of_node;
293	config.driver_data = bdreg;
294	config.regmap = bdreg->regmap;
295
296	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
297		/* BD9574MWF supports DVFS only */
298		if (chip == ROHM_CHIP_TYPE_BD9574 && regulators[i].id != DVFS)
299			continue;
300		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
301					       &config);
302		if (IS_ERR(rdev)) {
303			dev_err(&pdev->dev, "failed to register %s regulator\n",
304				regulators[i].name);
305			return PTR_ERR(rdev);
306		}
307	}
308
309	val = 0;
310	of_property_read_u32(config.dev->of_node, "rohm,ddr-backup-power", &val);
311	if (val & ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK) {
312		dev_err(&pdev->dev, "invalid %s mode %u\n",
313			"rohm,ddr-backup-power", val);
314		return -EINVAL;
315	}
316	bdreg->bkup_mode_cnt_keepon = val;
317
318	bdreg->rstbmode_level = of_property_read_bool(config.dev->of_node,
319						      "rohm,rstbmode-level");
320	bdreg->rstbmode_pulse = of_property_read_bool(config.dev->of_node,
321						      "rohm,rstbmode-pulse");
322	if (bdreg->rstbmode_level && bdreg->rstbmode_pulse) {
323		dev_err(&pdev->dev, "only one rohm,rstbmode-* may be specified");
324		return -EINVAL;
325	}
326
327#ifdef CONFIG_PM_SLEEP
328	if (bdreg->bkup_mode_cnt_keepon) {
329		int ret;
330
331		/*
332		 * Backup mode is enabled by default in pulse mode, but needs
333		 * explicit user setup in level mode.
334		 */
335		bdreg->bkup_mode_enabled = bdreg->rstbmode_pulse;
336
337		ret = device_create_file(&pdev->dev, &dev_attr_backup_mode);
338		if (ret)
339			return ret;
340	}
341#endif /* CONFIG_PM_SLEEP */
342
343	return 0;
344}
345
346static const struct platform_device_id bd9571mwv_regulator_id_table[] = {
347	{ "bd9571mwv-regulator", ROHM_CHIP_TYPE_BD9571 },
348	{ "bd9574mwf-regulator", ROHM_CHIP_TYPE_BD9574 },
349	{ /* sentinel */ }
350};
351MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table);
352
353static struct platform_driver bd9571mwv_regulator_driver = {
354	.driver = {
355		.name = "bd9571mwv-regulator",
 
356		.pm = DEV_PM_OPS,
357	},
358	.probe = bd9571mwv_regulator_probe,
359	.remove = bd9571mwv_regulator_remove,
360	.id_table = bd9571mwv_regulator_id_table,
361};
362module_platform_driver(bd9571mwv_regulator_driver);
363
364MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
365MODULE_DESCRIPTION("BD9571MWV Regulator driver");
366MODULE_LICENSE("GPL v2");
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * ROHM BD9571MWV-M and BD9574MWF-M regulator driver
  4 *
  5 * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
  6 *
  7 * Based on the TPS65086 driver
  8 *
  9 * NOTE: VD09 is missing
 10 */
 11
 12#include <linux/mfd/rohm-generic.h>
 13#include <linux/module.h>
 14#include <linux/of.h>
 15#include <linux/platform_device.h>
 16#include <linux/regulator/driver.h>
 17
 18#include <linux/mfd/bd9571mwv.h>
 19
 20struct bd9571mwv_reg {
 21	struct regmap *regmap;
 22
 23	/* DDR Backup Power */
 24	u8 bkup_mode_cnt_keepon;	/* from "rohm,ddr-backup-power" */
 25	u8 bkup_mode_cnt_saved;
 26	bool bkup_mode_enabled;
 27
 28	/* Power switch type */
 29	bool rstbmode_level;
 30	bool rstbmode_pulse;
 31};
 32
 33enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS };
 34
 35#define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\
 36	{							\
 37		.name			= _name,		\
 38		.of_match		= of_match_ptr(_of),	\
 39		.regulators_node	= "regulators",		\
 40		.id			= _id,			\
 41		.ops			= &_ops,		\
 42		.n_voltages		= _nv,			\
 43		.type			= REGULATOR_VOLTAGE,	\
 44		.owner			= THIS_MODULE,		\
 45		.vsel_reg		= _vr,			\
 46		.vsel_mask		= _vm,			\
 47		.min_uV			= _min,			\
 48		.uV_step		= _step,		\
 49		.linear_min_sel		= _lmin,		\
 50	}
 51
 52static int bd9571mwv_avs_get_moni_state(struct regulator_dev *rdev)
 53{
 54	unsigned int val;
 55	int ret;
 56
 57	ret = regmap_read(rdev->regmap, BD9571MWV_AVS_SET_MONI, &val);
 58	if (ret != 0)
 59		return ret;
 60
 61	return val & BD9571MWV_AVS_SET_MONI_MASK;
 62}
 63
 64static int bd9571mwv_avs_set_voltage_sel_regmap(struct regulator_dev *rdev,
 65						unsigned int sel)
 66{
 67	int ret;
 68
 69	ret = bd9571mwv_avs_get_moni_state(rdev);
 70	if (ret < 0)
 71		return ret;
 72
 73	return regmap_write_bits(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret),
 74				 rdev->desc->vsel_mask, sel);
 75}
 76
 77static int bd9571mwv_avs_get_voltage_sel_regmap(struct regulator_dev *rdev)
 78{
 79	unsigned int val;
 80	int ret;
 81
 82	ret = bd9571mwv_avs_get_moni_state(rdev);
 83	if (ret < 0)
 84		return ret;
 85
 86	ret = regmap_read(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), &val);
 87	if (ret != 0)
 88		return ret;
 89
 90	val &= rdev->desc->vsel_mask;
 91	val >>= ffs(rdev->desc->vsel_mask) - 1;
 92
 93	return val;
 94}
 95
 96static int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev,
 97						unsigned int sel)
 98{
 99	return regmap_write_bits(rdev->regmap, BD9571MWV_DVFS_SETVID,
100				 rdev->desc->vsel_mask, sel);
101}
102
103/* Operations permitted on AVS voltage regulator */
104static const struct regulator_ops avs_ops = {
105	.set_voltage_sel	= bd9571mwv_avs_set_voltage_sel_regmap,
106	.map_voltage		= regulator_map_voltage_linear,
107	.get_voltage_sel	= bd9571mwv_avs_get_voltage_sel_regmap,
108	.list_voltage		= regulator_list_voltage_linear,
109};
110
111/* Operations permitted on voltage regulators */
112static const struct regulator_ops reg_ops = {
113	.set_voltage_sel	= bd9571mwv_reg_set_voltage_sel_regmap,
114	.map_voltage		= regulator_map_voltage_linear,
115	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
116	.list_voltage		= regulator_list_voltage_linear,
117};
118
119/* Operations permitted on voltage monitors */
120static const struct regulator_ops vid_ops = {
121	.map_voltage		= regulator_map_voltage_linear,
122	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
123	.list_voltage		= regulator_list_voltage_linear,
124};
125
126static const struct regulator_desc regulators[] = {
127	BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f,
128		      0x6f, 600000, 10000, 0x3c),
129	BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf,
130		      16, 1625000, 25000, 0),
131	BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf,
132		      16, 2150000, 50000, 0),
133	BD9571MWV_REG("VD33", "vd33", VD33, vid_ops, BD9571MWV_VD33_VID, 0xf,
134		      11, 2800000, 100000, 0),
135	BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops,
136		      BD9571MWV_DVFS_MONIVDAC, 0x7f,
137		      0x6f, 600000, 10000, 0x3c),
138};
139
140#ifdef CONFIG_PM_SLEEP
141static int bd9571mwv_bkup_mode_read(struct bd9571mwv_reg *bdreg,
142				    unsigned int *mode)
143{
144	int ret;
145
146	ret = regmap_read(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
147	if (ret) {
148		dev_err(regmap_get_device(bdreg->regmap),
149			"failed to read backup mode (%d)\n", ret);
150		return ret;
151	}
152
153	return 0;
154}
155
156static int bd9571mwv_bkup_mode_write(struct bd9571mwv_reg *bdreg,
157				     unsigned int mode)
158{
159	int ret;
160
161	ret = regmap_write(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
162	if (ret) {
163		dev_err(regmap_get_device(bdreg->regmap),
164			"failed to configure backup mode 0x%x (%d)\n",
165			mode, ret);
166		return ret;
167	}
168
169	return 0;
170}
171
172static ssize_t backup_mode_show(struct device *dev,
173				struct device_attribute *attr, char *buf)
174{
175	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
176
177	return sysfs_emit(buf, "%s\n", bdreg->bkup_mode_enabled ? "on" : "off");
178}
179
180static ssize_t backup_mode_store(struct device *dev,
181				 struct device_attribute *attr,
182				 const char *buf, size_t count)
183{
184	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
185	unsigned int mode;
186	int ret;
187
188	if (!count)
189		return 0;
190
191	ret = kstrtobool(buf, &bdreg->bkup_mode_enabled);
192	if (ret)
193		return ret;
194
195	if (!bdreg->rstbmode_level)
196		return count;
197
198	/*
199	 * Configure DDR Backup Mode, to change the role of the accessory power
200	 * switch from a power switch to a wake-up switch, or vice versa
201	 */
202	ret = bd9571mwv_bkup_mode_read(bdreg, &mode);
203	if (ret)
204		return ret;
205
206	mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
207	if (bdreg->bkup_mode_enabled)
208		mode |= bdreg->bkup_mode_cnt_keepon;
209
210	ret = bd9571mwv_bkup_mode_write(bdreg, mode);
211	if (ret)
212		return ret;
213
214	return count;
215}
216
217static DEVICE_ATTR_RW(backup_mode);
218
219static int bd9571mwv_suspend(struct device *dev)
220{
221	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
222	unsigned int mode;
223	int ret;
224
225	if (!bdreg->bkup_mode_enabled)
226		return 0;
227
228	/* Save DDR Backup Mode */
229	ret = bd9571mwv_bkup_mode_read(bdreg, &mode);
230	if (ret)
231		return ret;
232
233	bdreg->bkup_mode_cnt_saved = mode;
234
235	if (!bdreg->rstbmode_pulse)
236		return 0;
237
238	/* Enable DDR Backup Mode */
239	mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
240	mode |= bdreg->bkup_mode_cnt_keepon;
241
242	if (mode != bdreg->bkup_mode_cnt_saved)
243		return bd9571mwv_bkup_mode_write(bdreg, mode);
244
245	return 0;
246}
247
248static int bd9571mwv_resume(struct device *dev)
249{
250	struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
251
252	if (!bdreg->bkup_mode_enabled)
253		return 0;
254
255	/* Restore DDR Backup Mode */
256	return bd9571mwv_bkup_mode_write(bdreg, bdreg->bkup_mode_cnt_saved);
257}
258
259static const struct dev_pm_ops bd9571mwv_pm  = {
260	SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
261};
262
263static void bd9571mwv_regulator_remove(struct platform_device *pdev)
264{
265	device_remove_file(&pdev->dev, &dev_attr_backup_mode);
 
266}
267#define DEV_PM_OPS	&bd9571mwv_pm
268#else
269#define DEV_PM_OPS	NULL
270#define bd9571mwv_regulator_remove	NULL
271#endif /* CONFIG_PM_SLEEP */
272
273static int bd9571mwv_regulator_probe(struct platform_device *pdev)
274{
275	struct regulator_config config = { };
276	struct bd9571mwv_reg *bdreg;
277	struct regulator_dev *rdev;
278	unsigned int val;
279	int i;
280	enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
281
282	bdreg = devm_kzalloc(&pdev->dev, sizeof(*bdreg), GFP_KERNEL);
283	if (!bdreg)
284		return -ENOMEM;
285
286	bdreg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
287
288	platform_set_drvdata(pdev, bdreg);
289
290	config.dev = &pdev->dev;
291	config.dev->of_node = pdev->dev.parent->of_node;
292	config.driver_data = bdreg;
293	config.regmap = bdreg->regmap;
294
295	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
296		/* BD9574MWF supports DVFS only */
297		if (chip == ROHM_CHIP_TYPE_BD9574 && regulators[i].id != DVFS)
298			continue;
299		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
300					       &config);
301		if (IS_ERR(rdev)) {
302			dev_err(&pdev->dev, "failed to register %s regulator\n",
303				regulators[i].name);
304			return PTR_ERR(rdev);
305		}
306	}
307
308	val = 0;
309	of_property_read_u32(config.dev->of_node, "rohm,ddr-backup-power", &val);
310	if (val & ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK) {
311		dev_err(&pdev->dev, "invalid %s mode %u\n",
312			"rohm,ddr-backup-power", val);
313		return -EINVAL;
314	}
315	bdreg->bkup_mode_cnt_keepon = val;
316
317	bdreg->rstbmode_level = of_property_read_bool(config.dev->of_node,
318						      "rohm,rstbmode-level");
319	bdreg->rstbmode_pulse = of_property_read_bool(config.dev->of_node,
320						      "rohm,rstbmode-pulse");
321	if (bdreg->rstbmode_level && bdreg->rstbmode_pulse) {
322		dev_err(&pdev->dev, "only one rohm,rstbmode-* may be specified");
323		return -EINVAL;
324	}
325
326#ifdef CONFIG_PM_SLEEP
327	if (bdreg->bkup_mode_cnt_keepon) {
328		int ret;
329
330		/*
331		 * Backup mode is enabled by default in pulse mode, but needs
332		 * explicit user setup in level mode.
333		 */
334		bdreg->bkup_mode_enabled = bdreg->rstbmode_pulse;
335
336		ret = device_create_file(&pdev->dev, &dev_attr_backup_mode);
337		if (ret)
338			return ret;
339	}
340#endif /* CONFIG_PM_SLEEP */
341
342	return 0;
343}
344
345static const struct platform_device_id bd9571mwv_regulator_id_table[] = {
346	{ "bd9571mwv-regulator", ROHM_CHIP_TYPE_BD9571 },
347	{ "bd9574mwf-regulator", ROHM_CHIP_TYPE_BD9574 },
348	{ /* sentinel */ }
349};
350MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table);
351
352static struct platform_driver bd9571mwv_regulator_driver = {
353	.driver = {
354		.name = "bd9571mwv-regulator",
355		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
356		.pm = DEV_PM_OPS,
357	},
358	.probe = bd9571mwv_regulator_probe,
359	.remove_new = bd9571mwv_regulator_remove,
360	.id_table = bd9571mwv_regulator_id_table,
361};
362module_platform_driver(bd9571mwv_regulator_driver);
363
364MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
365MODULE_DESCRIPTION("BD9571MWV Regulator driver");
366MODULE_LICENSE("GPL v2");