cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtq2134-regulator.c (10841B)


      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_MAX
     16};
     17
     18#define RTQ2134_AUTO_MODE		0
     19#define RTQ2134_FCCM_MODE		1
     20
     21#define RTQ2134_BUCK_DVS0_CTRL		0
     22#define RTQ2134_BUCK_VSEL_CTRL		2
     23
     24#define RTQ2134_REG_IO_CHIPNAME		0x01
     25#define RTQ2134_REG_FLT_RECORDTEMP	0x13
     26#define RTQ2134_REG_FLT_RECORDBUCK(_id)	(0x14 + (_id))
     27#define RTQ2134_REG_FLT_BUCKCTRL(_id)	(0x37 + (_id))
     28#define RTQ2134_REG_BUCK1_CFG0		0x42
     29#define RTQ2134_REG_BUCK1_DVS0CFG1	0x48
     30#define RTQ2134_REG_BUCK1_DVS0CFG0	0x49
     31#define RTQ2134_REG_BUCK1_DVS1CFG1	0x4A
     32#define RTQ2134_REG_BUCK1_DVS1CFG0	0x4B
     33#define RTQ2134_REG_BUCK1_DVSCFG	0x52
     34#define RTQ2134_REG_BUCK1_RSPCFG	0x54
     35#define RTQ2134_REG_BUCK2_CFG0		0x5F
     36#define RTQ2134_REG_BUCK2_DVS0CFG1	0x62
     37#define RTQ2134_REG_BUCK2_DVS0CFG0	0x63
     38#define RTQ2134_REG_BUCK2_DVS1CFG1	0x64
     39#define RTQ2134_REG_BUCK2_DVS1CFG0	0x65
     40#define RTQ2134_REG_BUCK2_DVSCFG	0x6C
     41#define RTQ2134_REG_BUCK2_RSPCFG	0x6E
     42#define RTQ2134_REG_BUCK3_CFG0		0x79
     43#define RTQ2134_REG_BUCK3_DVS0CFG1	0x7C
     44#define RTQ2134_REG_BUCK3_DVS0CFG0	0x7D
     45#define RTQ2134_REG_BUCK3_DVS1CFG1	0x7E
     46#define RTQ2134_REG_BUCK3_DVS1CFG0	0x7F
     47#define RTQ2134_REG_BUCK3_DVSCFG	0x86
     48#define RTQ2134_REG_BUCK3_RSPCFG	0x88
     49#define RTQ2134_REG_BUCK3_SLEWCTRL	0x89
     50
     51#define RTQ2134_VOUT_MAXNUM		256
     52#define RTQ2134_VOUT_MASK		0xFF
     53#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	else
     88		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	else
    158		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	else
    249		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	else
    260		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, 500
    268};
    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		.of_match_table = rtq2134_device_tables,
    367	},
    368	.probe_new = rtq2134_probe,
    369};
    370module_i2c_driver(rtq2134_driver);
    371
    372MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
    373MODULE_DESCRIPTION("Richtek RTQ2134 Regulator Driver");
    374MODULE_LICENSE("GPL v2");