brintos

brintos / linux-shallow public Read only

0
0
Text · 11.5 KiB · 1216cc3 Raw
462 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2023 Analog Devices, Inc.4 * ADI Regulator driver for the MAX778575 * MAX77859 and MAX77831.6 */7#include <linux/bitfield.h>8#include <linux/i2c.h>9#include <linux/interrupt.h>10#include <linux/module.h>11#include <linux/regmap.h>12#include <linux/regulator/driver.h>13#include <linux/regulator/machine.h>14#include <linux/regulator/of_regulator.h>15#include <linux/util_macros.h>16 17#define MAX77857_REG_INT_SRC		0x1018#define MAX77857_REG_INT_MASK		0x1119#define MAX77857_REG_CONT1		0x1220#define MAX77857_REG_CONT2		0x1321#define MAX77857_REG_CONT3		0x1422 23#define MAX77857_INT_SRC_OCP		BIT(0)24#define MAX77857_INT_SRC_THS		BIT(1)25#define MAX77857_INT_SRC_HARDSHORT	BIT(2)26#define MAX77857_INT_SRC_OVP		BIT(3)27#define MAX77857_INT_SRC_POK		BIT(4)28 29#define MAX77857_ILIM_MASK		GENMASK(2, 0)30#define MAX77857_CONT1_FREQ		GENMASK(4, 3)31#define MAX77857_CONT3_FPWM		BIT(5)32 33#define MAX77859_REG_INT_SRC		0x1134#define MAX77859_REG_CONT1		0x1335#define MAX77859_REG_CONT2		0x1436#define MAX77859_REG_CONT3		0x1537#define MAX77859_REG_CONT5		0x1738#define MAX77859_CONT2_FPWM		BIT(2)39#define MAX77859_CONT2_INTB		BIT(3)40#define MAX77859_CONT3_DVS_START	BIT(2)41#define MAX77859_VOLTAGE_SEL_MASK	GENMASK(9, 0)42 43#define MAX77859_CURRENT_MIN		100000044#define MAX77859_CURRENT_MAX		500000045#define MAX77859_CURRENT_STEP		5000046 47enum max77857_id {48	ID_MAX77831 = 1,49	ID_MAX77857,50	ID_MAX77859,51	ID_MAX77859A,52};53 54static bool max77857_volatile_reg(struct device *dev, unsigned int reg)55{56	enum max77857_id id = (uintptr_t)dev_get_drvdata(dev);57 58	switch (id) {59	case ID_MAX77831:60	case ID_MAX77857:61		return reg == MAX77857_REG_INT_SRC;62	case ID_MAX77859:63	case ID_MAX77859A:64		return reg == MAX77859_REG_INT_SRC;65	default:66		return true;67	}68}69 70static const struct regmap_config max77857_regmap_config = {71	.reg_bits = 8,72	.val_bits = 8,73	.cache_type = REGCACHE_MAPLE,74	.volatile_reg = max77857_volatile_reg,75};76 77static int max77857_get_status(struct regulator_dev *rdev)78{79	unsigned int val;80	int ret;81 82	ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);83	if (ret)84		return ret;85 86	if (FIELD_GET(MAX77857_INT_SRC_POK, val))87		return REGULATOR_STATUS_ON;88 89	return REGULATOR_STATUS_ERROR;90}91 92static unsigned int max77857_get_mode(struct regulator_dev *rdev)93{94	enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);95	unsigned int regval;96	int ret;97 98	switch (id) {99	case ID_MAX77831:100	case ID_MAX77857:101		ret = regmap_read(rdev->regmap, MAX77857_REG_CONT3, &regval);102		if (ret)103			return ret;104 105		if (FIELD_GET(MAX77857_CONT3_FPWM, regval))106			return REGULATOR_MODE_FAST;107 108		break;109	case ID_MAX77859:110	case ID_MAX77859A:111		ret = regmap_read(rdev->regmap, MAX77859_REG_CONT2, &regval);112		if (ret)113			return ret;114 115		if (FIELD_GET(MAX77859_CONT2_FPWM, regval))116			return REGULATOR_MODE_FAST;117 118		break;119	default:120		return -EINVAL;121	}122 123	return REGULATOR_MODE_NORMAL;124}125 126static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode)127{128	enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);129	unsigned int reg, val;130 131	switch (id) {132	case ID_MAX77831:133	case ID_MAX77857:134		reg = MAX77857_REG_CONT3;135		val = MAX77857_CONT3_FPWM;136		break;137	case ID_MAX77859:138	case ID_MAX77859A:139		reg = MAX77859_REG_CONT2;140		val = MAX77859_CONT2_FPWM;141		break;142	default:143		return -EINVAL;144	}145 146	switch (mode) {147	case REGULATOR_MODE_FAST:148		return regmap_set_bits(rdev->regmap, reg, val);149	case REGULATOR_MODE_NORMAL:150		return regmap_clear_bits(rdev->regmap, reg, val);151	default:152		return -EINVAL;153	}154}155 156static int max77857_get_error_flags(struct regulator_dev *rdev,157				    unsigned int *flags)158{159	unsigned int val;160	int ret;161 162	ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);163	if (ret)164		return ret;165 166	*flags = 0;167 168	if (FIELD_GET(MAX77857_INT_SRC_OVP, val))169		*flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;170 171	if (FIELD_GET(MAX77857_INT_SRC_OCP, val) ||172	    FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val))173		*flags |= REGULATOR_ERROR_OVER_CURRENT;174 175	if (FIELD_GET(MAX77857_INT_SRC_THS, val))176		*flags |= REGULATOR_ERROR_OVER_TEMP;177 178	if (!FIELD_GET(MAX77857_INT_SRC_POK, val))179		*flags |= REGULATOR_ERROR_FAIL;180 181	return 0;182}183 184static struct linear_range max77859_lin_ranges[] = {185	REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000)186};187 188static const unsigned int max77859_ramp_table[4] = {189	1000, 500, 250, 125190};191 192static int max77859_set_voltage_sel(struct regulator_dev *rdev,193				    unsigned int sel)194{195	__be16 reg;196	int ret;197 198	reg = cpu_to_be16(sel);199 200	ret = regmap_bulk_write(rdev->regmap, MAX77859_REG_CONT3, &reg, 2);201	if (ret)202		return ret;203 204	/* actually apply new voltage */205	return regmap_set_bits(rdev->regmap, MAX77859_REG_CONT3,206			       MAX77859_CONT3_DVS_START);207}208 209static int max77859_get_voltage_sel(struct regulator_dev *rdev)210{211	__be16 reg;212	int ret;213 214	ret = regmap_bulk_read(rdev->regmap, MAX77859_REG_CONT3, &reg, 2);215	if (ret)216		return ret;217 218	return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg));219}220 221static int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)222{223	u32 selector;224 225	if (max_uA < MAX77859_CURRENT_MIN)226		return -EINVAL;227 228	selector = 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_STEP;229 230	selector = clamp_val(selector, 0x00, 0x7F);231 232	return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector);233}234 235static int max77859_get_current_limit(struct regulator_dev *rdev)236{237	u32 selector;238	int ret;239 240	ret = regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector);241	if (ret)242		return ret;243 244	if (selector <= 0x12)245		return MAX77859_CURRENT_MIN;246 247	if (selector >= 0x64)248		return MAX77859_CURRENT_MAX;249 250	return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP;251}252 253static const struct regulator_ops max77859_regulator_ops = {254	.list_voltage = regulator_list_voltage_linear_range,255	.set_voltage_sel = max77859_set_voltage_sel,256	.get_voltage_sel = max77859_get_voltage_sel,257	.set_ramp_delay = regulator_set_ramp_delay_regmap,258	.get_status = max77857_get_status,259	.set_mode = max77857_set_mode,260	.get_mode = max77857_get_mode,261	.get_error_flags = max77857_get_error_flags,262};263 264static const struct regulator_ops max77859a_regulator_ops = {265	.list_voltage = regulator_list_voltage_linear_range,266	.set_voltage_sel = max77859_set_voltage_sel,267	.get_voltage_sel = max77859_get_voltage_sel,268	.set_current_limit = max77859_set_current_limit,269	.get_current_limit = max77859_get_current_limit,270	.set_ramp_delay = regulator_set_ramp_delay_regmap,271	.get_status = max77857_get_status,272	.set_mode = max77857_set_mode,273	.get_mode = max77857_get_mode,274	.get_error_flags = max77857_get_error_flags,275};276 277static const struct regulator_ops max77857_regulator_ops = {278	.list_voltage = regulator_list_voltage_linear_range,279	.set_voltage_sel = regulator_set_voltage_sel_regmap,280	.get_voltage_sel = regulator_get_voltage_sel_regmap,281	.set_ramp_delay = regulator_set_ramp_delay_regmap,282	.get_status = max77857_get_status,283	.set_mode = max77857_set_mode,284	.get_mode = max77857_get_mode,285	.get_error_flags = max77857_get_error_flags,286};287 288static struct linear_range max77857_lin_ranges[] = {289	REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500)290};291 292static const unsigned int max77857_switch_freq[] = {293	1200000, 1500000, 1800000, 2100000294};295 296#define RAMAP_DELAY_INIT_VAL 1333297 298static const unsigned int max77857_ramp_table[2][4] = {299	{ RAMAP_DELAY_INIT_VAL, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */300	{ 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */301};302 303static struct regulator_desc max77857_regulator_desc = {304	.ops = &max77857_regulator_ops,305	.name = "max77857",306	.linear_ranges = max77857_lin_ranges,307	.n_linear_ranges = ARRAY_SIZE(max77857_lin_ranges),308	.vsel_mask = 0xFF,309	.vsel_reg = MAX77857_REG_CONT2,310	.ramp_delay_table = max77857_ramp_table[0],311	.n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]),312	.ramp_reg = MAX77857_REG_CONT3,313	.ramp_mask = GENMASK(1, 0),314	.ramp_delay = RAMAP_DELAY_INIT_VAL,315	.owner = THIS_MODULE,316};317 318static void max77857_calc_range(struct device *dev, enum max77857_id id)319{320	struct linear_range *range;321	unsigned long vref_step;322	u32 rtop = 0;323	u32 rbot = 0;324 325	device_property_read_u32(dev, "adi,rtop-ohms", &rtop);326	device_property_read_u32(dev, "adi,rbot-ohms", &rbot);327 328	if (!rbot || !rtop)329		return;330 331	switch (id) {332	case ID_MAX77831:333	case ID_MAX77857:334		range = max77857_lin_ranges;335		vref_step = 4900UL;336		break;337	case ID_MAX77859:338	case ID_MAX77859A:339		range = max77859_lin_ranges;340		vref_step = 1250UL;341		break;342	}343 344	range->step = DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot);345	range->min = range->step * range->min_sel;346}347 348static int max77857_probe(struct i2c_client *client)349{350	const struct i2c_device_id *i2c_id;351	struct device *dev = &client->dev;352	struct regulator_config cfg = { };353	struct regulator_dev *rdev;354	struct regmap *regmap;355	enum max77857_id id;356	u32 switch_freq = 0;357	int ret;358 359	i2c_id = i2c_client_get_device_id(client);360	if (!i2c_id)361		return -EINVAL;362 363	id = i2c_id->driver_data;364 365	dev_set_drvdata(dev, (void *)id);366 367	if (id == ID_MAX77859 || id == ID_MAX77859A) {368		max77857_regulator_desc.ops = &max77859_regulator_ops;369		max77857_regulator_desc.linear_ranges = max77859_lin_ranges;370		max77857_regulator_desc.ramp_delay_table = max77859_ramp_table;371		max77857_regulator_desc.ramp_delay = max77859_ramp_table[0];372	}373 374	if (id == ID_MAX77859A)375		max77857_regulator_desc.ops = &max77859a_regulator_ops;376 377	max77857_calc_range(dev, id);378 379	regmap = devm_regmap_init_i2c(client, &max77857_regmap_config);380	if (IS_ERR(regmap))381		return dev_err_probe(dev, PTR_ERR(regmap),382				     "cannot initialize regmap\n");383 384	device_property_read_u32(dev, "adi,switch-frequency-hz", &switch_freq);385	if (switch_freq) {386		switch_freq = find_closest(switch_freq, max77857_switch_freq,387					   ARRAY_SIZE(max77857_switch_freq));388 389		if (id == ID_MAX77831 && switch_freq == 3)390			switch_freq = 2;391 392		switch (id) {393		case ID_MAX77831:394		case ID_MAX77857:395			ret = regmap_update_bits(regmap, MAX77857_REG_CONT1,396						 MAX77857_CONT1_FREQ, switch_freq);397 398			if (switch_freq >= 2)399				break;400 401			max77857_regulator_desc.ramp_delay_table = max77857_ramp_table[1];402			max77857_regulator_desc.ramp_delay = max77857_ramp_table[1][0];403			break;404		case ID_MAX77859:405		case ID_MAX77859A:406			ret = regmap_update_bits(regmap, MAX77859_REG_CONT1,407						 MAX77857_CONT1_FREQ, switch_freq);408			break;409		}410		if (ret)411			return ret;412	}413 414	cfg.dev = dev;415	cfg.driver_data = (void *)id;416	cfg.regmap = regmap;417	cfg.init_data = of_get_regulator_init_data(dev, dev->of_node,418						   &max77857_regulator_desc);419	if (!cfg.init_data)420		return -ENOMEM;421 422	rdev = devm_regulator_register(dev, &max77857_regulator_desc, &cfg);423	if (IS_ERR(rdev))424		return dev_err_probe(dev, PTR_ERR(rdev),425				     "cannot register regulator\n");426 427	return 0;428}429 430static const struct i2c_device_id max77857_id[] = {431	{ "max77831", ID_MAX77831 },432	{ "max77857", ID_MAX77857 },433	{ "max77859", ID_MAX77859 },434	{ "max77859a", ID_MAX77859A },435	{ }436};437MODULE_DEVICE_TABLE(i2c, max77857_id);438 439static const struct of_device_id max77857_of_id[] = {440	{ .compatible = "adi,max77831", .data = (void *)ID_MAX77831 },441	{ .compatible = "adi,max77857", .data = (void *)ID_MAX77857 },442	{ .compatible = "adi,max77859", .data = (void *)ID_MAX77859 },443	{ .compatible = "adi,max77859a", .data = (void *)ID_MAX77859A },444	{ }445};446MODULE_DEVICE_TABLE(of, max77857_of_id);447 448static struct i2c_driver max77857_driver = {449	.driver = {450		.name = "max77857",451		.of_match_table = max77857_of_id,452	},453	.id_table = max77857_id,454	.probe = max77857_probe,455};456module_i2c_driver(max77857_driver);457 458MODULE_DESCRIPTION("Analog Devices MAX77857 Buck-Boost Converter Driver");459MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>");460MODULE_AUTHOR("Okan Sahin <Okan.Sahin@analog.com>");461MODULE_LICENSE("GPL");462