brintos

brintos / linux-shallow public Read only

0
0
Text · 19.4 KiB · 79fbb45 Raw
632 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// Copyright 2014 Embest Technology Co. Ltd. Inc.4// bd71815-regulator.c ROHM BD71815 regulator driver5//6// Author: Tony Luo <luofc@embedinfo.com>7//8// Partially rewritten at 2021 by9// Matti Vaittinen <matti.vaitinen@fi.rohmeurope.com>10 11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/init.h>14#include <linux/err.h>15#include <linux/platform_device.h>16#include <linux/of.h>17#include <linux/gpio/consumer.h>18#include <linux/regulator/driver.h>19#include <linux/delay.h>20#include <linux/slab.h>21#include <linux/mfd/rohm-generic.h>22#include <linux/mfd/rohm-bd71815.h>23#include <linux/regulator/of_regulator.h>24 25struct bd71815_regulator {26	struct regulator_desc desc;27	const struct rohm_dvs_config *dvs;28};29 30static const int bd7181x_wled_currents[] = {31	10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000,32	5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,33	16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000,34};35 36static const struct rohm_dvs_config buck1_dvs = {37	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |38				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,39	.run_reg		= BD71815_REG_BUCK1_VOLT_H,40	.run_mask		= BD71815_VOLT_MASK,41	.run_on_mask		= BD71815_BUCK_RUN_ON,42	.snvs_on_mask		= BD71815_BUCK_SNVS_ON,43	.suspend_reg		= BD71815_REG_BUCK1_VOLT_L,44	.suspend_mask		= BD71815_VOLT_MASK,45	.suspend_on_mask	= BD71815_BUCK_SUSP_ON,46	.lpsr_reg		= BD71815_REG_BUCK1_VOLT_L,47	.lpsr_mask		= BD71815_VOLT_MASK,48	.lpsr_on_mask		= BD71815_BUCK_LPSR_ON,49};50 51static const struct rohm_dvs_config buck2_dvs = {52	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |53				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,54	.run_reg		= BD71815_REG_BUCK2_VOLT_H,55	.run_mask		= BD71815_VOLT_MASK,56	.run_on_mask		= BD71815_BUCK_RUN_ON,57	.snvs_on_mask		= BD71815_BUCK_SNVS_ON,58	.suspend_reg		= BD71815_REG_BUCK2_VOLT_L,59	.suspend_mask		= BD71815_VOLT_MASK,60	.suspend_on_mask	= BD71815_BUCK_SUSP_ON,61	.lpsr_reg		= BD71815_REG_BUCK2_VOLT_L,62	.lpsr_mask		= BD71815_VOLT_MASK,63	.lpsr_on_mask		= BD71815_BUCK_LPSR_ON,64};65 66static const struct rohm_dvs_config buck3_dvs = {67	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |68				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,69	.run_reg		= BD71815_REG_BUCK3_VOLT,70	.run_mask		= BD71815_VOLT_MASK,71	.run_on_mask		= BD71815_BUCK_RUN_ON,72	.snvs_on_mask		= BD71815_BUCK_SNVS_ON,73	.suspend_on_mask	= BD71815_BUCK_SUSP_ON,74	.lpsr_on_mask		= BD71815_BUCK_LPSR_ON,75};76 77static const struct rohm_dvs_config buck4_dvs = {78	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |79				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,80	.run_reg		= BD71815_REG_BUCK4_VOLT,81	.run_mask		= BD71815_VOLT_MASK,82	.run_on_mask		= BD71815_BUCK_RUN_ON,83	.snvs_on_mask		= BD71815_BUCK_SNVS_ON,84	.suspend_on_mask	= BD71815_BUCK_SUSP_ON,85	.lpsr_on_mask		= BD71815_BUCK_LPSR_ON,86};87 88static const struct rohm_dvs_config ldo1_dvs = {89	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |90				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,91	.run_reg		= BD71815_REG_LDO_MODE1,92	.run_mask		= BD71815_VOLT_MASK,93	.run_on_mask		= LDO1_RUN_ON,94	.snvs_on_mask		= LDO1_SNVS_ON,95	.suspend_on_mask	= LDO1_SUSP_ON,96	.lpsr_on_mask		= LDO1_LPSR_ON,97};98 99static const struct rohm_dvs_config ldo2_dvs = {100	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |101				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,102	.run_reg		= BD71815_REG_LDO_MODE2,103	.run_mask		= BD71815_VOLT_MASK,104	.run_on_mask		= LDO2_RUN_ON,105	.snvs_on_mask		= LDO2_SNVS_ON,106	.suspend_on_mask	= LDO2_SUSP_ON,107	.lpsr_on_mask		= LDO2_LPSR_ON,108};109 110static const struct rohm_dvs_config ldo3_dvs = {111	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |112				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,113	.run_reg		= BD71815_REG_LDO_MODE2,114	.run_mask		= BD71815_VOLT_MASK,115	.run_on_mask		= LDO3_RUN_ON,116	.snvs_on_mask		= LDO3_SNVS_ON,117	.suspend_on_mask	= LDO3_SUSP_ON,118	.lpsr_on_mask		= LDO3_LPSR_ON,119};120 121static const struct rohm_dvs_config ldo4_dvs = {122	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |123				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,124	.run_reg		= BD71815_REG_LDO_MODE3,125	.run_mask		= BD71815_VOLT_MASK,126	.run_on_mask		= LDO4_RUN_ON,127	.snvs_on_mask		= LDO4_SNVS_ON,128	.suspend_on_mask	= LDO4_SUSP_ON,129	.lpsr_on_mask		= LDO4_LPSR_ON,130};131 132static const struct rohm_dvs_config ldo5_dvs = {133	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |134				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,135	.run_reg		= BD71815_REG_LDO_MODE3,136	.run_mask		= BD71815_VOLT_MASK,137	.run_on_mask		= LDO5_RUN_ON,138	.snvs_on_mask		= LDO5_SNVS_ON,139	.suspend_on_mask	= LDO5_SUSP_ON,140	.lpsr_on_mask		= LDO5_LPSR_ON,141};142 143static const struct rohm_dvs_config dvref_dvs = {144	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |145				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,146	.run_on_mask		= DVREF_RUN_ON,147	.snvs_on_mask		= DVREF_SNVS_ON,148	.suspend_on_mask	= DVREF_SUSP_ON,149	.lpsr_on_mask		= DVREF_LPSR_ON,150};151 152static const struct rohm_dvs_config ldolpsr_dvs = {153	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |154				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,155	.run_on_mask		= DVREF_RUN_ON,156	.snvs_on_mask		= DVREF_SNVS_ON,157	.suspend_on_mask	= DVREF_SUSP_ON,158	.lpsr_on_mask		= DVREF_LPSR_ON,159};160 161static const struct rohm_dvs_config buck5_dvs = {162	.level_map		= ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |163				  ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,164	.run_reg		= BD71815_REG_BUCK5_VOLT,165	.run_mask		= BD71815_VOLT_MASK,166	.run_on_mask		= BD71815_BUCK_RUN_ON,167	.snvs_on_mask		= BD71815_BUCK_SNVS_ON,168	.suspend_on_mask	= BD71815_BUCK_SUSP_ON,169	.lpsr_on_mask		= BD71815_BUCK_LPSR_ON,170};171 172static int set_hw_dvs_levels(struct device_node *np,173			     const struct regulator_desc *desc,174			     struct regulator_config *cfg)175{176	struct bd71815_regulator *data;177 178	data = container_of(desc, struct bd71815_regulator, desc);179	return rohm_regulator_set_dvs_levels(data->dvs, np, desc, cfg->regmap);180}181 182/*183 * Bucks 1 and 2 have two voltage selection registers where selected184 * voltage can be set. Which of the registers is used can be either controlled185 * by a control bit in register - or by HW state. If HW state specific voltages186 * are given - then we assume HW state based control should be used.187 *188 * If volatge value is updated to currently selected register - then output189 * voltage is immediately changed no matter what is set as ramp rate. Thus we190 * default changing voltage by writing new value to inactive register and191 * then updating the 'register selection' bit. This naturally only works when192 * HW state machine is not used to select the voltage.193 */194static int buck12_set_hw_dvs_levels(struct device_node *np,195				    const struct regulator_desc *desc,196				    struct regulator_config *cfg)197{198	struct bd71815_regulator *data;199	int ret = 0, val;200 201	data = container_of(desc, struct bd71815_regulator, desc);202 203	if (of_property_present(np, "rohm,dvs-run-voltage") ||204	    of_property_present(np, "rohm,dvs-suspend-voltage") ||205	    of_property_present(np, "rohm,dvs-lpsr-voltage") ||206	    of_property_present(np, "rohm,dvs-snvs-voltage")) {207		ret = regmap_read(cfg->regmap, desc->vsel_reg, &val);208		if (ret)209			return ret;210 211		if (!(BD71815_BUCK_STBY_DVS & val) &&212		    !(BD71815_BUCK_DVSSEL & val)) {213			int val2;214 215			/*216			 * We are currently using voltage from _L.217			 * We'd better copy it to _H and switch to it to218			 * avoid shutting us down if LPSR or SUSPEND is set to219			 * disabled. _L value is at reg _H + 1220			 */221			ret = regmap_read(cfg->regmap, desc->vsel_reg + 1,222					  &val2);223			if (ret)224				return ret;225 226			ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,227						 BD71815_VOLT_MASK |228						 BD71815_BUCK_DVSSEL,229						 val2 | BD71815_BUCK_DVSSEL);230			if (ret)231				return ret;232		}233		ret = rohm_regulator_set_dvs_levels(data->dvs, np, desc,234						    cfg->regmap);235		if (ret)236			return ret;237		/*238		 * DVS levels were given => use HW-state machine for voltage239		 * controls. NOTE: AFAIK, This means that if voltage is changed240		 * by SW the ramp-rate is not respected. Should we disable241		 * SW voltage control when the HW state machine is used?242		 */243		ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,244					 BD71815_BUCK_STBY_DVS,245					 BD71815_BUCK_STBY_DVS);246	}247 248	return ret;249}250 251/*252 * BUCK1/2253 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting254 * 00: 10.00mV/usec	10mV 1uS255 * 01: 5.00mV/usec	10mV 2uS256 * 10: 2.50mV/usec	10mV 4uS257 * 11: 1.25mV/usec	10mV 8uS258 */259static const unsigned int bd7181x_ramp_table[] = { 10000, 5000, 2500, 1250 };260 261static int bd7181x_led_set_current_limit(struct regulator_dev *rdev,262					int min_uA, int max_uA)263{264	int ret;265	int onstatus;266 267	onstatus = regulator_is_enabled_regmap(rdev);268 269	ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA);270	if (!ret) {271		int newstatus;272 273		newstatus = regulator_is_enabled_regmap(rdev);274		if (onstatus != newstatus) {275			/*276			 * HW FIX: spurious led status change detected. Toggle277			 * state as a workaround278			 */279			if (onstatus)280				ret = regulator_enable_regmap(rdev);281			else282				ret = regulator_disable_regmap(rdev);283 284			if (ret)285				dev_err(rdev_get_dev(rdev),286					"failed to revert the LED state (%d)\n",287					ret);288		}289	}290 291	return ret;292}293 294static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)295{296	int rid = rdev_get_id(rdev);297	int ret, regh, regl, val;298 299	regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2;300	regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2;301 302	ret = regmap_read(rdev->regmap, regh, &val);303	if (ret)304		return ret;305 306	/*307	 * If we use HW state machine based voltage reg selection - then we308	 * return BD71815_REG_BUCK1_VOLT_H which is used at RUN.309	 * Else we do return the BD71815_REG_BUCK1_VOLT_H or310	 * BD71815_REG_BUCK1_VOLT_L depending on which is selected to be used311	 * by BD71815_BUCK_DVSSEL bit312	 */313	if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))314		ret = regmap_read(rdev->regmap, regl, &val);315 316	if (ret)317		return ret;318 319	return val & BD71815_VOLT_MASK;320}321 322/*323 * For Buck 1/2.324 */325static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,326					  unsigned int sel)327{328	int rid = rdev_get_id(rdev);329	int ret, val, reg, regh, regl;330 331	regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2;332	regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2;333 334	ret = regmap_read(rdev->regmap, regh, &val);335	if (ret)336		return ret;337 338	/*339	 * If bucks 1 & 2 are controlled by state machine - then the RUN state340	 * voltage is set to BD71815_REG_BUCK1_VOLT_H. Changing SUSPEND/LPSR341	 * voltages at runtime is not supported by this driver.342	 */343	if (((val & BD71815_BUCK_STBY_DVS))) {344		return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,345					  sel);346	}347	/* Update new voltage to the register which is not selected now */348	if (val & BD71815_BUCK_DVSSEL)349		reg = regl;350	else351		reg = regh;352 353	ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel);354	if (ret)355		return ret;356 357	/* Select the other DVS register to be used */358	return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,359				  ~val);360}361 362static const struct regulator_ops bd7181x_ldo_regulator_ops = {363	.enable = regulator_enable_regmap,364	.disable = regulator_disable_regmap,365	.is_enabled = regulator_is_enabled_regmap,366	.list_voltage = regulator_list_voltage_linear,367	.set_voltage_sel = regulator_set_voltage_sel_regmap,368	.get_voltage_sel = regulator_get_voltage_sel_regmap,369};370 371static const struct regulator_ops bd7181x_fixed_regulator_ops = {372	.enable = regulator_enable_regmap,373	.disable = regulator_disable_regmap,374	.is_enabled = regulator_is_enabled_regmap,375	.list_voltage = regulator_list_voltage_linear,376};377 378static const struct regulator_ops bd7181x_buck_regulator_ops = {379	.enable = regulator_enable_regmap,380	.disable = regulator_disable_regmap,381	.is_enabled = regulator_is_enabled_regmap,382	.list_voltage = regulator_list_voltage_linear,383	.set_voltage_sel = regulator_set_voltage_sel_regmap,384	.get_voltage_sel = regulator_get_voltage_sel_regmap,385	.set_voltage_time_sel = regulator_set_voltage_time_sel,386};387 388static const struct regulator_ops bd7181x_buck12_regulator_ops = {389	.enable = regulator_enable_regmap,390	.disable = regulator_disable_regmap,391	.is_enabled = regulator_is_enabled_regmap,392	.list_voltage = regulator_list_voltage_linear,393	.set_voltage_sel = bd7181x_buck12_set_voltage_sel,394	.get_voltage_sel = bd7181x_buck12_get_voltage_sel,395	.set_voltage_time_sel = regulator_set_voltage_time_sel,396	.set_ramp_delay = regulator_set_ramp_delay_regmap,397};398 399static const struct regulator_ops bd7181x_led_regulator_ops = {400	.enable = regulator_enable_regmap,401	.disable = regulator_disable_regmap,402	.is_enabled = regulator_is_enabled_regmap,403	.set_current_limit = bd7181x_led_set_current_limit,404	.get_current_limit = regulator_get_current_limit_regmap,405};406 407#define BD71815_FIXED_REG(_name, _id, ereg, emsk, voltage, _dvs)	\408	[(_id)] = {							\409		.desc = {						\410			.name = #_name,					\411			.of_match = of_match_ptr(#_name),		\412			.regulators_node = of_match_ptr("regulators"),	\413			.n_voltages = 1,				\414			.ops = &bd7181x_fixed_regulator_ops,		\415			.type = REGULATOR_VOLTAGE,			\416			.id = (_id),					\417			.owner = THIS_MODULE,				\418			.min_uV = (voltage),				\419			.enable_reg = (ereg),				\420			.enable_mask = (emsk),				\421			.of_parse_cb = set_hw_dvs_levels,		\422		},							\423		.dvs = (_dvs),						\424	}425 426#define BD71815_BUCK_REG(_name, _id, vsel, ereg, min, max, step, _dvs)	\427	[(_id)] = {							\428		.desc = {						\429			.name = #_name,					\430			.of_match = of_match_ptr(#_name),		\431			.regulators_node = of_match_ptr("regulators"),	\432			.n_voltages = ((max) - (min)) / (step) + 1,	\433			.ops = &bd7181x_buck_regulator_ops,		\434			.type = REGULATOR_VOLTAGE,			\435			.id = (_id),					\436			.owner = THIS_MODULE,				\437			.min_uV = (min),				\438			.uV_step = (step),				\439			.vsel_reg = (vsel),				\440			.vsel_mask = BD71815_VOLT_MASK,			\441			.enable_reg = (ereg),				\442			.enable_mask = BD71815_BUCK_RUN_ON,		\443			.of_parse_cb = set_hw_dvs_levels,		\444		},							\445		.dvs = (_dvs),						\446	}447 448#define BD71815_BUCK12_REG(_name, _id, vsel, ereg, min, max, step,	\449			   _dvs)					\450	[(_id)] = {							\451		.desc = {						\452			.name = #_name,					\453			.of_match = of_match_ptr(#_name),		\454			.regulators_node = of_match_ptr("regulators"),	\455			.n_voltages = ((max) - (min)) / (step) + 1,	\456			.ops = &bd7181x_buck12_regulator_ops,		\457			.type = REGULATOR_VOLTAGE,			\458			.id = (_id),					\459			.owner = THIS_MODULE,				\460			.min_uV = (min),				\461			.uV_step = (step),				\462			.vsel_reg = (vsel),				\463			.vsel_mask = BD71815_VOLT_MASK,			\464			.enable_reg = (ereg),				\465			.enable_mask = BD71815_BUCK_RUN_ON,		\466			.ramp_reg = (ereg),				\467			.ramp_mask = BD71815_BUCK_RAMPRATE_MASK,	\468			.ramp_delay_table = bd7181x_ramp_table,		\469			.n_ramp_values = ARRAY_SIZE(bd7181x_ramp_table),\470			.of_parse_cb = buck12_set_hw_dvs_levels,	\471		},							\472		.dvs = (_dvs),						\473	}474 475#define BD71815_LED_REG(_name, _id, csel, mask, ereg, emsk, currents)	\476	[(_id)] = {							\477		.desc = {						\478			.name = #_name,					\479			.of_match = of_match_ptr(#_name),		\480			.regulators_node = of_match_ptr("regulators"),	\481			.n_current_limits = ARRAY_SIZE(currents),	\482			.ops = &bd7181x_led_regulator_ops,		\483			.type = REGULATOR_CURRENT,			\484			.id = (_id),					\485			.owner = THIS_MODULE,				\486			.curr_table = currents,				\487			.csel_reg = (csel),				\488			.csel_mask = (mask),				\489			.enable_reg = (ereg),				\490			.enable_mask = (emsk),				\491		},							\492	}493 494#define BD71815_LDO_REG(_name, _id, vsel, ereg, emsk, min, max, step,	\495			_dvs)						\496	[(_id)] = {							\497		.desc = {						\498			.name = #_name,					\499			.of_match = of_match_ptr(#_name),		\500			.regulators_node = of_match_ptr("regulators"),	\501			.n_voltages = ((max) - (min)) / (step) + 1,	\502			.ops = &bd7181x_ldo_regulator_ops,		\503			.type = REGULATOR_VOLTAGE,			\504			.id = (_id),					\505			.owner = THIS_MODULE,				\506			.min_uV = (min),				\507			.uV_step = (step),				\508			.vsel_reg = (vsel),				\509			.vsel_mask = BD71815_VOLT_MASK,			\510			.enable_reg = (ereg),				\511			.enable_mask = (emsk),				\512			.of_parse_cb = set_hw_dvs_levels,		\513		},							\514		.dvs = (_dvs),						\515	}516 517static const struct bd71815_regulator bd71815_regulators[] = {518	BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H,519			   BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000,520			   &buck1_dvs),521	BD71815_BUCK12_REG(buck2, BD71815_BUCK2, BD71815_REG_BUCK2_VOLT_H,522			   BD71815_REG_BUCK2_MODE, 800000, 2000000, 25000,523			   &buck2_dvs),524	BD71815_BUCK_REG(buck3, BD71815_BUCK3, BD71815_REG_BUCK3_VOLT,525			 BD71815_REG_BUCK3_MODE,  1200000, 2700000, 50000,526			 &buck3_dvs),527	BD71815_BUCK_REG(buck4, BD71815_BUCK4, BD71815_REG_BUCK4_VOLT,528			 BD71815_REG_BUCK4_MODE,  1100000, 1850000, 25000,529			 &buck4_dvs),530	BD71815_BUCK_REG(buck5, BD71815_BUCK5, BD71815_REG_BUCK5_VOLT,531			 BD71815_REG_BUCK5_MODE,  1800000, 3300000, 50000,532			 &buck5_dvs),533	BD71815_LDO_REG(ldo1, BD71815_LDO1, BD71815_REG_LDO1_VOLT,534			BD71815_REG_LDO_MODE1, LDO1_RUN_ON, 800000, 3300000,535			50000, &ldo1_dvs),536	BD71815_LDO_REG(ldo2, BD71815_LDO2, BD71815_REG_LDO2_VOLT,537			BD71815_REG_LDO_MODE2, LDO2_RUN_ON, 800000, 3300000,538			50000, &ldo2_dvs),539	/*540	 * Let's default LDO3 to be enabled by SW. We can override ops if DT541	 * says LDO3 should be enabled by HW when DCIN is connected.542	 */543	BD71815_LDO_REG(ldo3, BD71815_LDO3, BD71815_REG_LDO3_VOLT,544			BD71815_REG_LDO_MODE2, LDO3_RUN_ON, 800000, 3300000,545			50000, &ldo3_dvs),546	BD71815_LDO_REG(ldo4, BD71815_LDO4, BD71815_REG_LDO4_VOLT,547			BD71815_REG_LDO_MODE3, LDO4_RUN_ON, 800000, 3300000,548			50000, &ldo4_dvs),549	BD71815_LDO_REG(ldo5, BD71815_LDO5, BD71815_REG_LDO5_VOLT_H,550			BD71815_REG_LDO_MODE3, LDO5_RUN_ON, 800000, 3300000,551			50000, &ldo5_dvs),552	BD71815_FIXED_REG(ldodvref, BD71815_LDODVREF, BD71815_REG_LDO_MODE4,553			  DVREF_RUN_ON, 3000000, &dvref_dvs),554	BD71815_FIXED_REG(ldolpsr, BD71815_LDOLPSR, BD71815_REG_LDO_MODE4,555			  LDO_LPSR_RUN_ON, 1800000, &ldolpsr_dvs),556	BD71815_LED_REG(wled, BD71815_WLED, BD71815_REG_LED_DIMM, LED_DIMM_MASK,557			BD71815_REG_LED_CTRL, LED_RUN_ON,558			bd7181x_wled_currents),559};560 561static int bd7181x_probe(struct platform_device *pdev)562{563	struct regulator_config config = {};564	int i, ret;565	struct gpio_desc *ldo4_en;566	struct regmap *regmap;567 568	regmap = dev_get_regmap(pdev->dev.parent, NULL);569	if (!regmap) {570		dev_err(&pdev->dev, "No parent regmap\n");571		return -ENODEV;572	}573 574	ldo4_en = devm_fwnode_gpiod_get(&pdev->dev,575					dev_fwnode(pdev->dev.parent),576					"rohm,vsel", GPIOD_ASIS, "ldo4-en");577	if (IS_ERR(ldo4_en)) {578		ret = PTR_ERR(ldo4_en);579		if (ret != -ENOENT)580			return ret;581		ldo4_en = NULL;582	}583 584	/* Disable to go to ship-mode */585	ret = regmap_update_bits(regmap, BD71815_REG_PWRCTRL, RESTARTEN, 0);586	if (ret)587		return ret;588 589	config.dev = pdev->dev.parent;590	config.regmap = regmap;591 592	for (i = 0; i < BD71815_REGULATOR_CNT; i++) {593		const struct regulator_desc *desc;594		struct regulator_dev *rdev;595 596		desc = &bd71815_regulators[i].desc;597 598		if (i == BD71815_LDO4)599			config.ena_gpiod = ldo4_en;600		else601			config.ena_gpiod = NULL;602 603		rdev = devm_regulator_register(&pdev->dev, desc, &config);604		if (IS_ERR(rdev))605			return dev_err_probe(&pdev->dev, PTR_ERR(rdev),606					     "failed to register %s regulator\n",607					     desc->name);608	}609	return 0;610}611 612static const struct platform_device_id bd7181x_pmic_id[] = {613	{ "bd71815-pmic", ROHM_CHIP_TYPE_BD71815 },614	{ },615};616MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);617 618static struct platform_driver bd7181x_regulator = {619	.driver = {620		.name = "bd7181x-pmic",621		.probe_type = PROBE_PREFER_ASYNCHRONOUS,622	},623	.probe = bd7181x_probe,624	.id_table = bd7181x_pmic_id,625};626module_platform_driver(bd7181x_regulator);627 628MODULE_AUTHOR("Tony Luo <luofc@embedinfo.com>");629MODULE_DESCRIPTION("BD71815 voltage regulator driver");630MODULE_LICENSE("GPL v2");631MODULE_ALIAS("platform:bd7181x-pmic");632