brintos

brintos / linux-shallow public Read only

0
0
Text · 30.9 KiB · bf5f9c3 Raw
1141 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2020 ROHM Semiconductors3// ROHM BD9576MUF/BD9573MUF regulator driver4 5#include <linux/err.h>6#include <linux/gpio/consumer.h>7#include <linux/interrupt.h>8#include <linux/jiffies.h>9#include <linux/kernel.h>10#include <linux/mfd/rohm-bd957x.h>11#include <linux/mfd/rohm-generic.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/platform_device.h>15#include <linux/property.h>16#include <linux/regulator/driver.h>17#include <linux/regulator/machine.h>18#include <linux/regulator/of_regulator.h>19#include <linux/slab.h>20#include <linux/spinlock.h>21#include <linux/workqueue.h>22 23#define BD957X_VOUTS1_VOLT	330000024#define BD957X_VOUTS4_BASE_VOLT	103000025#define BD957X_VOUTS34_NUM_VOLT	3226 27#define BD9576_THERM_IRQ_MASK_TW	BIT(5)28#define BD9576_xVD_IRQ_MASK_VOUTL1	BIT(5)29#define BD9576_UVD_IRQ_MASK_VOUTS1_OCW	BIT(6)30#define BD9576_xVD_IRQ_MASK_VOUT1TO4	0x0F31 32static const unsigned int vout1_volt_table[] = {33	5000000, 4900000, 4800000, 4700000, 4600000,34	4500000, 4500000, 4500000, 5000000, 5100000,35	5200000, 5300000, 5400000, 5500000, 5500000,36	550000037};38 39static const unsigned int vout2_volt_table[] = {40	1800000, 1780000, 1760000, 1740000, 1720000,41	1700000, 1680000, 1660000, 1800000, 1820000,42	1840000, 1860000, 1880000, 1900000, 1920000,43	194000044};45 46static const unsigned int voutl1_volt_table[] = {47	2500000, 2540000, 2580000, 2620000, 2660000,48	2700000, 2740000, 2780000, 2500000, 2460000,49	2420000, 2380000, 2340000, 2300000, 2260000,50	222000051};52 53static const struct linear_range vout1_xvd_ranges[] = {54	REGULATOR_LINEAR_RANGE(225000, 0x01, 0x2b, 0),55	REGULATOR_LINEAR_RANGE(225000, 0x2c, 0x54, 5000),56	REGULATOR_LINEAR_RANGE(425000, 0x55, 0x7f, 0),57};58 59static const struct linear_range vout234_xvd_ranges[] = {60	REGULATOR_LINEAR_RANGE(17000, 0x01, 0x0f, 0),61	REGULATOR_LINEAR_RANGE(17000, 0x10, 0x6d, 1000),62	REGULATOR_LINEAR_RANGE(110000, 0x6e, 0x7f, 0),63};64 65static const struct linear_range voutL1_xvd_ranges[] = {66	REGULATOR_LINEAR_RANGE(34000, 0x01, 0x0f, 0),67	REGULATOR_LINEAR_RANGE(34000, 0x10, 0x6d, 2000),68	REGULATOR_LINEAR_RANGE(220000, 0x6e, 0x7f, 0),69};70 71static const struct linear_range voutS1_ocw_ranges_internal[] = {72	REGULATOR_LINEAR_RANGE(200000, 0x01, 0x04, 0),73	REGULATOR_LINEAR_RANGE(250000, 0x05, 0x18, 50000),74	REGULATOR_LINEAR_RANGE(1200000, 0x19, 0x3f, 0),75};76 77static const struct linear_range voutS1_ocw_ranges[] = {78	REGULATOR_LINEAR_RANGE(50000, 0x01, 0x04, 0),79	REGULATOR_LINEAR_RANGE(60000, 0x05, 0x18, 10000),80	REGULATOR_LINEAR_RANGE(250000, 0x19, 0x3f, 0),81};82 83static const struct linear_range voutS1_ocp_ranges_internal[] = {84	REGULATOR_LINEAR_RANGE(300000, 0x01, 0x06, 0),85	REGULATOR_LINEAR_RANGE(350000, 0x7, 0x1b, 50000),86	REGULATOR_LINEAR_RANGE(1350000, 0x1c, 0x3f, 0),87};88 89static const struct linear_range voutS1_ocp_ranges[] = {90	REGULATOR_LINEAR_RANGE(70000, 0x01, 0x06, 0),91	REGULATOR_LINEAR_RANGE(80000, 0x7, 0x1b, 10000),92	REGULATOR_LINEAR_RANGE(280000, 0x1c, 0x3f, 0),93};94 95struct bd957x_regulator_data {96	struct regulator_desc desc;97	int base_voltage;98	struct regulator_dev *rdev;99	int ovd_notif;100	int uvd_notif;101	int temp_notif;102	int ovd_err;103	int uvd_err;104	int temp_err;105	const struct linear_range *xvd_ranges;106	int num_xvd_ranges;107	bool oc_supported;108	unsigned int ovd_reg;109	unsigned int uvd_reg;110	unsigned int xvd_mask;111	unsigned int ocp_reg;112	unsigned int ocp_mask;113	unsigned int ocw_reg;114	unsigned int ocw_mask;115	unsigned int ocw_rfet;116};117 118#define BD9576_NUM_REGULATORS 6119#define BD9576_NUM_OVD_REGULATORS 5120 121struct bd957x_data {122	struct bd957x_regulator_data regulator_data[BD9576_NUM_REGULATORS];123	struct regmap *regmap;124	struct delayed_work therm_irq_suppress;125	struct delayed_work ovd_irq_suppress;126	struct delayed_work uvd_irq_suppress;127	unsigned int therm_irq;128	unsigned int ovd_irq;129	unsigned int uvd_irq;130	spinlock_t err_lock;131	int regulator_global_err;132};133 134static int bd957x_vout34_list_voltage(struct regulator_dev *rdev,135				      unsigned int selector)136{137	const struct regulator_desc *desc = rdev->desc;138	int multiplier = selector & desc->vsel_mask & 0x7f;139	int tune;140 141	/* VOUT3 and 4 has 10mV step */142	tune = multiplier * 10000;143 144	if (!(selector & 0x80))145		return desc->fixed_uV - tune;146 147	return desc->fixed_uV + tune;148}149 150static int bd957x_list_voltage(struct regulator_dev *rdev,151			       unsigned int selector)152{153	const struct regulator_desc *desc = rdev->desc;154	int index = selector & desc->vsel_mask & 0x7f;155 156	if (!(selector & 0x80))157		index += desc->n_voltages/2;158 159	if (index >= desc->n_voltages)160		return -EINVAL;161 162	return desc->volt_table[index];163}164 165static void bd9576_fill_ovd_flags(struct bd957x_regulator_data *data,166				  bool warn)167{168	if (warn) {169		data->ovd_notif = REGULATOR_EVENT_OVER_VOLTAGE_WARN;170		data->ovd_err = REGULATOR_ERROR_OVER_VOLTAGE_WARN;171	} else {172		data->ovd_notif = REGULATOR_EVENT_REGULATION_OUT;173		data->ovd_err = REGULATOR_ERROR_REGULATION_OUT;174	}175}176 177static void bd9576_fill_ocp_flags(struct bd957x_regulator_data *data,178				  bool warn)179{180	if (warn) {181		data->uvd_notif = REGULATOR_EVENT_OVER_CURRENT_WARN;182		data->uvd_err = REGULATOR_ERROR_OVER_CURRENT_WARN;183	} else {184		data->uvd_notif = REGULATOR_EVENT_OVER_CURRENT;185		data->uvd_err = REGULATOR_ERROR_OVER_CURRENT;186	}187}188 189static void bd9576_fill_uvd_flags(struct bd957x_regulator_data *data,190				  bool warn)191{192	if (warn) {193		data->uvd_notif = REGULATOR_EVENT_UNDER_VOLTAGE_WARN;194		data->uvd_err = REGULATOR_ERROR_UNDER_VOLTAGE_WARN;195	} else {196		data->uvd_notif = REGULATOR_EVENT_UNDER_VOLTAGE;197		data->uvd_err = REGULATOR_ERROR_UNDER_VOLTAGE;198	}199}200 201static void bd9576_fill_temp_flags(struct bd957x_regulator_data *data,202				   bool enable, bool warn)203{204	if (!enable) {205		data->temp_notif = 0;206		data->temp_err = 0;207	} else if (warn) {208		data->temp_notif = REGULATOR_EVENT_OVER_TEMP_WARN;209		data->temp_err = REGULATOR_ERROR_OVER_TEMP_WARN;210	} else {211		data->temp_notif = REGULATOR_EVENT_OVER_TEMP;212		data->temp_err = REGULATOR_ERROR_OVER_TEMP;213	}214}215 216static int bd9576_set_limit(const struct linear_range *r, int num_ranges,217			    struct regmap *regmap, int reg, int mask, int lim)218{219	int ret;220	bool found;221	int sel = 0;222 223	if (lim) {224 225		ret = linear_range_get_selector_low_array(r, num_ranges,226							  lim, &sel, &found);227		if (ret)228			return ret;229 230		if (!found)231			dev_warn(regmap_get_device(regmap),232				 "limit %d out of range. Setting lower\n",233				 lim);234	}235 236	return regmap_update_bits(regmap, reg, mask, sel);237}238 239static bool check_ocp_flag_mismatch(struct regulator_dev *rdev, int severity,240				    struct bd957x_regulator_data *r)241{242	if ((severity == REGULATOR_SEVERITY_ERR &&243	    r->uvd_notif != REGULATOR_EVENT_OVER_CURRENT) ||244	    (severity == REGULATOR_SEVERITY_WARN &&245	    r->uvd_notif != REGULATOR_EVENT_OVER_CURRENT_WARN)) {246		dev_warn(rdev_get_dev(rdev),247			 "Can't support both OCP WARN and ERR\n");248		/* Do not overwrite ERR config with WARN */249		if (severity == REGULATOR_SEVERITY_WARN)250			return true;251 252		bd9576_fill_ocp_flags(r, 0);253	}254 255	return false;256}257 258static bool check_uvd_flag_mismatch(struct regulator_dev *rdev, int severity,259				    struct bd957x_regulator_data *r)260{261	if ((severity == REGULATOR_SEVERITY_ERR &&262	     r->uvd_notif != REGULATOR_EVENT_UNDER_VOLTAGE) ||263	     (severity == REGULATOR_SEVERITY_WARN &&264	     r->uvd_notif != REGULATOR_EVENT_UNDER_VOLTAGE_WARN)) {265		dev_warn(rdev_get_dev(rdev),266			 "Can't support both UVD WARN and ERR\n");267		if (severity == REGULATOR_SEVERITY_WARN)268			return true;269 270		bd9576_fill_uvd_flags(r, 0);271	}272 273	return false;274}275 276static bool check_ovd_flag_mismatch(struct regulator_dev *rdev, int severity,277				    struct bd957x_regulator_data *r)278{279	if ((severity == REGULATOR_SEVERITY_ERR &&280	     r->ovd_notif != REGULATOR_EVENT_REGULATION_OUT) ||281	     (severity == REGULATOR_SEVERITY_WARN &&282	     r->ovd_notif != REGULATOR_EVENT_OVER_VOLTAGE_WARN)) {283		dev_warn(rdev_get_dev(rdev),284			 "Can't support both OVD WARN and ERR\n");285		if (severity == REGULATOR_SEVERITY_WARN)286			return true;287 288		bd9576_fill_ovd_flags(r, 0);289	}290 291	return false;292}293 294static bool check_temp_flag_mismatch(struct regulator_dev *rdev, int severity,295				    struct bd957x_regulator_data *r)296{297	if ((severity == REGULATOR_SEVERITY_ERR &&298	     r->temp_notif != REGULATOR_EVENT_OVER_TEMP) ||299	     (severity == REGULATOR_SEVERITY_WARN &&300	     r->temp_notif != REGULATOR_EVENT_OVER_TEMP_WARN)) {301		dev_warn(rdev_get_dev(rdev),302			 "Can't support both thermal WARN and ERR\n");303		if (severity == REGULATOR_SEVERITY_WARN)304			return true;305	}306 307	return false;308}309 310static int bd9576_set_ocp(struct regulator_dev *rdev, int lim_uA, int severity,311			  bool enable)312{313	struct bd957x_data *d;314	struct bd957x_regulator_data *r;315	int reg, mask;316	int Vfet, rfet;317	const struct linear_range *range;318	int num_ranges;319 320	if ((lim_uA && !enable) || (!lim_uA && enable))321		return -EINVAL;322 323	r = container_of(rdev->desc, struct bd957x_regulator_data, desc);324	if (!r->oc_supported)325		return -EINVAL;326 327	d = rdev_get_drvdata(rdev);328 329	if (severity == REGULATOR_SEVERITY_PROT) {330		reg = r->ocp_reg;331		mask = r->ocp_mask;332		if (r->ocw_rfet) {333			range = voutS1_ocp_ranges;334			num_ranges = ARRAY_SIZE(voutS1_ocp_ranges);335			rfet = r->ocw_rfet / 1000;336		} else {337			range = voutS1_ocp_ranges_internal;338			num_ranges = ARRAY_SIZE(voutS1_ocp_ranges_internal);339			/* Internal values are already micro-amperes */340			rfet = 1000;341		}342	} else {343		reg = r->ocw_reg;344		mask = r->ocw_mask;345 346		if (r->ocw_rfet) {347			range = voutS1_ocw_ranges;348			num_ranges = ARRAY_SIZE(voutS1_ocw_ranges);349			rfet = r->ocw_rfet / 1000;350		} else {351			range = voutS1_ocw_ranges_internal;352			num_ranges = ARRAY_SIZE(voutS1_ocw_ranges_internal);353			/* Internal values are already micro-amperes */354			rfet = 1000;355		}356 357		/* We abuse uvd fields for OCW on VoutS1 */358		if (r->uvd_notif) {359			/*360			 * If both warning and error are requested, prioritize361			 * ERROR configuration362			 */363			if (check_ocp_flag_mismatch(rdev, severity, r))364				return 0;365		} else {366			bool warn = severity == REGULATOR_SEVERITY_WARN;367 368			bd9576_fill_ocp_flags(r, warn);369		}370	}371 372	/*373	 * limits are given in uA, rfet is mOhm374	 * Divide lim_uA by 1000 to get Vfet in uV.375	 * (We expect both Rfet and limit uA to be magnitude of hundreds of376	 * milli Amperes & milli Ohms => we should still have decent accuracy)377	 */378	Vfet = lim_uA/1000 * rfet;379 380	return bd9576_set_limit(range, num_ranges, d->regmap,381				reg, mask, Vfet);382}383 384static int bd9576_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity,385			  bool enable)386{387	struct bd957x_data *d;388	struct bd957x_regulator_data *r;389	int mask, reg;390 391	if (severity == REGULATOR_SEVERITY_PROT) {392		if (!enable || lim_uV)393			return -EINVAL;394		return 0;395	}396 397	/*398	 * BD9576 has enable control as a special value in limit reg. Can't399	 * set limit but keep feature disabled or enable W/O given limit.400	 */401	if ((lim_uV && !enable) || (!lim_uV && enable))402		return -EINVAL;403 404	r = container_of(rdev->desc, struct bd957x_regulator_data, desc);405	d = rdev_get_drvdata(rdev);406 407	mask = r->xvd_mask;408	reg = r->uvd_reg;409	/*410	 * Check that there is no mismatch for what the detection IRQs are to411	 * be used.412	 */413	if (r->uvd_notif) {414		if (check_uvd_flag_mismatch(rdev, severity, r))415			return 0;416	} else {417		bd9576_fill_uvd_flags(r, severity == REGULATOR_SEVERITY_WARN);418	}419 420	return bd9576_set_limit(r->xvd_ranges, r->num_xvd_ranges, d->regmap,421				reg, mask, lim_uV);422}423 424static int bd9576_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity,425			  bool enable)426{427	struct bd957x_data *d;428	struct bd957x_regulator_data *r;429	int mask, reg;430 431	if (severity == REGULATOR_SEVERITY_PROT) {432		if (!enable || lim_uV)433			return -EINVAL;434		return 0;435	}436 437	/*438	 * BD9576 has enable control as a special value in limit reg. Can't439	 * set limit but keep feature disabled or enable W/O given limit.440	 */441	if ((lim_uV && !enable) || (!lim_uV && enable))442		return -EINVAL;443 444	r = container_of(rdev->desc, struct bd957x_regulator_data, desc);445	d = rdev_get_drvdata(rdev);446 447	mask = r->xvd_mask;448	reg = r->ovd_reg;449	/*450	 * Check that there is no mismatch for what the detection IRQs are to451	 * be used.452	 */453	if (r->ovd_notif) {454		if (check_ovd_flag_mismatch(rdev, severity, r))455			return 0;456	} else {457		bd9576_fill_ovd_flags(r, severity == REGULATOR_SEVERITY_WARN);458	}459 460	return bd9576_set_limit(r->xvd_ranges, r->num_xvd_ranges, d->regmap,461				reg, mask, lim_uV);462}463 464 465static int bd9576_set_tw(struct regulator_dev *rdev, int lim, int severity,466			  bool enable)467{468	struct bd957x_data *d;469	struct bd957x_regulator_data *r;470	int i;471 472	/*473	 * BD9576MUF has fixed temperature limits474	 * The detection can only be enabled/disabled475	 */476	if (lim)477		return -EINVAL;478 479	/* Protection can't be disabled */480	if (severity == REGULATOR_SEVERITY_PROT) {481		if (!enable)482			return -EINVAL;483		else484			return 0;485	}486 487	r = container_of(rdev->desc, struct bd957x_regulator_data, desc);488	d = rdev_get_drvdata(rdev);489 490	/*491	 * Check that there is no mismatch for what the detection IRQs are to492	 * be used.493	 */494	if (r->temp_notif)495		if (check_temp_flag_mismatch(rdev, severity, r))496			return 0;497 498	bd9576_fill_temp_flags(r, enable, severity == REGULATOR_SEVERITY_WARN);499 500	if (enable)501		return regmap_update_bits(d->regmap, BD957X_REG_INT_THERM_MASK,502					 BD9576_THERM_IRQ_MASK_TW, 0);503 504	/*505	 * If any of the regulators is interested in thermal warning we keep IRQ506	 * enabled.507	 */508	for (i = 0; i < BD9576_NUM_REGULATORS; i++)509		if (d->regulator_data[i].temp_notif)510			return 0;511 512	return regmap_update_bits(d->regmap, BD957X_REG_INT_THERM_MASK,513				  BD9576_THERM_IRQ_MASK_TW,514				  BD9576_THERM_IRQ_MASK_TW);515}516 517static const struct regulator_ops bd9573_vout34_ops = {518	.is_enabled = regulator_is_enabled_regmap,519	.list_voltage = bd957x_vout34_list_voltage,520	.get_voltage_sel = regulator_get_voltage_sel_regmap,521};522 523static const struct regulator_ops bd9576_vout34_ops = {524	.is_enabled = regulator_is_enabled_regmap,525	.list_voltage = bd957x_vout34_list_voltage,526	.get_voltage_sel = regulator_get_voltage_sel_regmap,527	.set_over_voltage_protection = bd9576_set_ovp,528	.set_under_voltage_protection = bd9576_set_uvp,529	.set_thermal_protection = bd9576_set_tw,530};531 532static const struct regulator_ops bd9573_vouts1_regulator_ops = {533	.is_enabled = regulator_is_enabled_regmap,534};535 536static const struct regulator_ops bd9576_vouts1_regulator_ops = {537	.is_enabled = regulator_is_enabled_regmap,538	.set_over_current_protection = bd9576_set_ocp,539};540 541static const struct regulator_ops bd9573_ops = {542	.is_enabled = regulator_is_enabled_regmap,543	.list_voltage = bd957x_list_voltage,544	.get_voltage_sel = regulator_get_voltage_sel_regmap,545};546 547static const struct regulator_ops bd9576_ops = {548	.is_enabled = regulator_is_enabled_regmap,549	.list_voltage = bd957x_list_voltage,550	.get_voltage_sel = regulator_get_voltage_sel_regmap,551	.set_over_voltage_protection = bd9576_set_ovp,552	.set_under_voltage_protection = bd9576_set_uvp,553	.set_thermal_protection = bd9576_set_tw,554};555 556static const struct regulator_ops  *bd9573_ops_arr[] = {557	[BD957X_VD50]	= &bd9573_ops,558	[BD957X_VD18]	= &bd9573_ops,559	[BD957X_VDDDR]	= &bd9573_vout34_ops,560	[BD957X_VD10]	= &bd9573_vout34_ops,561	[BD957X_VOUTL1]	= &bd9573_ops,562	[BD957X_VOUTS1]	= &bd9573_vouts1_regulator_ops,563};564 565static const struct regulator_ops  *bd9576_ops_arr[] = {566	[BD957X_VD50]	= &bd9576_ops,567	[BD957X_VD18]	= &bd9576_ops,568	[BD957X_VDDDR]	= &bd9576_vout34_ops,569	[BD957X_VD10]	= &bd9576_vout34_ops,570	[BD957X_VOUTL1]	= &bd9576_ops,571	[BD957X_VOUTS1]	= &bd9576_vouts1_regulator_ops,572};573 574static int vouts1_get_fet_res(struct device_node *np,575				const struct regulator_desc *desc,576				struct regulator_config *cfg)577{578	struct bd957x_regulator_data *data;579	int ret;580	u32 uohms;581 582	data = container_of(desc, struct bd957x_regulator_data, desc);583 584	ret = of_property_read_u32(np, "rohm,ocw-fet-ron-micro-ohms", &uohms);585	if (ret) {586		if (ret != -EINVAL)587			return ret;588 589		return 0;590	}591	data->ocw_rfet = uohms;592	return 0;593}594 595static struct bd957x_data bd957x_regulators = {596	.regulator_data = {597		{598			.desc = {599				.name = "VD50",600				.of_match = of_match_ptr("regulator-vd50"),601				.regulators_node = of_match_ptr("regulators"),602				.id = BD957X_VD50,603				.type = REGULATOR_VOLTAGE,604				.volt_table = &vout1_volt_table[0],605				.n_voltages = ARRAY_SIZE(vout1_volt_table),606				.vsel_reg = BD957X_REG_VOUT1_TUNE,607				.vsel_mask = BD957X_MASK_VOUT1_TUNE,608				.enable_reg = BD957X_REG_POW_TRIGGER1,609				.enable_mask = BD957X_REGULATOR_EN_MASK,610				.enable_val = BD957X_REGULATOR_DIS_VAL,611				.enable_is_inverted = true,612				.owner = THIS_MODULE,613			},614			.xvd_ranges = vout1_xvd_ranges,615			.num_xvd_ranges = ARRAY_SIZE(vout1_xvd_ranges),616			.ovd_reg = BD9576_REG_VOUT1_OVD,617			.uvd_reg = BD9576_REG_VOUT1_UVD,618			.xvd_mask = BD9576_MASK_XVD,619		},620		{621			.desc = {622				.name = "VD18",623				.of_match = of_match_ptr("regulator-vd18"),624				.regulators_node = of_match_ptr("regulators"),625				.id = BD957X_VD18,626				.type = REGULATOR_VOLTAGE,627				.volt_table = &vout2_volt_table[0],628				.n_voltages = ARRAY_SIZE(vout2_volt_table),629				.vsel_reg = BD957X_REG_VOUT2_TUNE,630				.vsel_mask = BD957X_MASK_VOUT2_TUNE,631				.enable_reg = BD957X_REG_POW_TRIGGER2,632				.enable_mask = BD957X_REGULATOR_EN_MASK,633				.enable_val = BD957X_REGULATOR_DIS_VAL,634				.enable_is_inverted = true,635				.owner = THIS_MODULE,636			},637			.xvd_ranges = vout234_xvd_ranges,638			.num_xvd_ranges = ARRAY_SIZE(vout234_xvd_ranges),639			.ovd_reg = BD9576_REG_VOUT2_OVD,640			.uvd_reg = BD9576_REG_VOUT2_UVD,641			.xvd_mask = BD9576_MASK_XVD,642		},643		{644			.desc = {645				.name = "VDDDR",646				.of_match = of_match_ptr("regulator-vdddr"),647				.regulators_node = of_match_ptr("regulators"),648				.id = BD957X_VDDDR,649				.type = REGULATOR_VOLTAGE,650				.n_voltages = BD957X_VOUTS34_NUM_VOLT,651				.vsel_reg = BD957X_REG_VOUT3_TUNE,652				.vsel_mask = BD957X_MASK_VOUT3_TUNE,653				.enable_reg = BD957X_REG_POW_TRIGGER3,654				.enable_mask = BD957X_REGULATOR_EN_MASK,655				.enable_val = BD957X_REGULATOR_DIS_VAL,656				.enable_is_inverted = true,657				.owner = THIS_MODULE,658			},659			.ovd_reg = BD9576_REG_VOUT3_OVD,660			.uvd_reg = BD9576_REG_VOUT3_UVD,661			.xvd_mask = BD9576_MASK_XVD,662			.xvd_ranges = vout234_xvd_ranges,663			.num_xvd_ranges = ARRAY_SIZE(vout234_xvd_ranges),664		},665		{666			.desc = {667				.name = "VD10",668				.of_match = of_match_ptr("regulator-vd10"),669				.regulators_node = of_match_ptr("regulators"),670				.id = BD957X_VD10,671				.type = REGULATOR_VOLTAGE,672				.fixed_uV = BD957X_VOUTS4_BASE_VOLT,673				.n_voltages = BD957X_VOUTS34_NUM_VOLT,674				.vsel_reg = BD957X_REG_VOUT4_TUNE,675				.vsel_mask = BD957X_MASK_VOUT4_TUNE,676				.enable_reg = BD957X_REG_POW_TRIGGER4,677				.enable_mask = BD957X_REGULATOR_EN_MASK,678				.enable_val = BD957X_REGULATOR_DIS_VAL,679				.enable_is_inverted = true,680				.owner = THIS_MODULE,681			},682			.xvd_ranges = vout234_xvd_ranges,683			.num_xvd_ranges = ARRAY_SIZE(vout234_xvd_ranges),684			.ovd_reg = BD9576_REG_VOUT4_OVD,685			.uvd_reg = BD9576_REG_VOUT4_UVD,686			.xvd_mask = BD9576_MASK_XVD,687		},688		{689			.desc = {690				.name = "VOUTL1",691				.of_match = of_match_ptr("regulator-voutl1"),692				.regulators_node = of_match_ptr("regulators"),693				.id = BD957X_VOUTL1,694				.type = REGULATOR_VOLTAGE,695				.volt_table = &voutl1_volt_table[0],696				.n_voltages = ARRAY_SIZE(voutl1_volt_table),697				.vsel_reg = BD957X_REG_VOUTL1_TUNE,698				.vsel_mask = BD957X_MASK_VOUTL1_TUNE,699				.enable_reg = BD957X_REG_POW_TRIGGERL1,700				.enable_mask = BD957X_REGULATOR_EN_MASK,701				.enable_val = BD957X_REGULATOR_DIS_VAL,702				.enable_is_inverted = true,703				.owner = THIS_MODULE,704			},705			.xvd_ranges = voutL1_xvd_ranges,706			.num_xvd_ranges = ARRAY_SIZE(voutL1_xvd_ranges),707			.ovd_reg = BD9576_REG_VOUTL1_OVD,708			.uvd_reg = BD9576_REG_VOUTL1_UVD,709			.xvd_mask = BD9576_MASK_XVD,710		},711		{712			.desc = {713				.name = "VOUTS1",714				.of_match = of_match_ptr("regulator-vouts1"),715				.regulators_node = of_match_ptr("regulators"),716				.id = BD957X_VOUTS1,717				.type = REGULATOR_VOLTAGE,718				.n_voltages = 1,719				.fixed_uV = BD957X_VOUTS1_VOLT,720				.enable_reg = BD957X_REG_POW_TRIGGERS1,721				.enable_mask = BD957X_REGULATOR_EN_MASK,722				.enable_val = BD957X_REGULATOR_DIS_VAL,723				.enable_is_inverted = true,724				.owner = THIS_MODULE,725				.of_parse_cb = vouts1_get_fet_res,726			},727			.oc_supported = true,728			.ocw_reg = BD9576_REG_VOUT1S_OCW,729			.ocw_mask = BD9576_MASK_VOUT1S_OCW,730			.ocp_reg = BD9576_REG_VOUT1S_OCP,731			.ocp_mask = BD9576_MASK_VOUT1S_OCP,732		},733	},734};735 736static int bd9576_renable(struct regulator_irq_data *rid, int reg, int mask)737{738	int val, ret;739	struct bd957x_data *d = (struct bd957x_data *)rid->data;740 741	ret = regmap_read(d->regmap, reg, &val);742	if (ret)743		return REGULATOR_FAILED_RETRY;744 745	if (rid->opaque && rid->opaque == (val & mask)) {746		/*747		 * It seems we stil have same status. Ack and return748		 * information that we are still out of limits and core749		 * should not enable IRQ750		 */751		regmap_write(d->regmap, reg, mask & val);752		return REGULATOR_ERROR_ON;753	}754	rid->opaque = 0;755	/*756	 * Status was changed. Either prolem was solved or we have new issues.757	 * Let's re-enable IRQs and be prepared to report problems again758	 */759	return REGULATOR_ERROR_CLEARED;760}761 762static int bd9576_uvd_renable(struct regulator_irq_data *rid)763{764	return bd9576_renable(rid, BD957X_REG_INT_UVD_STAT, UVD_IRQ_VALID_MASK);765}766 767static int bd9576_ovd_renable(struct regulator_irq_data *rid)768{769	return bd9576_renable(rid, BD957X_REG_INT_OVD_STAT, OVD_IRQ_VALID_MASK);770}771 772static int bd9576_temp_renable(struct regulator_irq_data *rid)773{774	return bd9576_renable(rid, BD957X_REG_INT_THERM_STAT,775			      BD9576_THERM_IRQ_MASK_TW);776}777 778static int bd9576_uvd_handler(int irq, struct regulator_irq_data *rid,779			      unsigned long *dev_mask)780{781	int val, ret, i;782	struct bd957x_data *d = (struct bd957x_data *)rid->data;783 784	ret = regmap_read(d->regmap, BD957X_REG_INT_UVD_STAT, &val);785	if (ret)786		return REGULATOR_FAILED_RETRY;787 788	*dev_mask = 0;789 790	rid->opaque = val & UVD_IRQ_VALID_MASK;791 792	/*793	 * Go through the set status bits and report either error or warning794	 * to the notifier depending on what was flagged in DT795	 */796	*dev_mask = val & BD9576_xVD_IRQ_MASK_VOUT1TO4;797	/* There is 1 bit gap in register after Vout1 .. Vout4 statuses */798	*dev_mask |= ((val & BD9576_xVD_IRQ_MASK_VOUTL1) >> 1);799	/*800	 * We (ab)use the uvd for OCW notification. DT parsing should801	 * have added correct OCW flag to uvd_notif and uvd_err for S1802	 */803	*dev_mask |= ((val & BD9576_UVD_IRQ_MASK_VOUTS1_OCW) >> 1);804 805	for_each_set_bit(i, dev_mask, 6) {806		struct bd957x_regulator_data *rdata;807		struct regulator_err_state *stat;808 809		rdata = &d->regulator_data[i];810		stat  = &rid->states[i];811 812		stat->notifs	= rdata->uvd_notif;813		stat->errors	= rdata->uvd_err;814	}815 816	ret = regmap_write(d->regmap, BD957X_REG_INT_UVD_STAT,817			   UVD_IRQ_VALID_MASK & val);818 819	return 0;820}821 822static int bd9576_ovd_handler(int irq, struct regulator_irq_data *rid,823			      unsigned long *dev_mask)824{825	int val, ret, i;826	struct bd957x_data *d = (struct bd957x_data *)rid->data;827 828	ret = regmap_read(d->regmap, BD957X_REG_INT_OVD_STAT, &val);829	if (ret)830		return REGULATOR_FAILED_RETRY;831 832	rid->opaque = val & OVD_IRQ_VALID_MASK;833	*dev_mask = 0;834 835	if (!(val & OVD_IRQ_VALID_MASK))836		return 0;837 838	*dev_mask = val & BD9576_xVD_IRQ_MASK_VOUT1TO4;839	/* There is 1 bit gap in register after Vout1 .. Vout4 statuses */840	*dev_mask |= ((val & BD9576_xVD_IRQ_MASK_VOUTL1) >> 1);841 842	for_each_set_bit(i, dev_mask, 5) {843		struct bd957x_regulator_data *rdata;844		struct regulator_err_state *stat;845 846		rdata = &d->regulator_data[i];847		stat  = &rid->states[i];848 849		stat->notifs	= rdata->ovd_notif;850		stat->errors	= rdata->ovd_err;851	}852 853	/* Clear the sub-IRQ status */854	regmap_write(d->regmap, BD957X_REG_INT_OVD_STAT,855		     OVD_IRQ_VALID_MASK & val);856 857	return 0;858}859 860#define BD9576_DEV_MASK_ALL_REGULATORS 0x3F861 862static int bd9576_thermal_handler(int irq, struct regulator_irq_data *rid,863				  unsigned long *dev_mask)864{865	int val, ret, i;866	struct bd957x_data *d = (struct bd957x_data *)rid->data;867 868	ret = regmap_read(d->regmap, BD957X_REG_INT_THERM_STAT, &val);869	if (ret)870		return REGULATOR_FAILED_RETRY;871 872	if (!(val & BD9576_THERM_IRQ_MASK_TW)) {873		*dev_mask = 0;874		return 0;875	}876 877	*dev_mask = BD9576_DEV_MASK_ALL_REGULATORS;878 879	for (i = 0; i < BD9576_NUM_REGULATORS; i++) {880		struct bd957x_regulator_data *rdata;881		struct regulator_err_state *stat;882 883		rdata = &d->regulator_data[i];884		stat  = &rid->states[i];885 886		stat->notifs	= rdata->temp_notif;887		stat->errors	= rdata->temp_err;888	}889 890	/* Clear the sub-IRQ status */891	regmap_write(d->regmap, BD957X_REG_INT_THERM_STAT,892		     BD9576_THERM_IRQ_MASK_TW);893 894	return 0;895}896 897static int bd957x_probe(struct platform_device *pdev)898{899	int i;900	unsigned int num_reg_data;901	bool vout_mode, ddr_sel, may_have_irqs = false;902	struct regmap *regmap;903	struct bd957x_data *ic_data;904	struct regulator_config config = { 0 };905	/* All regulators are related to UVD and thermal IRQs... */906	struct regulator_dev *rdevs[BD9576_NUM_REGULATORS];907	/* ...But VoutS1 is not flagged by OVD IRQ */908	struct regulator_dev *ovd_devs[BD9576_NUM_OVD_REGULATORS];909	static const struct regulator_irq_desc bd9576_notif_uvd = {910		.name = "bd9576-uvd",911		.irq_off_ms = 1000,912		.map_event = bd9576_uvd_handler,913		.renable = bd9576_uvd_renable,914		.data = &bd957x_regulators,915	};916	static const struct regulator_irq_desc bd9576_notif_ovd = {917		.name = "bd9576-ovd",918		.irq_off_ms = 1000,919		.map_event = bd9576_ovd_handler,920		.renable = bd9576_ovd_renable,921		.data = &bd957x_regulators,922	};923	static const struct regulator_irq_desc bd9576_notif_temp = {924		.name = "bd9576-temp",925		.irq_off_ms = 1000,926		.map_event = bd9576_thermal_handler,927		.renable = bd9576_temp_renable,928		.data = &bd957x_regulators,929	};930	enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;931 932	num_reg_data = ARRAY_SIZE(bd957x_regulators.regulator_data);933 934	ic_data = &bd957x_regulators;935 936	regmap = dev_get_regmap(pdev->dev.parent, NULL);937	if (!regmap) {938		dev_err(&pdev->dev, "No regmap\n");939		return -EINVAL;940	}941 942	ic_data->regmap = regmap;943	vout_mode = device_property_read_bool(pdev->dev.parent,944					      "rohm,vout1-en-low");945	if (vout_mode) {946		struct gpio_desc *en;947 948		dev_dbg(&pdev->dev, "GPIO controlled mode\n");949 950		/* VOUT1 enable state judged by VOUT1_EN pin */951		/* See if we have GPIO defined */952		en = devm_fwnode_gpiod_get(&pdev->dev,953					   dev_fwnode(pdev->dev.parent),954					   "rohm,vout1-en", GPIOD_OUT_LOW,955					   "vout1-en");956 957		/* VOUT1_OPS gpio ctrl */958		/*959		 * Regulator core prioritizes the ena_gpio over960		 * enable/disable/is_enabled callbacks so no need to clear them961		 * even if GPIO is used. So, we can still use same ops.962		 *963		 * In theory it is possible someone wants to set vout1-en LOW964		 * during OTP loading and set VOUT1 to be controlled by GPIO -965		 * but control the GPIO from some where else than this driver.966		 * For that to work we should unset the is_enabled callback967		 * here.968		 *969		 * I believe such case where rohm,vout1-en-low is set and970		 * vout1-en-gpios is not is likely to be a misconfiguration.971		 * So let's just err out for now.972		 */973		if (!IS_ERR(en))974			config.ena_gpiod = en;975		else976			return dev_err_probe(&pdev->dev, PTR_ERR(en),977					"Failed to get VOUT1 control GPIO\n");978	}979 980	/*981	 * If more than one PMIC needs to be controlled by same processor then982	 * allocate the regulator data array here and use bd9576_regulators as983	 * template. At the moment I see no such use-case so I spare some984	 * bytes and use bd9576_regulators directly for non-constant configs985	 * like DDR voltage selection.986	 */987	platform_set_drvdata(pdev, ic_data);988	ddr_sel = device_property_read_bool(pdev->dev.parent,989					    "rohm,ddr-sel-low");990	if (ddr_sel)991		ic_data->regulator_data[2].desc.fixed_uV = 1350000;992	else993		ic_data->regulator_data[2].desc.fixed_uV = 1500000;994 995	switch (chip) {996	case ROHM_CHIP_TYPE_BD9576:997		may_have_irqs = true;998		dev_dbg(&pdev->dev, "Found BD9576MUF\n");999		break;1000	case ROHM_CHIP_TYPE_BD9573:1001		dev_dbg(&pdev->dev, "Found BD9573MUF\n");1002		break;1003	default:1004		dev_err(&pdev->dev, "Unsupported chip type\n");1005		return -EINVAL;1006	}1007 1008	for (i = 0; i < num_reg_data; i++) {1009		struct regulator_desc *d;1010 1011		d = &ic_data->regulator_data[i].desc;1012 1013 1014		if (may_have_irqs) {1015			if (d->id >= ARRAY_SIZE(bd9576_ops_arr))1016				return -EINVAL;1017 1018			d->ops = bd9576_ops_arr[d->id];1019		} else {1020			if (d->id >= ARRAY_SIZE(bd9573_ops_arr))1021				return -EINVAL;1022 1023			d->ops = bd9573_ops_arr[d->id];1024		}1025	}1026 1027	config.dev = pdev->dev.parent;1028	config.regmap = regmap;1029	config.driver_data = ic_data;1030 1031	for (i = 0; i < num_reg_data; i++) {1032 1033		struct bd957x_regulator_data *r = &ic_data->regulator_data[i];1034		const struct regulator_desc *desc = &r->desc;1035 1036		r->rdev = devm_regulator_register(&pdev->dev, desc,1037							   &config);1038		if (IS_ERR(r->rdev))1039			return dev_err_probe(&pdev->dev, PTR_ERR(r->rdev),1040					"failed to register %s regulator\n",1041					desc->name);1042		/*1043		 * Clear the VOUT1 GPIO setting - rest of the regulators do not1044		 * support GPIO control1045		 */1046		config.ena_gpiod = NULL;1047 1048		if (!may_have_irqs)1049			continue;1050 1051		rdevs[i] = r->rdev;1052		if (i < BD957X_VOUTS1)1053			ovd_devs[i] = r->rdev;1054	}1055	if (may_have_irqs) {1056		void *ret;1057		/*1058		 * We can add both the possible error and warning flags here1059		 * because the core uses these only for status clearing and1060		 * if we use warnings - errors are always clear and the other1061		 * way around. We can also add CURRENT flag for all regulators1062		 * because it is never set if it is not supported. Same applies1063		 * to setting UVD for VoutS1 - it is not accidentally cleared1064		 * as it is never set.1065		 */1066		int uvd_errs = REGULATOR_ERROR_UNDER_VOLTAGE |1067			       REGULATOR_ERROR_UNDER_VOLTAGE_WARN |1068			       REGULATOR_ERROR_OVER_CURRENT |1069			       REGULATOR_ERROR_OVER_CURRENT_WARN;1070		int ovd_errs = REGULATOR_ERROR_OVER_VOLTAGE_WARN |1071			       REGULATOR_ERROR_REGULATION_OUT;1072		int temp_errs = REGULATOR_ERROR_OVER_TEMP |1073				REGULATOR_ERROR_OVER_TEMP_WARN;1074		int irq;1075 1076		irq = platform_get_irq_byname(pdev, "bd9576-uvd");1077 1078		/* Register notifiers - can fail if IRQ is not given */1079		ret = devm_regulator_irq_helper(&pdev->dev, &bd9576_notif_uvd,1080						irq, 0, uvd_errs, NULL,1081						&rdevs[0],1082						BD9576_NUM_REGULATORS);1083		if (IS_ERR(ret)) {1084			if (PTR_ERR(ret) == -EPROBE_DEFER)1085				return -EPROBE_DEFER;1086 1087			dev_warn(&pdev->dev, "UVD disabled %pe\n", ret);1088		}1089 1090		irq = platform_get_irq_byname(pdev, "bd9576-ovd");1091 1092		ret = devm_regulator_irq_helper(&pdev->dev, &bd9576_notif_ovd,1093						irq, 0, ovd_errs, NULL,1094						&ovd_devs[0],1095						BD9576_NUM_OVD_REGULATORS);1096		if (IS_ERR(ret)) {1097			if (PTR_ERR(ret) == -EPROBE_DEFER)1098				return -EPROBE_DEFER;1099 1100			dev_warn(&pdev->dev, "OVD disabled %pe\n", ret);1101		}1102		irq = platform_get_irq_byname(pdev, "bd9576-temp");1103 1104		ret = devm_regulator_irq_helper(&pdev->dev, &bd9576_notif_temp,1105						irq, 0, temp_errs, NULL,1106						&rdevs[0],1107						BD9576_NUM_REGULATORS);1108		if (IS_ERR(ret)) {1109			if (PTR_ERR(ret) == -EPROBE_DEFER)1110				return -EPROBE_DEFER;1111 1112			dev_warn(&pdev->dev, "Thermal warning disabled %pe\n",1113				 ret);1114		}1115	}1116	return 0;1117}1118 1119static const struct platform_device_id bd957x_pmic_id[] = {1120	{ "bd9573-regulator", ROHM_CHIP_TYPE_BD9573 },1121	{ "bd9576-regulator", ROHM_CHIP_TYPE_BD9576 },1122	{ },1123};1124MODULE_DEVICE_TABLE(platform, bd957x_pmic_id);1125 1126static struct platform_driver bd957x_regulator = {1127	.driver = {1128		.name = "bd957x-pmic",1129		.probe_type = PROBE_PREFER_ASYNCHRONOUS,1130	},1131	.probe = bd957x_probe,1132	.id_table = bd957x_pmic_id,1133};1134 1135module_platform_driver(bd957x_regulator);1136 1137MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");1138MODULE_DESCRIPTION("ROHM BD9576/BD9573 voltage regulator driver");1139MODULE_LICENSE("GPL");1140MODULE_ALIAS("platform:bd957x-pmic");1141