brintos

brintos / linux-shallow public Read only

0
0
Text · 10.6 KiB · b7372cb Raw
376 lines · c
1// SPDX-License-Identifier: GPL-2.0+2 3#include <linux/bitops.h>4#include <linux/i2c.h>5#include <linux/kernel.h>6#include <linux/module.h>7#include <linux/of.h>8#include <linux/regmap.h>9#include <linux/regulator/driver.h>10 11enum {12	RTQ2134_IDX_BUCK1 = 0,13	RTQ2134_IDX_BUCK2,14	RTQ2134_IDX_BUCK3,15	RTQ2134_IDX_MAX16};17 18#define RTQ2134_AUTO_MODE		019#define RTQ2134_FCCM_MODE		120 21#define RTQ2134_BUCK_DVS0_CTRL		022#define RTQ2134_BUCK_VSEL_CTRL		223 24#define RTQ2134_REG_IO_CHIPNAME		0x0125#define RTQ2134_REG_FLT_RECORDTEMP	0x1326#define RTQ2134_REG_FLT_RECORDBUCK(_id)	(0x14 + (_id))27#define RTQ2134_REG_FLT_BUCKCTRL(_id)	(0x37 + (_id))28#define RTQ2134_REG_BUCK1_CFG0		0x4229#define RTQ2134_REG_BUCK1_DVS0CFG1	0x4830#define RTQ2134_REG_BUCK1_DVS0CFG0	0x4931#define RTQ2134_REG_BUCK1_DVS1CFG1	0x4A32#define RTQ2134_REG_BUCK1_DVS1CFG0	0x4B33#define RTQ2134_REG_BUCK1_DVSCFG	0x5234#define RTQ2134_REG_BUCK1_RSPCFG	0x5435#define RTQ2134_REG_BUCK2_CFG0		0x5F36#define RTQ2134_REG_BUCK2_DVS0CFG1	0x6237#define RTQ2134_REG_BUCK2_DVS0CFG0	0x6338#define RTQ2134_REG_BUCK2_DVS1CFG1	0x6439#define RTQ2134_REG_BUCK2_DVS1CFG0	0x6540#define RTQ2134_REG_BUCK2_DVSCFG	0x6C41#define RTQ2134_REG_BUCK2_RSPCFG	0x6E42#define RTQ2134_REG_BUCK3_CFG0		0x7943#define RTQ2134_REG_BUCK3_DVS0CFG1	0x7C44#define RTQ2134_REG_BUCK3_DVS0CFG0	0x7D45#define RTQ2134_REG_BUCK3_DVS1CFG1	0x7E46#define RTQ2134_REG_BUCK3_DVS1CFG0	0x7F47#define RTQ2134_REG_BUCK3_DVSCFG	0x8648#define RTQ2134_REG_BUCK3_RSPCFG	0x8849#define RTQ2134_REG_BUCK3_SLEWCTRL	0x8950 51#define RTQ2134_VOUT_MAXNUM		25652#define RTQ2134_VOUT_MASK		0xFF53#define RTQ2134_VOUTEN_MASK		BIT(0)54#define RTQ2134_ACTDISCHG_MASK		BIT(0)55#define RTQ2134_RSPUP_MASK		GENMASK(6, 4)56#define RTQ2134_FCCM_MASK		BIT(5)57#define RTQ2134_UVHICCUP_MASK		BIT(3)58#define RTQ2134_BUCKDVS_CTRL_MASK	GENMASK(1, 0)59#define RTQ2134_CHIPOT_MASK		BIT(2)60#define RTQ2134_BUCKOV_MASK		BIT(5)61#define RTQ2134_BUCKUV_MASK		BIT(4)62 63struct rtq2134_regulator_desc {64	struct regulator_desc desc;65	/* Extension for proprietary register and mask */66	unsigned int mode_reg;67	unsigned int mode_mask;68	unsigned int suspend_enable_reg;69	unsigned int suspend_enable_mask;70	unsigned int suspend_vsel_reg;71	unsigned int suspend_vsel_mask;72	unsigned int suspend_mode_reg;73	unsigned int suspend_mode_mask;74	unsigned int dvs_ctrl_reg;75};76 77static int rtq2134_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)78{79	struct rtq2134_regulator_desc *desc =80		(struct rtq2134_regulator_desc *)rdev->desc;81	unsigned int val;82 83	if (mode == REGULATOR_MODE_NORMAL)84		val = RTQ2134_AUTO_MODE;85	else if (mode == REGULATOR_MODE_FAST)86		val = RTQ2134_FCCM_MODE;87	else88		return -EINVAL;89 90	val <<= ffs(desc->mode_mask) - 1;91	return regmap_update_bits(rdev->regmap, desc->mode_reg, desc->mode_mask,92				  val);93}94 95static unsigned int rtq2134_buck_get_mode(struct regulator_dev *rdev)96{97	struct rtq2134_regulator_desc *desc =98		(struct rtq2134_regulator_desc *)rdev->desc;99	unsigned int mode;100	int ret;101 102	ret = regmap_read(rdev->regmap, desc->mode_reg, &mode);103	if (ret)104		return ret;105 106	if (mode & desc->mode_mask)107		return REGULATOR_MODE_FAST;108	return REGULATOR_MODE_NORMAL;109}110 111static int rtq2134_buck_set_suspend_voltage(struct regulator_dev *rdev, int uV)112{113	struct rtq2134_regulator_desc *desc =114		(struct rtq2134_regulator_desc *)rdev->desc;115	int sel;116 117	sel = regulator_map_voltage_linear_range(rdev, uV, uV);118	if (sel < 0)119		return sel;120 121	sel <<= ffs(desc->suspend_vsel_mask) - 1;122 123	return regmap_update_bits(rdev->regmap, desc->suspend_vsel_reg,124				  desc->suspend_vsel_mask, sel);125}126 127static int rtq2134_buck_set_suspend_enable(struct regulator_dev *rdev)128{129	struct rtq2134_regulator_desc *desc =130		(struct rtq2134_regulator_desc *)rdev->desc;131	unsigned int val = desc->suspend_enable_mask;132 133	return regmap_update_bits(rdev->regmap, desc->suspend_enable_reg,134				  desc->suspend_enable_mask, val);135}136 137static int rtq2134_buck_set_suspend_disable(struct regulator_dev *rdev)138{139	struct rtq2134_regulator_desc *desc =140		(struct rtq2134_regulator_desc *)rdev->desc;141 142	return regmap_update_bits(rdev->regmap, desc->suspend_enable_reg,143				  desc->suspend_enable_mask, 0);144}145 146static int rtq2134_buck_set_suspend_mode(struct regulator_dev *rdev,147					 unsigned int mode)148{149	struct rtq2134_regulator_desc *desc =150		(struct rtq2134_regulator_desc *)rdev->desc;151	unsigned int val;152 153	if (mode == REGULATOR_MODE_NORMAL)154		val = RTQ2134_AUTO_MODE;155	else if (mode == REGULATOR_MODE_FAST)156		val = RTQ2134_FCCM_MODE;157	else158		return -EINVAL;159 160	val <<= ffs(desc->suspend_mode_mask) - 1;161	return regmap_update_bits(rdev->regmap, desc->suspend_mode_reg,162				  desc->suspend_mode_mask, val);163}164 165static int rtq2134_buck_get_error_flags(struct regulator_dev *rdev,166					unsigned int *flags)167{168	int rid = rdev_get_id(rdev);169	unsigned int chip_error, buck_error, events = 0;170	int ret;171 172	ret = regmap_read(rdev->regmap, RTQ2134_REG_FLT_RECORDTEMP,173			  &chip_error);174	if (ret) {175		dev_err(&rdev->dev, "Failed to get chip error flag\n");176		return ret;177	}178 179	ret = regmap_read(rdev->regmap, RTQ2134_REG_FLT_RECORDBUCK(rid),180			  &buck_error);181	if (ret) {182		dev_err(&rdev->dev, "Failed to get buck error flag\n");183		return ret;184	}185 186	if (chip_error & RTQ2134_CHIPOT_MASK)187		events |= REGULATOR_ERROR_OVER_TEMP;188 189	if (buck_error & RTQ2134_BUCKUV_MASK)190		events |= REGULATOR_ERROR_UNDER_VOLTAGE;191 192	if (buck_error & RTQ2134_BUCKOV_MASK)193		events |= REGULATOR_ERROR_REGULATION_OUT;194 195	*flags = events;196	return 0;197}198 199static const struct regulator_ops rtq2134_buck_ops = {200	.list_voltage = regulator_list_voltage_linear_range,201	.set_voltage_sel = regulator_set_voltage_sel_regmap,202	.get_voltage_sel = regulator_get_voltage_sel_regmap,203	.enable = regulator_enable_regmap,204	.disable = regulator_disable_regmap,205	.is_enabled = regulator_is_enabled_regmap,206	.set_active_discharge = regulator_set_active_discharge_regmap,207	.set_ramp_delay = regulator_set_ramp_delay_regmap,208	.set_mode = rtq2134_buck_set_mode,209	.get_mode = rtq2134_buck_get_mode,210	.set_suspend_voltage = rtq2134_buck_set_suspend_voltage,211	.set_suspend_enable = rtq2134_buck_set_suspend_enable,212	.set_suspend_disable = rtq2134_buck_set_suspend_disable,213	.set_suspend_mode = rtq2134_buck_set_suspend_mode,214	.get_error_flags = rtq2134_buck_get_error_flags,215};216 217static const struct linear_range rtq2134_buck_vout_ranges[] = {218	REGULATOR_LINEAR_RANGE(300000, 0, 200, 5000),219	REGULATOR_LINEAR_RANGE(1310000, 201, 255, 10000)220};221 222static unsigned int rtq2134_buck_of_map_mode(unsigned int mode)223{224	switch (mode) {225	case RTQ2134_AUTO_MODE:226		return REGULATOR_MODE_NORMAL;227	case RTQ2134_FCCM_MODE:228		return REGULATOR_MODE_FAST;229	}230 231	return REGULATOR_MODE_INVALID;232}233 234static int rtq2134_buck_of_parse_cb(struct device_node *np,235				    const struct regulator_desc *desc,236				    struct regulator_config *cfg)237{238	struct rtq2134_regulator_desc *rdesc =239		(struct rtq2134_regulator_desc *)desc;240	int rid = desc->id;241	bool uv_shutdown, vsel_dvs;242	unsigned int val;243	int ret;244 245	vsel_dvs = of_property_read_bool(np, "richtek,use-vsel-dvs");246	if (vsel_dvs)247		val = RTQ2134_BUCK_VSEL_CTRL;248	else249		val = RTQ2134_BUCK_DVS0_CTRL;250 251	ret = regmap_update_bits(cfg->regmap, rdesc->dvs_ctrl_reg,252				 RTQ2134_BUCKDVS_CTRL_MASK, val);253	if (ret)254		return ret;255 256	uv_shutdown = of_property_read_bool(np, "richtek,uv-shutdown");257	if (uv_shutdown)258		val = 0;259	else260		val = RTQ2134_UVHICCUP_MASK;261 262	return regmap_update_bits(cfg->regmap, RTQ2134_REG_FLT_BUCKCTRL(rid),263				  RTQ2134_UVHICCUP_MASK, val);264}265 266static const unsigned int rtq2134_buck_ramp_delay_table[] = {267	0, 16000, 0, 8000, 4000, 2000, 1000, 500268};269 270#define RTQ2134_BUCK_DESC(_id) { \271	.desc = { \272		.name = "rtq2134_buck" #_id, \273		.of_match = of_match_ptr("buck" #_id), \274		.regulators_node = of_match_ptr("regulators"), \275		.id = RTQ2134_IDX_BUCK##_id, \276		.type = REGULATOR_VOLTAGE, \277		.owner = THIS_MODULE, \278		.ops = &rtq2134_buck_ops, \279		.n_voltages = RTQ2134_VOUT_MAXNUM, \280		.linear_ranges = rtq2134_buck_vout_ranges, \281		.n_linear_ranges = ARRAY_SIZE(rtq2134_buck_vout_ranges), \282		.vsel_reg = RTQ2134_REG_BUCK##_id##_DVS0CFG1, \283		.vsel_mask = RTQ2134_VOUT_MASK, \284		.enable_reg = RTQ2134_REG_BUCK##_id##_DVS0CFG0, \285		.enable_mask = RTQ2134_VOUTEN_MASK, \286		.active_discharge_reg = RTQ2134_REG_BUCK##_id##_CFG0, \287		.active_discharge_mask = RTQ2134_ACTDISCHG_MASK, \288		.active_discharge_on = RTQ2134_ACTDISCHG_MASK, \289		.ramp_reg = RTQ2134_REG_BUCK##_id##_RSPCFG, \290		.ramp_mask = RTQ2134_RSPUP_MASK, \291		.ramp_delay_table = rtq2134_buck_ramp_delay_table, \292		.n_ramp_values = ARRAY_SIZE(rtq2134_buck_ramp_delay_table), \293		.of_map_mode = rtq2134_buck_of_map_mode, \294		.of_parse_cb = rtq2134_buck_of_parse_cb, \295	}, \296	.mode_reg = RTQ2134_REG_BUCK##_id##_DVS0CFG0, \297	.mode_mask = RTQ2134_FCCM_MASK, \298	.suspend_mode_reg = RTQ2134_REG_BUCK##_id##_DVS1CFG0, \299	.suspend_mode_mask = RTQ2134_FCCM_MASK, \300	.suspend_enable_reg = RTQ2134_REG_BUCK##_id##_DVS1CFG0, \301	.suspend_enable_mask = RTQ2134_VOUTEN_MASK, \302	.suspend_vsel_reg = RTQ2134_REG_BUCK##_id##_DVS1CFG1, \303	.suspend_vsel_mask = RTQ2134_VOUT_MASK, \304	.dvs_ctrl_reg = RTQ2134_REG_BUCK##_id##_DVSCFG, \305}306 307static const struct rtq2134_regulator_desc rtq2134_regulator_descs[] = {308	RTQ2134_BUCK_DESC(1),309	RTQ2134_BUCK_DESC(2),310	RTQ2134_BUCK_DESC(3)311};312 313static bool rtq2134_is_accissible_reg(struct device *dev, unsigned int reg)314{315	if (reg >= RTQ2134_REG_IO_CHIPNAME && reg <= RTQ2134_REG_BUCK3_SLEWCTRL)316		return true;317	return false;318}319 320static const struct regmap_config rtq2134_regmap_config = {321	.reg_bits = 8,322	.val_bits = 8,323	.max_register = RTQ2134_REG_BUCK3_SLEWCTRL,324 325	.readable_reg = rtq2134_is_accissible_reg,326	.writeable_reg = rtq2134_is_accissible_reg,327};328 329static int rtq2134_probe(struct i2c_client *i2c)330{331	struct regmap *regmap;332	struct regulator_dev *rdev;333	struct regulator_config regulator_cfg = {};334	int i;335 336	regmap = devm_regmap_init_i2c(i2c, &rtq2134_regmap_config);337	if (IS_ERR(regmap)) {338		dev_err(&i2c->dev, "Failed to allocate regmap\n");339		return PTR_ERR(regmap);340	}341 342	regulator_cfg.dev = &i2c->dev;343	regulator_cfg.regmap = regmap;344	for (i = 0; i < ARRAY_SIZE(rtq2134_regulator_descs); i++) {345		rdev = devm_regulator_register(&i2c->dev,346					       &rtq2134_regulator_descs[i].desc,347					       &regulator_cfg);348		if (IS_ERR(rdev)) {349			dev_err(&i2c->dev, "Failed to init %d regulator\n", i);350			return PTR_ERR(rdev);351		}352	}353 354	return 0;355}356 357static const struct of_device_id __maybe_unused rtq2134_device_tables[] = {358	{ .compatible = "richtek,rtq2134", },359	{}360};361MODULE_DEVICE_TABLE(of, rtq2134_device_tables);362 363static struct i2c_driver rtq2134_driver = {364	.driver = {365		.name = "rtq2134",366		.probe_type = PROBE_PREFER_ASYNCHRONOUS,367		.of_match_table = rtq2134_device_tables,368	},369	.probe = rtq2134_probe,370};371module_i2c_driver(rtq2134_driver);372 373MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");374MODULE_DESCRIPTION("Richtek RTQ2134 Regulator Driver");375MODULE_LICENSE("GPL v2");376