brintos

brintos / linux-shallow public Read only

0
0
Text · 16.2 KiB · 4a568b1 Raw
656 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Device driver for regulators in MAX5970 and MAX5978 IC4 *5 * Copyright (c) 2022 9elements GmbH6 *7 * Author: Patrick Rudolph <patrick.rudolph@9elements.com>8 */9 10#include <linux/bitops.h>11#include <linux/device.h>12#include <linux/err.h>13#include <linux/hwmon.h>14#include <linux/module.h>15#include <linux/io.h>16#include <linux/of.h>17#include <linux/i2c.h>18#include <linux/regmap.h>19#include <linux/regulator/driver.h>20#include <linux/regulator/machine.h>21#include <linux/regulator/of_regulator.h>22#include <linux/platform_device.h>23 24#include <linux/mfd/max5970.h>25 26struct max5970_regulator {27	int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA;28	struct regmap *regmap;29};30 31enum max597x_regulator_id {32	MAX597X_sw0,33	MAX597X_sw1,34};35 36static int max5970_read_adc(struct regmap *regmap, int reg, long *val)37{38	u8 reg_data[2];39	int ret;40 41	ret = regmap_bulk_read(regmap, reg, &reg_data[0], 2);42	if (ret < 0)43		return ret;44 45	*val = (reg_data[0] << 2) | (reg_data[1] & 3);46 47	return 0;48}49 50static int max5970_read(struct device *dev, enum hwmon_sensor_types type,51			u32 attr, int channel, long *val)52{53	struct regulator_dev **rdevs = dev_get_drvdata(dev);54	struct max5970_regulator *ddata = rdev_get_drvdata(rdevs[channel]);55	struct regmap *regmap = ddata->regmap;56	int ret;57 58	switch (type) {59	case hwmon_curr:60		switch (attr) {61		case hwmon_curr_input:62			ret = max5970_read_adc(regmap, MAX5970_REG_CURRENT_H(channel), val);63			if (ret < 0)64				return ret;65			/*66			 * Calculate current from ADC value, IRNG range & shunt resistor value.67			 * ddata->irng holds the voltage corresponding to the maximum value the68			 * 10-bit ADC can measure.69			 * To obtain the output, multiply the ADC value by the IRNG range (in70			 * millivolts) and then divide it by the maximum value of the 10-bit ADC.71			 */72			*val = (*val * ddata->irng) >> 10;73			/* Convert the voltage measurement across shunt resistor to current */74			*val = (*val * 1000) / ddata->shunt_micro_ohms;75			return 0;76		default:77			return -EOPNOTSUPP;78		}79 80	case hwmon_in:81		switch (attr) {82		case hwmon_in_input:83			ret = max5970_read_adc(regmap, MAX5970_REG_VOLTAGE_H(channel), val);84			if (ret < 0)85				return ret;86			/*87			 * Calculate voltage from ADC value and MON range.88			 * ddata->mon_rng holds the voltage corresponding to the maximum value the89			 * 10-bit ADC can measure.90			 * To obtain the output, multiply the ADC value by the MON range (in91			 * microvolts) and then divide it by the maximum value of the 10-bit ADC.92			 */93			*val = mul_u64_u32_shr(*val, ddata->mon_rng, 10);94			/* uV to mV */95			*val = *val / 1000;96			return 0;97		default:98			return -EOPNOTSUPP;99		}100	default:101		return -EOPNOTSUPP;102	}103}104 105static umode_t max5970_is_visible(const void *data,106				  enum hwmon_sensor_types type,107				  u32 attr, int channel)108{109	struct regulator_dev **rdevs = (struct regulator_dev **)data;110	struct max5970_regulator *ddata;111 112	if (channel >= MAX5970_NUM_SWITCHES || !rdevs[channel])113		return 0;114 115	ddata = rdev_get_drvdata(rdevs[channel]);116 117	if (channel >= ddata->num_switches)118		return 0;119 120	switch (type) {121	case hwmon_in:122		switch (attr) {123		case hwmon_in_input:124			return 0444;125		default:126			break;127		}128		break;129	case hwmon_curr:130		switch (attr) {131		case hwmon_curr_input:132			/* Current measurement requires knowledge of the shunt resistor value. */133			if (ddata->shunt_micro_ohms)134				return 0444;135			break;136		default:137			break;138		}139		break;140	default:141		break;142	}143	return 0;144}145 146static const struct hwmon_ops max5970_hwmon_ops = {147	.is_visible = max5970_is_visible,148	.read = max5970_read,149};150 151static const struct hwmon_channel_info *max5970_info[] = {152	HWMON_CHANNEL_INFO(in, HWMON_I_INPUT, HWMON_I_INPUT),153	HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT, HWMON_C_INPUT),154	NULL155};156 157static const struct hwmon_chip_info max5970_chip_info = {158	.ops = &max5970_hwmon_ops,159	.info = max5970_info,160};161 162static int max597x_uvp_ovp_check_mode(struct regulator_dev *rdev, int severity)163{164	int ret, reg;165 166	/* Status1 register contains the soft strap values sampled at POR */167	ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS1, &reg);168	if (ret)169		return ret;170 171	/* Check soft straps match requested mode */172	if (severity == REGULATOR_SEVERITY_PROT) {173		if (STATUS1_PROT(reg) != STATUS1_PROT_SHUTDOWN)174			return -EOPNOTSUPP;175 176		return 0;177	}178	if (STATUS1_PROT(reg) == STATUS1_PROT_SHUTDOWN)179		return -EOPNOTSUPP;180 181	return 0;182}183 184static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity,185			  bool enable, bool overvoltage)186{187	int off_h, off_l, reg, ret;188	struct max5970_regulator *data = rdev_get_drvdata(rdev);189	int channel = rdev_get_id(rdev);190 191	if (overvoltage) {192		if (severity == REGULATOR_SEVERITY_WARN) {193			off_h = MAX5970_REG_CH_OV_WARN_H(channel);194			off_l = MAX5970_REG_CH_OV_WARN_L(channel);195		} else {196			off_h = MAX5970_REG_CH_OV_CRIT_H(channel);197			off_l = MAX5970_REG_CH_OV_CRIT_L(channel);198		}199	} else {200		if (severity == REGULATOR_SEVERITY_WARN) {201			off_h = MAX5970_REG_CH_UV_WARN_H(channel);202			off_l = MAX5970_REG_CH_UV_WARN_L(channel);203		} else {204			off_h = MAX5970_REG_CH_UV_CRIT_H(channel);205			off_l = MAX5970_REG_CH_UV_CRIT_L(channel);206		}207	}208 209	if (enable)210		/* reg = ADC_MASK * (lim_uV / 1000000) / (data->mon_rng / 1000000) */211		reg = ADC_MASK * lim_uV / data->mon_rng;212	else213		reg = 0;214 215	ret = regmap_write(rdev->regmap, off_h, MAX5970_VAL2REG_H(reg));216	if (ret)217		return ret;218 219	ret = regmap_write(rdev->regmap, off_l, MAX5970_VAL2REG_L(reg));220	if (ret)221		return ret;222 223	return 0;224}225 226static int max597x_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity,227			   bool enable)228{229	int ret;230 231	/*232	 * MAX5970 has enable control as a special value in limit reg. Can't233	 * set limit but keep feature disabled or enable W/O given limit.234	 */235	if ((lim_uV && !enable) || (!lim_uV && enable))236		return -EINVAL;237 238	ret = max597x_uvp_ovp_check_mode(rdev, severity);239	if (ret)240		return ret;241 242	return max597x_set_vp(rdev, lim_uV, severity, enable, false);243}244 245static int max597x_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity,246			   bool enable)247{248	int ret;249 250	/*251	 * MAX5970 has enable control as a special value in limit reg. Can't252	 * set limit but keep feature disabled or enable W/O given limit.253	 */254	if ((lim_uV && !enable) || (!lim_uV && enable))255		return -EINVAL;256 257	ret = max597x_uvp_ovp_check_mode(rdev, severity);258	if (ret)259		return ret;260 261	return max597x_set_vp(rdev, lim_uV, severity, enable, true);262}263 264static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA,265			   int severity, bool enable)266{267	int val, reg;268	unsigned int vthst, vthfst;269 270	struct max5970_regulator *data = rdev_get_drvdata(rdev);271	int rdev_id = rdev_get_id(rdev);272	/*273	 * MAX5970 doesn't has enable control for ocp.274	 * If limit is specified but enable is not set then hold the value in275	 * variable & later use it when ocp needs to be enabled.276	 */277	if (lim_uA != 0 && lim_uA != data->lim_uA)278		data->lim_uA = lim_uA;279 280	if (severity != REGULATOR_SEVERITY_PROT)281		return -EINVAL;282 283	if (enable) {284 285		/* Calc Vtrip threshold in uV. */286		vthst =287		    div_u64(mul_u32_u32(data->shunt_micro_ohms, data->lim_uA),288			    1000000);289 290		/*291		 * As recommended in datasheed, add 20% margin to avoid292		 * spurious event & passive component tolerance.293		 */294		vthst = div_u64(mul_u32_u32(vthst, 120), 100);295 296		/* Calc fast Vtrip threshold in uV */297		vthfst = vthst * (MAX5970_FAST2SLOW_RATIO / 100);298 299		if (vthfst > data->irng) {300			dev_err(&rdev->dev, "Current limit out of range\n");301			return -EINVAL;302		}303		/* Fast trip threshold to be programmed */304		val = div_u64(mul_u32_u32(0xFF, vthfst), data->irng);305	} else306		/*307		 * Since there is no option to disable ocp, set limit to max308		 * value309		 */310		val = 0xFF;311 312	reg = MAX5970_REG_DAC_FAST(rdev_id);313 314	return regmap_write(rdev->regmap, reg, val);315}316 317static int max597x_get_status(struct regulator_dev *rdev)318{319	int val, ret;320 321	ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS3, &val);322	if (ret)323		return ret;324 325	if (val & MAX5970_STATUS3_ALERT)326		return REGULATOR_STATUS_ERROR;327 328	ret = regulator_is_enabled_regmap(rdev);329	if (ret < 0)330		return ret;331 332	if (ret)333		return REGULATOR_STATUS_ON;334 335	return REGULATOR_STATUS_OFF;336}337 338static const struct regulator_ops max597x_switch_ops = {339	.enable = regulator_enable_regmap,340	.disable = regulator_disable_regmap,341	.is_enabled = regulator_is_enabled_regmap,342	.get_status = max597x_get_status,343	.set_over_voltage_protection = max597x_set_ovp,344	.set_under_voltage_protection = max597x_set_uvp,345	.set_over_current_protection = max597x_set_ocp,346};347 348static int max597x_dt_parse(struct device_node *np,349			    const struct regulator_desc *desc,350			    struct regulator_config *cfg)351{352	struct max5970_regulator *data = cfg->driver_data;353	int ret = 0;354 355	ret =356	    of_property_read_u32(np, "shunt-resistor-micro-ohms",357				 &data->shunt_micro_ohms);358	if (ret < 0)359		dev_err(cfg->dev,360			"property 'shunt-resistor-micro-ohms' not found, err %d\n",361			ret);362	return ret;363 364}365 366#define MAX597X_SWITCH(_ID, _ereg, _chan, _supply) {     \367	.name            = #_ID,                         \368	.of_match        = of_match_ptr(#_ID),           \369	.ops             = &max597x_switch_ops,          \370	.regulators_node = of_match_ptr("regulators"),   \371	.type            = REGULATOR_VOLTAGE,            \372	.id              = MAX597X_##_ID,                \373	.owner           = THIS_MODULE,                  \374	.supply_name     = _supply,                      \375	.enable_reg      = _ereg,                        \376	.enable_mask     = CHXEN((_chan)),               \377	.of_parse_cb	 = max597x_dt_parse,		 \378}379 380static const struct regulator_desc regulators[] = {381	MAX597X_SWITCH(sw0, MAX5970_REG_CHXEN, 0, "vss1"),382	MAX597X_SWITCH(sw1, MAX5970_REG_CHXEN, 1, "vss2"),383};384 385static int max597x_regmap_read_clear(struct regmap *map, unsigned int reg,386				     unsigned int *val)387{388	int ret;389 390	ret = regmap_read(map, reg, val);391	if (ret)392		return ret;393 394	if (*val)395		return regmap_write(map, reg, 0);396 397	return 0;398}399 400static int max597x_irq_handler(int irq, struct regulator_irq_data *rid,401			       unsigned long *dev_mask)402{403	struct regulator_err_state *stat;404	struct max5970_regulator *d = (struct max5970_regulator *)rid->data;405	int val, ret, i;406 407	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val);408	if (ret)409		return REGULATOR_FAILED_RETRY;410 411	*dev_mask = 0;412	for (i = 0; i < d->num_switches; i++) {413		stat = &rid->states[i];414		stat->notifs = 0;415		stat->errors = 0;416	}417 418	for (i = 0; i < d->num_switches; i++) {419		stat = &rid->states[i];420 421		if (val & UV_STATUS_CRIT(i)) {422			*dev_mask |= 1 << i;423			stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE;424			stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE;425		} else if (val & UV_STATUS_WARN(i)) {426			*dev_mask |= 1 << i;427			stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE_WARN;428			stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE_WARN;429		}430	}431 432	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT1, &val);433	if (ret)434		return REGULATOR_FAILED_RETRY;435 436	for (i = 0; i < d->num_switches; i++) {437		stat = &rid->states[i];438 439		if (val & OV_STATUS_CRIT(i)) {440			*dev_mask |= 1 << i;441			stat->notifs |= REGULATOR_EVENT_REGULATION_OUT;442			stat->errors |= REGULATOR_ERROR_REGULATION_OUT;443		} else if (val & OV_STATUS_WARN(i)) {444			*dev_mask |= 1 << i;445			stat->notifs |= REGULATOR_EVENT_OVER_VOLTAGE_WARN;446			stat->errors |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;447		}448	}449 450	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT2, &val);451	if (ret)452		return REGULATOR_FAILED_RETRY;453 454	for (i = 0; i < d->num_switches; i++) {455		stat = &rid->states[i];456 457		if (val & OC_STATUS_WARN(i)) {458			*dev_mask |= 1 << i;459			stat->notifs |= REGULATOR_EVENT_OVER_CURRENT_WARN;460			stat->errors |= REGULATOR_ERROR_OVER_CURRENT_WARN;461		}462	}463 464	ret = regmap_read(d->regmap, MAX5970_REG_STATUS0, &val);465	if (ret)466		return REGULATOR_FAILED_RETRY;467 468	for (i = 0; i < d->num_switches; i++) {469		stat = &rid->states[i];470 471		if ((val & MAX5970_CB_IFAULTF(i))472		    || (val & MAX5970_CB_IFAULTS(i))) {473			*dev_mask |= 1 << i;474			stat->notifs |=475			    REGULATOR_EVENT_OVER_CURRENT |476			    REGULATOR_EVENT_DISABLE;477			stat->errors |=478			    REGULATOR_ERROR_OVER_CURRENT | REGULATOR_ERROR_FAIL;479 480			/* Clear the sub-IRQ status */481			regulator_disable_regmap(stat->rdev);482		}483	}484	return 0;485}486 487static int max597x_adc_range(struct regmap *regmap, const int ch,488			     u32 *irng, u32 *mon_rng)489{490	unsigned int reg;491	int ret;492 493	/* Decode current ADC range */494	ret = regmap_read(regmap, MAX5970_REG_STATUS2, &reg);495	if (ret)496		return ret;497	switch (MAX5970_IRNG(reg, ch)) {498	case 0:499		*irng = 100000;	/* 100 mV */500		break;501	case 1:502		*irng = 50000;	/* 50 mV */503		break;504	case 2:505		*irng = 25000;	/* 25 mV */506		break;507	default:508		return -EINVAL;509	}510 511	/* Decode current voltage monitor range */512	ret = regmap_read(regmap, MAX5970_REG_MON_RANGE, &reg);513	if (ret)514		return ret;515 516	*mon_rng = MAX5970_MON_MAX_RANGE_UV >> MAX5970_MON(reg, ch);517 518	return 0;519}520 521static int max597x_setup_irq(struct device *dev,522			     int irq,523			     struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES],524			     int num_switches, struct max5970_regulator *data)525{526	struct regulator_irq_desc max597x_notif = {527		.name = "max597x-irq",528		.map_event = max597x_irq_handler,529		.data = data,530	};531	int errs = REGULATOR_ERROR_UNDER_VOLTAGE |532	    REGULATOR_ERROR_UNDER_VOLTAGE_WARN |533	    REGULATOR_ERROR_OVER_VOLTAGE_WARN |534	    REGULATOR_ERROR_REGULATION_OUT |535	    REGULATOR_ERROR_OVER_CURRENT |536	    REGULATOR_ERROR_OVER_CURRENT_WARN | REGULATOR_ERROR_FAIL;537	void *irq_helper;538 539	/* Register notifiers - can fail if IRQ is not given */540	irq_helper = devm_regulator_irq_helper(dev, &max597x_notif,541					       irq, 0, errs, NULL,542					       &rdevs[0], num_switches);543	if (IS_ERR(irq_helper)) {544		if (PTR_ERR(irq_helper) == -EPROBE_DEFER)545			return -EPROBE_DEFER;546 547		dev_warn(dev, "IRQ disabled %pe\n", irq_helper);548	}549 550	return 0;551}552 553static int max597x_regulator_probe(struct platform_device *pdev)554{555	struct max5970_data *max597x;556	struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);557	struct max5970_regulator *data;558	struct i2c_client *i2c = to_i2c_client(pdev->dev.parent);559	struct regulator_config config = { };560	struct regulator_dev *rdev;561	struct regulator_dev **rdevs = NULL;562	struct device *hwmon_dev;563	int num_switches;564	int ret, i;565 566	if (!regmap)567		return -EPROBE_DEFER;568 569	max597x = devm_kzalloc(&i2c->dev, sizeof(struct max5970_data), GFP_KERNEL);570	if (!max597x)571		return -ENOMEM;572 573	rdevs = devm_kcalloc(&i2c->dev, MAX5970_NUM_SWITCHES, sizeof(struct regulator_dev *),574			     GFP_KERNEL);575	if (!rdevs)576		return -ENOMEM;577 578	i2c_set_clientdata(i2c, max597x);579 580	if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978"))581		max597x->num_switches = MAX5978_NUM_SWITCHES;582	else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970"))583		max597x->num_switches = MAX5970_NUM_SWITCHES;584	else585		return -ENODEV;586 587	num_switches = max597x->num_switches;588 589	for (i = 0; i < num_switches; i++) {590		data =591		    devm_kzalloc(&i2c->dev, sizeof(struct max5970_regulator),592				 GFP_KERNEL);593		if (!data)594			return -ENOMEM;595 596		data->num_switches = num_switches;597		data->regmap = regmap;598 599		ret = max597x_adc_range(regmap, i, &max597x->irng[i], &max597x->mon_rng[i]);600		if (ret < 0)601			return ret;602 603		data->irng = max597x->irng[i];604		data->mon_rng = max597x->mon_rng[i];605 606		config.dev = &i2c->dev;607		config.driver_data = (void *)data;608		config.regmap = data->regmap;609		rdev = devm_regulator_register(&i2c->dev,610					       &regulators[i], &config);611		if (IS_ERR(rdev)) {612			dev_err(&i2c->dev, "failed to register regulator %s\n",613				regulators[i].name);614			return PTR_ERR(rdev);615		}616		rdevs[i] = rdev;617		max597x->shunt_micro_ohms[i] = data->shunt_micro_ohms;618	}619 620	if (IS_REACHABLE(CONFIG_HWMON)) {621		hwmon_dev = devm_hwmon_device_register_with_info(&i2c->dev, "max5970", rdevs,622								 &max5970_chip_info, NULL);623		if (IS_ERR(hwmon_dev)) {624			return dev_err_probe(&i2c->dev, PTR_ERR(hwmon_dev),625					     "Unable to register hwmon device\n");626		}627	}628 629	if (i2c->irq) {630		ret =631		    max597x_setup_irq(&i2c->dev, i2c->irq, rdevs, num_switches,632				      data);633		if (ret) {634			dev_err(&i2c->dev, "IRQ setup failed");635			return ret;636		}637	}638 639	return ret;640}641 642static struct platform_driver max597x_regulator_driver = {643	.driver = {644		.name = "max5970-regulator",645		.probe_type = PROBE_PREFER_ASYNCHRONOUS,646	},647	.probe = max597x_regulator_probe,648};649 650module_platform_driver(max597x_regulator_driver);651 652 653MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");654MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");655MODULE_LICENSE("GPL v2");656