brintos

brintos / linux-shallow public Read only

0
0
Text · 7.6 KiB · d35d844 Raw
291 lines · c
1// SPDX-License-Identifier: GPL-2.0+2 3#include <linux/bitops.h>4#include <linux/delay.h>5#include <linux/gpio/consumer.h>6#include <linux/i2c.h>7#include <linux/kernel.h>8#include <linux/module.h>9#include <linux/mutex.h>10#include <linux/regmap.h>11#include <linux/regulator/driver.h>12 13enum {14	RTQ6752_IDX_PAVDD = 0,15	RTQ6752_IDX_NAVDD = 1,16	RTQ6752_IDX_MAX17};18 19#define RTQ6752_REG_PAVDD	0x0020#define RTQ6752_REG_NAVDD	0x0121#define RTQ6752_REG_PAVDDONDLY	0x0722#define RTQ6752_REG_PAVDDSSTIME	0x0823#define RTQ6752_REG_NAVDDONDLY	0x0D24#define RTQ6752_REG_NAVDDSSTIME	0x0E25#define RTQ6752_REG_OPTION1	0x1226#define RTQ6752_REG_CHSWITCH	0x1627#define RTQ6752_REG_FAULT	0x1D28 29#define RTQ6752_VOUT_MASK	GENMASK(5, 0)30#define RTQ6752_NAVDDEN_MASK	BIT(3)31#define RTQ6752_PAVDDEN_MASK	BIT(0)32#define RTQ6752_PAVDDAD_MASK	BIT(4)33#define RTQ6752_NAVDDAD_MASK	BIT(3)34#define RTQ6752_PAVDDF_MASK	BIT(3)35#define RTQ6752_NAVDDF_MASK	BIT(0)36#define RTQ6752_ENABLE_MASK	(BIT(RTQ6752_IDX_MAX) - 1)37 38#define RTQ6752_VOUT_MINUV	500000039#define RTQ6752_VOUT_STEPUV	5000040#define RTQ6752_VOUT_NUM	4741#define RTQ6752_I2CRDY_TIMEUS	100042#define RTQ6752_MINSS_TIMEUS	500043 44struct rtq6752_priv {45	struct regmap *regmap;46	struct gpio_desc *enable_gpio;47	struct mutex lock;48	unsigned char enable_flag;49};50 51static int rtq6752_set_vdd_enable(struct regulator_dev *rdev)52{53	struct rtq6752_priv *priv = rdev_get_drvdata(rdev);54	int rid = rdev_get_id(rdev), ret;55 56	mutex_lock(&priv->lock);57	if (!priv->enable_flag) {58		if (priv->enable_gpio) {59			gpiod_set_value(priv->enable_gpio, 1);60 61			usleep_range(RTQ6752_I2CRDY_TIMEUS,62				     RTQ6752_I2CRDY_TIMEUS + 100);63		}64 65		regcache_cache_only(priv->regmap, false);66		ret = regcache_sync(priv->regmap);67		if (ret) {68			mutex_unlock(&priv->lock);69			return ret;70		}71	}72 73	priv->enable_flag |= BIT(rid);74	mutex_unlock(&priv->lock);75 76	return regulator_enable_regmap(rdev);77}78 79static int rtq6752_set_vdd_disable(struct regulator_dev *rdev)80{81	struct rtq6752_priv *priv = rdev_get_drvdata(rdev);82	int rid = rdev_get_id(rdev), ret;83 84	ret = regulator_disable_regmap(rdev);85	if (ret)86		return ret;87 88	mutex_lock(&priv->lock);89	priv->enable_flag &= ~BIT(rid);90 91	if (!priv->enable_flag) {92		regcache_cache_only(priv->regmap, true);93		regcache_mark_dirty(priv->regmap);94 95		if (priv->enable_gpio)96			gpiod_set_value(priv->enable_gpio, 0);97 98	}99	mutex_unlock(&priv->lock);100 101	return 0;102}103 104static int rtq6752_get_error_flags(struct regulator_dev *rdev,105				   unsigned int *flags)106{107	unsigned int val, events = 0;108	const unsigned int fault_mask[] = {109		RTQ6752_PAVDDF_MASK, RTQ6752_NAVDDF_MASK };110	int rid = rdev_get_id(rdev), ret;111 112	ret = regmap_read(rdev->regmap, RTQ6752_REG_FAULT, &val);113	if (ret)114		return ret;115 116	if (val & fault_mask[rid])117		events = REGULATOR_ERROR_REGULATION_OUT;118 119	*flags = events;120	return 0;121}122 123static const struct regulator_ops rtq6752_regulator_ops = {124	.list_voltage = regulator_list_voltage_linear,125	.set_voltage_sel = regulator_set_voltage_sel_regmap,126	.get_voltage_sel = regulator_get_voltage_sel_regmap,127	.enable = rtq6752_set_vdd_enable,128	.disable = rtq6752_set_vdd_disable,129	.is_enabled = regulator_is_enabled_regmap,130	.set_active_discharge = regulator_set_active_discharge_regmap,131	.get_error_flags = rtq6752_get_error_flags,132};133 134static const struct regulator_desc rtq6752_regulator_descs[] = {135	{136		.name = "rtq6752-pavdd",137		.of_match = of_match_ptr("pavdd"),138		.regulators_node = of_match_ptr("regulators"),139		.id = RTQ6752_IDX_PAVDD,140		.n_voltages = RTQ6752_VOUT_NUM,141		.ops = &rtq6752_regulator_ops,142		.owner = THIS_MODULE,143		.min_uV = RTQ6752_VOUT_MINUV,144		.uV_step = RTQ6752_VOUT_STEPUV,145		.enable_time = RTQ6752_MINSS_TIMEUS,146		.vsel_reg = RTQ6752_REG_PAVDD,147		.vsel_mask = RTQ6752_VOUT_MASK,148		.enable_reg = RTQ6752_REG_CHSWITCH,149		.enable_mask = RTQ6752_PAVDDEN_MASK,150		.active_discharge_reg = RTQ6752_REG_OPTION1,151		.active_discharge_mask = RTQ6752_PAVDDAD_MASK,152		.active_discharge_off = RTQ6752_PAVDDAD_MASK,153	},154	{155		.name = "rtq6752-navdd",156		.of_match = of_match_ptr("navdd"),157		.regulators_node = of_match_ptr("regulators"),158		.id = RTQ6752_IDX_NAVDD,159		.n_voltages = RTQ6752_VOUT_NUM,160		.ops = &rtq6752_regulator_ops,161		.owner = THIS_MODULE,162		.min_uV = RTQ6752_VOUT_MINUV,163		.uV_step = RTQ6752_VOUT_STEPUV,164		.enable_time = RTQ6752_MINSS_TIMEUS,165		.vsel_reg = RTQ6752_REG_NAVDD,166		.vsel_mask = RTQ6752_VOUT_MASK,167		.enable_reg = RTQ6752_REG_CHSWITCH,168		.enable_mask = RTQ6752_NAVDDEN_MASK,169		.active_discharge_reg = RTQ6752_REG_OPTION1,170		.active_discharge_mask = RTQ6752_NAVDDAD_MASK,171		.active_discharge_off = RTQ6752_NAVDDAD_MASK,172	}173};174 175static int rtq6752_init_device_properties(struct rtq6752_priv *priv)176{177	u8 raw_vals[] = { 0, 0 };178	int ret;179 180	/* Configure PAVDD on and softstart delay time to the minimum */181	ret = regmap_raw_write(priv->regmap, RTQ6752_REG_PAVDDONDLY, raw_vals,182			       ARRAY_SIZE(raw_vals));183	if (ret)184		return ret;185 186	/* Configure NAVDD on and softstart delay time to the minimum */187	return regmap_raw_write(priv->regmap, RTQ6752_REG_NAVDDONDLY, raw_vals,188				ARRAY_SIZE(raw_vals));189}190 191static bool rtq6752_is_volatile_reg(struct device *dev, unsigned int reg)192{193	if (reg == RTQ6752_REG_FAULT)194		return true;195	return false;196}197 198static const struct reg_default rtq6752_reg_defaults[] = {199	{ RTQ6752_REG_PAVDD, 0x14 },200	{ RTQ6752_REG_NAVDD, 0x14 },201	{ RTQ6752_REG_PAVDDONDLY, 0x01 },202	{ RTQ6752_REG_PAVDDSSTIME, 0x01 },203	{ RTQ6752_REG_NAVDDONDLY, 0x01 },204	{ RTQ6752_REG_NAVDDSSTIME, 0x01 },205	{ RTQ6752_REG_OPTION1, 0x07 },206	{ RTQ6752_REG_CHSWITCH, 0x29 },207};208 209static const struct regmap_config rtq6752_regmap_config = {210	.reg_bits = 8,211	.val_bits = 8,212	.cache_type = REGCACHE_MAPLE,213	.max_register = RTQ6752_REG_FAULT,214	.reg_defaults = rtq6752_reg_defaults,215	.num_reg_defaults = ARRAY_SIZE(rtq6752_reg_defaults),216	.volatile_reg = rtq6752_is_volatile_reg,217};218 219static int rtq6752_probe(struct i2c_client *i2c)220{221	struct rtq6752_priv *priv;222	struct regulator_config reg_cfg = {};223	struct regulator_dev *rdev;224	int i, ret;225 226	priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);227	if (!priv)228		return -ENOMEM;229 230	mutex_init(&priv->lock);231 232	priv->enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable",233						    GPIOD_OUT_HIGH);234	if (IS_ERR(priv->enable_gpio)) {235		dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");236		return PTR_ERR(priv->enable_gpio);237	}238 239	usleep_range(RTQ6752_I2CRDY_TIMEUS, RTQ6752_I2CRDY_TIMEUS + 100);240	/* Default EN pin to high, PAVDD and NAVDD will be on */241	priv->enable_flag = RTQ6752_ENABLE_MASK;242 243	priv->regmap = devm_regmap_init_i2c(i2c, &rtq6752_regmap_config);244	if (IS_ERR(priv->regmap)) {245		dev_err(&i2c->dev, "Failed to init regmap\n");246		return PTR_ERR(priv->regmap);247	}248 249	ret = rtq6752_init_device_properties(priv);250	if (ret) {251		dev_err(&i2c->dev, "Failed to init device properties\n");252		return ret;253	}254 255	reg_cfg.dev = &i2c->dev;256	reg_cfg.regmap = priv->regmap;257	reg_cfg.driver_data = priv;258 259	for (i = 0; i < ARRAY_SIZE(rtq6752_regulator_descs); i++) {260		rdev = devm_regulator_register(&i2c->dev,261					       rtq6752_regulator_descs + i,262					       &reg_cfg);263		if (IS_ERR(rdev)) {264			dev_err(&i2c->dev, "Failed to init %d regulator\n", i);265			return PTR_ERR(rdev);266		}267	}268 269	return 0;270}271 272static const struct of_device_id __maybe_unused rtq6752_device_table[] = {273	{ .compatible = "richtek,rtq6752", },274	{}275};276MODULE_DEVICE_TABLE(of, rtq6752_device_table);277 278static struct i2c_driver rtq6752_driver = {279	.driver = {280		.name = "rtq6752",281		.probe_type = PROBE_PREFER_ASYNCHRONOUS,282		.of_match_table = rtq6752_device_table,283	},284	.probe = rtq6752_probe,285};286module_i2c_driver(rtq6752_driver);287 288MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");289MODULE_DESCRIPTION("Richtek RTQ6752 Regulator Driver");290MODULE_LICENSE("GPL v2");291