10555d414SChiYuan Huang // SPDX-License-Identifier: GPL-2.0+
20555d414SChiYuan Huang 
30555d414SChiYuan Huang #include <linux/bitops.h>
40555d414SChiYuan Huang #include <linux/i2c.h>
50555d414SChiYuan Huang #include <linux/kernel.h>
60555d414SChiYuan Huang #include <linux/module.h>
70555d414SChiYuan Huang #include <linux/of.h>
80555d414SChiYuan Huang #include <linux/regmap.h>
90555d414SChiYuan Huang #include <linux/regulator/driver.h>
100555d414SChiYuan Huang 
110555d414SChiYuan Huang enum {
120555d414SChiYuan Huang 	RTQ2134_IDX_BUCK1 = 0,
130555d414SChiYuan Huang 	RTQ2134_IDX_BUCK2,
140555d414SChiYuan Huang 	RTQ2134_IDX_BUCK3,
150555d414SChiYuan Huang 	RTQ2134_IDX_MAX
160555d414SChiYuan Huang };
170555d414SChiYuan Huang 
180555d414SChiYuan Huang #define RTQ2134_AUTO_MODE		0
190555d414SChiYuan Huang #define RTQ2134_FCCM_MODE		1
200555d414SChiYuan Huang 
210555d414SChiYuan Huang #define RTQ2134_BUCK_DVS0_CTRL		0
220555d414SChiYuan Huang #define RTQ2134_BUCK_VSEL_CTRL		2
230555d414SChiYuan Huang 
240555d414SChiYuan Huang #define RTQ2134_REG_IO_CHIPNAME		0x01
250555d414SChiYuan Huang #define RTQ2134_REG_FLT_RECORDTEMP	0x13
260555d414SChiYuan Huang #define RTQ2134_REG_FLT_RECORDBUCK(_id)	(0x14 + (_id))
270555d414SChiYuan Huang #define RTQ2134_REG_FLT_BUCKCTRL(_id)	(0x37 + (_id))
280555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_CFG0		0x42
290555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_DVS0CFG1	0x48
300555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_DVS0CFG0	0x49
310555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_DVS1CFG1	0x4A
320555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_DVS1CFG0	0x4B
330555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_DVSCFG	0x52
340555d414SChiYuan Huang #define RTQ2134_REG_BUCK1_RSPCFG	0x54
350555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_CFG0		0x5F
360555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_DVS0CFG1	0x62
370555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_DVS0CFG0	0x63
380555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_DVS1CFG1	0x64
390555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_DVS1CFG0	0x65
400555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_DVSCFG	0x6C
410555d414SChiYuan Huang #define RTQ2134_REG_BUCK2_RSPCFG	0x6E
420555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_CFG0		0x79
430555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_DVS0CFG1	0x7C
440555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_DVS0CFG0	0x7D
450555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_DVS1CFG1	0x7E
460555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_DVS1CFG0	0x7F
470555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_DVSCFG	0x86
480555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_RSPCFG	0x88
490555d414SChiYuan Huang #define RTQ2134_REG_BUCK3_SLEWCTRL	0x89
500555d414SChiYuan Huang 
510555d414SChiYuan Huang #define RTQ2134_VOUT_MAXNUM		256
520555d414SChiYuan Huang #define RTQ2134_VOUT_MASK		0xFF
530555d414SChiYuan Huang #define RTQ2134_VOUTEN_MASK		BIT(0)
540555d414SChiYuan Huang #define RTQ2134_ACTDISCHG_MASK		BIT(0)
550555d414SChiYuan Huang #define RTQ2134_RSPUP_MASK		GENMASK(6, 4)
560555d414SChiYuan Huang #define RTQ2134_FCCM_MASK		BIT(5)
570555d414SChiYuan Huang #define RTQ2134_UVHICCUP_MASK		BIT(3)
580555d414SChiYuan Huang #define RTQ2134_BUCKDVS_CTRL_MASK	GENMASK(1, 0)
590555d414SChiYuan Huang #define RTQ2134_CHIPOT_MASK		BIT(2)
600555d414SChiYuan Huang #define RTQ2134_BUCKOV_MASK		BIT(5)
610555d414SChiYuan Huang #define RTQ2134_BUCKUV_MASK		BIT(4)
620555d414SChiYuan Huang 
630555d414SChiYuan Huang struct rtq2134_regulator_desc {
640555d414SChiYuan Huang 	struct regulator_desc desc;
650555d414SChiYuan Huang 	/* Extension for proprietary register and mask */
660555d414SChiYuan Huang 	unsigned int mode_reg;
670555d414SChiYuan Huang 	unsigned int mode_mask;
680555d414SChiYuan Huang 	unsigned int suspend_enable_reg;
690555d414SChiYuan Huang 	unsigned int suspend_enable_mask;
700555d414SChiYuan Huang 	unsigned int suspend_vsel_reg;
710555d414SChiYuan Huang 	unsigned int suspend_vsel_mask;
720555d414SChiYuan Huang 	unsigned int suspend_mode_reg;
730555d414SChiYuan Huang 	unsigned int suspend_mode_mask;
740555d414SChiYuan Huang 	unsigned int dvs_ctrl_reg;
750555d414SChiYuan Huang };
760555d414SChiYuan Huang 
rtq2134_buck_set_mode(struct regulator_dev * rdev,unsigned int mode)770555d414SChiYuan Huang static int rtq2134_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
780555d414SChiYuan Huang {
790555d414SChiYuan Huang 	struct rtq2134_regulator_desc *desc =
800555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)rdev->desc;
810555d414SChiYuan Huang 	unsigned int val;
820555d414SChiYuan Huang 
830555d414SChiYuan Huang 	if (mode == REGULATOR_MODE_NORMAL)
840555d414SChiYuan Huang 		val = RTQ2134_AUTO_MODE;
850555d414SChiYuan Huang 	else if (mode == REGULATOR_MODE_FAST)
860555d414SChiYuan Huang 		val = RTQ2134_FCCM_MODE;
870555d414SChiYuan Huang 	else
880555d414SChiYuan Huang 		return -EINVAL;
890555d414SChiYuan Huang 
900555d414SChiYuan Huang 	val <<= ffs(desc->mode_mask) - 1;
910555d414SChiYuan Huang 	return regmap_update_bits(rdev->regmap, desc->mode_reg, desc->mode_mask,
920555d414SChiYuan Huang 				  val);
930555d414SChiYuan Huang }
940555d414SChiYuan Huang 
rtq2134_buck_get_mode(struct regulator_dev * rdev)950555d414SChiYuan Huang static unsigned int rtq2134_buck_get_mode(struct regulator_dev *rdev)
960555d414SChiYuan Huang {
970555d414SChiYuan Huang 	struct rtq2134_regulator_desc *desc =
980555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)rdev->desc;
990555d414SChiYuan Huang 	unsigned int mode;
1000555d414SChiYuan Huang 	int ret;
1010555d414SChiYuan Huang 
1020555d414SChiYuan Huang 	ret = regmap_read(rdev->regmap, desc->mode_reg, &mode);
1030555d414SChiYuan Huang 	if (ret)
1040555d414SChiYuan Huang 		return ret;
1050555d414SChiYuan Huang 
1060555d414SChiYuan Huang 	if (mode & desc->mode_mask)
1070555d414SChiYuan Huang 		return REGULATOR_MODE_FAST;
1080555d414SChiYuan Huang 	return REGULATOR_MODE_NORMAL;
1090555d414SChiYuan Huang }
1100555d414SChiYuan Huang 
rtq2134_buck_set_suspend_voltage(struct regulator_dev * rdev,int uV)1110555d414SChiYuan Huang static int rtq2134_buck_set_suspend_voltage(struct regulator_dev *rdev, int uV)
1120555d414SChiYuan Huang {
1130555d414SChiYuan Huang 	struct rtq2134_regulator_desc *desc =
1140555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)rdev->desc;
1150555d414SChiYuan Huang 	int sel;
1160555d414SChiYuan Huang 
1170555d414SChiYuan Huang 	sel = regulator_map_voltage_linear_range(rdev, uV, uV);
1180555d414SChiYuan Huang 	if (sel < 0)
1190555d414SChiYuan Huang 		return sel;
1200555d414SChiYuan Huang 
1210555d414SChiYuan Huang 	sel <<= ffs(desc->suspend_vsel_mask) - 1;
1220555d414SChiYuan Huang 
1230555d414SChiYuan Huang 	return regmap_update_bits(rdev->regmap, desc->suspend_vsel_reg,
1240555d414SChiYuan Huang 				  desc->suspend_vsel_mask, sel);
1250555d414SChiYuan Huang }
1260555d414SChiYuan Huang 
rtq2134_buck_set_suspend_enable(struct regulator_dev * rdev)1270555d414SChiYuan Huang static int rtq2134_buck_set_suspend_enable(struct regulator_dev *rdev)
1280555d414SChiYuan Huang {
1290555d414SChiYuan Huang 	struct rtq2134_regulator_desc *desc =
1300555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)rdev->desc;
1310555d414SChiYuan Huang 	unsigned int val = desc->suspend_enable_mask;
1320555d414SChiYuan Huang 
1330555d414SChiYuan Huang 	return regmap_update_bits(rdev->regmap, desc->suspend_enable_reg,
1340555d414SChiYuan Huang 				  desc->suspend_enable_mask, val);
1350555d414SChiYuan Huang }
1360555d414SChiYuan Huang 
rtq2134_buck_set_suspend_disable(struct regulator_dev * rdev)1370555d414SChiYuan Huang static int rtq2134_buck_set_suspend_disable(struct regulator_dev *rdev)
1380555d414SChiYuan Huang {
1390555d414SChiYuan Huang 	struct rtq2134_regulator_desc *desc =
1400555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)rdev->desc;
1410555d414SChiYuan Huang 
1420555d414SChiYuan Huang 	return regmap_update_bits(rdev->regmap, desc->suspend_enable_reg,
1430555d414SChiYuan Huang 				  desc->suspend_enable_mask, 0);
1440555d414SChiYuan Huang }
1450555d414SChiYuan Huang 
rtq2134_buck_set_suspend_mode(struct regulator_dev * rdev,unsigned int mode)1460555d414SChiYuan Huang static int rtq2134_buck_set_suspend_mode(struct regulator_dev *rdev,
1470555d414SChiYuan Huang 					 unsigned int mode)
1480555d414SChiYuan Huang {
1490555d414SChiYuan Huang 	struct rtq2134_regulator_desc *desc =
1500555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)rdev->desc;
1510555d414SChiYuan Huang 	unsigned int val;
1520555d414SChiYuan Huang 
1530555d414SChiYuan Huang 	if (mode == REGULATOR_MODE_NORMAL)
1540555d414SChiYuan Huang 		val = RTQ2134_AUTO_MODE;
1550555d414SChiYuan Huang 	else if (mode == REGULATOR_MODE_FAST)
1560555d414SChiYuan Huang 		val = RTQ2134_FCCM_MODE;
1570555d414SChiYuan Huang 	else
1580555d414SChiYuan Huang 		return -EINVAL;
1590555d414SChiYuan Huang 
1600555d414SChiYuan Huang 	val <<= ffs(desc->suspend_mode_mask) - 1;
1610555d414SChiYuan Huang 	return regmap_update_bits(rdev->regmap, desc->suspend_mode_reg,
1620555d414SChiYuan Huang 				  desc->suspend_mode_mask, val);
1630555d414SChiYuan Huang }
1640555d414SChiYuan Huang 
rtq2134_buck_get_error_flags(struct regulator_dev * rdev,unsigned int * flags)1650555d414SChiYuan Huang static int rtq2134_buck_get_error_flags(struct regulator_dev *rdev,
1660555d414SChiYuan Huang 					unsigned int *flags)
1670555d414SChiYuan Huang {
1680555d414SChiYuan Huang 	int rid = rdev_get_id(rdev);
1690555d414SChiYuan Huang 	unsigned int chip_error, buck_error, events = 0;
1700555d414SChiYuan Huang 	int ret;
1710555d414SChiYuan Huang 
1720555d414SChiYuan Huang 	ret = regmap_read(rdev->regmap, RTQ2134_REG_FLT_RECORDTEMP,
1730555d414SChiYuan Huang 			  &chip_error);
1740555d414SChiYuan Huang 	if (ret) {
1750555d414SChiYuan Huang 		dev_err(&rdev->dev, "Failed to get chip error flag\n");
1760555d414SChiYuan Huang 		return ret;
1770555d414SChiYuan Huang 	}
1780555d414SChiYuan Huang 
1790555d414SChiYuan Huang 	ret = regmap_read(rdev->regmap, RTQ2134_REG_FLT_RECORDBUCK(rid),
1800555d414SChiYuan Huang 			  &buck_error);
1810555d414SChiYuan Huang 	if (ret) {
1820555d414SChiYuan Huang 		dev_err(&rdev->dev, "Failed to get buck error flag\n");
1830555d414SChiYuan Huang 		return ret;
1840555d414SChiYuan Huang 	}
1850555d414SChiYuan Huang 
1860555d414SChiYuan Huang 	if (chip_error & RTQ2134_CHIPOT_MASK)
1870555d414SChiYuan Huang 		events |= REGULATOR_ERROR_OVER_TEMP;
1880555d414SChiYuan Huang 
1890555d414SChiYuan Huang 	if (buck_error & RTQ2134_BUCKUV_MASK)
1900555d414SChiYuan Huang 		events |= REGULATOR_ERROR_UNDER_VOLTAGE;
1910555d414SChiYuan Huang 
1920555d414SChiYuan Huang 	if (buck_error & RTQ2134_BUCKOV_MASK)
1930555d414SChiYuan Huang 		events |= REGULATOR_ERROR_REGULATION_OUT;
1940555d414SChiYuan Huang 
1950555d414SChiYuan Huang 	*flags = events;
1960555d414SChiYuan Huang 	return 0;
1970555d414SChiYuan Huang }
1980555d414SChiYuan Huang 
1990555d414SChiYuan Huang static const struct regulator_ops rtq2134_buck_ops = {
2000555d414SChiYuan Huang 	.list_voltage = regulator_list_voltage_linear_range,
2010555d414SChiYuan Huang 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
2020555d414SChiYuan Huang 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
2030555d414SChiYuan Huang 	.enable = regulator_enable_regmap,
2040555d414SChiYuan Huang 	.disable = regulator_disable_regmap,
2050555d414SChiYuan Huang 	.is_enabled = regulator_is_enabled_regmap,
2060555d414SChiYuan Huang 	.set_active_discharge = regulator_set_active_discharge_regmap,
2070555d414SChiYuan Huang 	.set_ramp_delay = regulator_set_ramp_delay_regmap,
2080555d414SChiYuan Huang 	.set_mode = rtq2134_buck_set_mode,
2090555d414SChiYuan Huang 	.get_mode = rtq2134_buck_get_mode,
2100555d414SChiYuan Huang 	.set_suspend_voltage = rtq2134_buck_set_suspend_voltage,
2110555d414SChiYuan Huang 	.set_suspend_enable = rtq2134_buck_set_suspend_enable,
2120555d414SChiYuan Huang 	.set_suspend_disable = rtq2134_buck_set_suspend_disable,
2130555d414SChiYuan Huang 	.set_suspend_mode = rtq2134_buck_set_suspend_mode,
2140555d414SChiYuan Huang 	.get_error_flags = rtq2134_buck_get_error_flags,
2150555d414SChiYuan Huang };
2160555d414SChiYuan Huang 
2170555d414SChiYuan Huang static const struct linear_range rtq2134_buck_vout_ranges[] = {
2180555d414SChiYuan Huang 	REGULATOR_LINEAR_RANGE(300000, 0, 200, 5000),
2190555d414SChiYuan Huang 	REGULATOR_LINEAR_RANGE(1310000, 201, 255, 10000)
2200555d414SChiYuan Huang };
2210555d414SChiYuan Huang 
rtq2134_buck_of_map_mode(unsigned int mode)2220555d414SChiYuan Huang static unsigned int rtq2134_buck_of_map_mode(unsigned int mode)
2230555d414SChiYuan Huang {
2240555d414SChiYuan Huang 	switch (mode) {
2250555d414SChiYuan Huang 	case RTQ2134_AUTO_MODE:
2260555d414SChiYuan Huang 		return REGULATOR_MODE_NORMAL;
2270555d414SChiYuan Huang 	case RTQ2134_FCCM_MODE:
2280555d414SChiYuan Huang 		return REGULATOR_MODE_FAST;
2290555d414SChiYuan Huang 	}
2300555d414SChiYuan Huang 
2310555d414SChiYuan Huang 	return REGULATOR_MODE_INVALID;
2320555d414SChiYuan Huang }
2330555d414SChiYuan Huang 
rtq2134_buck_of_parse_cb(struct device_node * np,const struct regulator_desc * desc,struct regulator_config * cfg)2340555d414SChiYuan Huang static int rtq2134_buck_of_parse_cb(struct device_node *np,
2350555d414SChiYuan Huang 				    const struct regulator_desc *desc,
2360555d414SChiYuan Huang 				    struct regulator_config *cfg)
2370555d414SChiYuan Huang {
2380555d414SChiYuan Huang 	struct rtq2134_regulator_desc *rdesc =
2390555d414SChiYuan Huang 		(struct rtq2134_regulator_desc *)desc;
2400555d414SChiYuan Huang 	int rid = desc->id;
2410555d414SChiYuan Huang 	bool uv_shutdown, vsel_dvs;
2420555d414SChiYuan Huang 	unsigned int val;
2430555d414SChiYuan Huang 	int ret;
2440555d414SChiYuan Huang 
2450555d414SChiYuan Huang 	vsel_dvs = of_property_read_bool(np, "richtek,use-vsel-dvs");
2460555d414SChiYuan Huang 	if (vsel_dvs)
2470555d414SChiYuan Huang 		val = RTQ2134_BUCK_VSEL_CTRL;
2480555d414SChiYuan Huang 	else
2490555d414SChiYuan Huang 		val = RTQ2134_BUCK_DVS0_CTRL;
2500555d414SChiYuan Huang 
2510555d414SChiYuan Huang 	ret = regmap_update_bits(cfg->regmap, rdesc->dvs_ctrl_reg,
2520555d414SChiYuan Huang 				 RTQ2134_BUCKDVS_CTRL_MASK, val);
2530555d414SChiYuan Huang 	if (ret)
2540555d414SChiYuan Huang 		return ret;
2550555d414SChiYuan Huang 
2560555d414SChiYuan Huang 	uv_shutdown = of_property_read_bool(np, "richtek,uv-shutdown");
2570555d414SChiYuan Huang 	if (uv_shutdown)
2580555d414SChiYuan Huang 		val = 0;
2590555d414SChiYuan Huang 	else
2600555d414SChiYuan Huang 		val = RTQ2134_UVHICCUP_MASK;
2610555d414SChiYuan Huang 
2620555d414SChiYuan Huang 	return regmap_update_bits(cfg->regmap, RTQ2134_REG_FLT_BUCKCTRL(rid),
2630555d414SChiYuan Huang 				  RTQ2134_UVHICCUP_MASK, val);
2640555d414SChiYuan Huang }
2650555d414SChiYuan Huang 
2660555d414SChiYuan Huang static const unsigned int rtq2134_buck_ramp_delay_table[] = {
2670555d414SChiYuan Huang 	0, 16000, 0, 8000, 4000, 2000, 1000, 500
2680555d414SChiYuan Huang };
2690555d414SChiYuan Huang 
2700555d414SChiYuan Huang #define RTQ2134_BUCK_DESC(_id) { \
2710555d414SChiYuan Huang 	.desc = { \
2720555d414SChiYuan Huang 		.name = "rtq2134_buck" #_id, \
2730555d414SChiYuan Huang 		.of_match = of_match_ptr("buck" #_id), \
2740555d414SChiYuan Huang 		.regulators_node = of_match_ptr("regulators"), \
2750555d414SChiYuan Huang 		.id = RTQ2134_IDX_BUCK##_id, \
2760555d414SChiYuan Huang 		.type = REGULATOR_VOLTAGE, \
2770555d414SChiYuan Huang 		.owner = THIS_MODULE, \
2780555d414SChiYuan Huang 		.ops = &rtq2134_buck_ops, \
2790555d414SChiYuan Huang 		.n_voltages = RTQ2134_VOUT_MAXNUM, \
2800555d414SChiYuan Huang 		.linear_ranges = rtq2134_buck_vout_ranges, \
2810555d414SChiYuan Huang 		.n_linear_ranges = ARRAY_SIZE(rtq2134_buck_vout_ranges), \
2820555d414SChiYuan Huang 		.vsel_reg = RTQ2134_REG_BUCK##_id##_DVS0CFG1, \
2830555d414SChiYuan Huang 		.vsel_mask = RTQ2134_VOUT_MASK, \
2840555d414SChiYuan Huang 		.enable_reg = RTQ2134_REG_BUCK##_id##_DVS0CFG0, \
2850555d414SChiYuan Huang 		.enable_mask = RTQ2134_VOUTEN_MASK, \
2860555d414SChiYuan Huang 		.active_discharge_reg = RTQ2134_REG_BUCK##_id##_CFG0, \
2870555d414SChiYuan Huang 		.active_discharge_mask = RTQ2134_ACTDISCHG_MASK, \
28817049bf9SAxel Lin 		.active_discharge_on = RTQ2134_ACTDISCHG_MASK, \
2890555d414SChiYuan Huang 		.ramp_reg = RTQ2134_REG_BUCK##_id##_RSPCFG, \
2900555d414SChiYuan Huang 		.ramp_mask = RTQ2134_RSPUP_MASK, \
2910555d414SChiYuan Huang 		.ramp_delay_table = rtq2134_buck_ramp_delay_table, \
2920555d414SChiYuan Huang 		.n_ramp_values = ARRAY_SIZE(rtq2134_buck_ramp_delay_table), \
2930555d414SChiYuan Huang 		.of_map_mode = rtq2134_buck_of_map_mode, \
2940555d414SChiYuan Huang 		.of_parse_cb = rtq2134_buck_of_parse_cb, \
2950555d414SChiYuan Huang 	}, \
2960555d414SChiYuan Huang 	.mode_reg = RTQ2134_REG_BUCK##_id##_DVS0CFG0, \
2970555d414SChiYuan Huang 	.mode_mask = RTQ2134_FCCM_MASK, \
2980555d414SChiYuan Huang 	.suspend_mode_reg = RTQ2134_REG_BUCK##_id##_DVS1CFG0, \
2990555d414SChiYuan Huang 	.suspend_mode_mask = RTQ2134_FCCM_MASK, \
3000555d414SChiYuan Huang 	.suspend_enable_reg = RTQ2134_REG_BUCK##_id##_DVS1CFG0, \
3010555d414SChiYuan Huang 	.suspend_enable_mask = RTQ2134_VOUTEN_MASK, \
3020555d414SChiYuan Huang 	.suspend_vsel_reg = RTQ2134_REG_BUCK##_id##_DVS1CFG1, \
3030555d414SChiYuan Huang 	.suspend_vsel_mask = RTQ2134_VOUT_MASK, \
3040555d414SChiYuan Huang 	.dvs_ctrl_reg = RTQ2134_REG_BUCK##_id##_DVSCFG, \
3050555d414SChiYuan Huang }
3060555d414SChiYuan Huang 
3070555d414SChiYuan Huang static const struct rtq2134_regulator_desc rtq2134_regulator_descs[] = {
3080555d414SChiYuan Huang 	RTQ2134_BUCK_DESC(1),
3090555d414SChiYuan Huang 	RTQ2134_BUCK_DESC(2),
3100555d414SChiYuan Huang 	RTQ2134_BUCK_DESC(3)
3110555d414SChiYuan Huang };
3120555d414SChiYuan Huang 
rtq2134_is_accissible_reg(struct device * dev,unsigned int reg)3130555d414SChiYuan Huang static bool rtq2134_is_accissible_reg(struct device *dev, unsigned int reg)
3140555d414SChiYuan Huang {
31515b4d2b9SChiYuan Huang 	if (reg >= RTQ2134_REG_IO_CHIPNAME && reg <= RTQ2134_REG_BUCK3_SLEWCTRL)
3160555d414SChiYuan Huang 		return true;
3170555d414SChiYuan Huang 	return false;
3180555d414SChiYuan Huang }
3190555d414SChiYuan Huang 
3200555d414SChiYuan Huang static const struct regmap_config rtq2134_regmap_config = {
3210555d414SChiYuan Huang 	.reg_bits = 8,
3220555d414SChiYuan Huang 	.val_bits = 8,
3230555d414SChiYuan Huang 	.max_register = RTQ2134_REG_BUCK3_SLEWCTRL,
3240555d414SChiYuan Huang 
3250555d414SChiYuan Huang 	.readable_reg = rtq2134_is_accissible_reg,
3260555d414SChiYuan Huang 	.writeable_reg = rtq2134_is_accissible_reg,
3270555d414SChiYuan Huang };
3280555d414SChiYuan Huang 
rtq2134_probe(struct i2c_client * i2c)3290555d414SChiYuan Huang static int rtq2134_probe(struct i2c_client *i2c)
3300555d414SChiYuan Huang {
3310555d414SChiYuan Huang 	struct regmap *regmap;
3320555d414SChiYuan Huang 	struct regulator_dev *rdev;
3330555d414SChiYuan Huang 	struct regulator_config regulator_cfg = {};
3340555d414SChiYuan Huang 	int i;
3350555d414SChiYuan Huang 
3360555d414SChiYuan Huang 	regmap = devm_regmap_init_i2c(i2c, &rtq2134_regmap_config);
3370555d414SChiYuan Huang 	if (IS_ERR(regmap)) {
3380555d414SChiYuan Huang 		dev_err(&i2c->dev, "Failed to allocate regmap\n");
3390555d414SChiYuan Huang 		return PTR_ERR(regmap);
3400555d414SChiYuan Huang 	}
3410555d414SChiYuan Huang 
3420555d414SChiYuan Huang 	regulator_cfg.dev = &i2c->dev;
3430555d414SChiYuan Huang 	regulator_cfg.regmap = regmap;
3440555d414SChiYuan Huang 	for (i = 0; i < ARRAY_SIZE(rtq2134_regulator_descs); i++) {
3450555d414SChiYuan Huang 		rdev = devm_regulator_register(&i2c->dev,
3460555d414SChiYuan Huang 					       &rtq2134_regulator_descs[i].desc,
3470555d414SChiYuan Huang 					       &regulator_cfg);
3480555d414SChiYuan Huang 		if (IS_ERR(rdev)) {
3490555d414SChiYuan Huang 			dev_err(&i2c->dev, "Failed to init %d regulator\n", i);
3500555d414SChiYuan Huang 			return PTR_ERR(rdev);
3510555d414SChiYuan Huang 		}
3520555d414SChiYuan Huang 	}
3530555d414SChiYuan Huang 
3540555d414SChiYuan Huang 	return 0;
3550555d414SChiYuan Huang }
3560555d414SChiYuan Huang 
3570555d414SChiYuan Huang static const struct of_device_id __maybe_unused rtq2134_device_tables[] = {
3580555d414SChiYuan Huang 	{ .compatible = "richtek,rtq2134", },
3590555d414SChiYuan Huang 	{}
3600555d414SChiYuan Huang };
3610555d414SChiYuan Huang MODULE_DEVICE_TABLE(of, rtq2134_device_tables);
3620555d414SChiYuan Huang 
3630555d414SChiYuan Huang static struct i2c_driver rtq2134_driver = {
3640555d414SChiYuan Huang 	.driver = {
3650555d414SChiYuan Huang 		.name = "rtq2134",
36646600ab1SDouglas Anderson 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
3670555d414SChiYuan Huang 		.of_match_table = rtq2134_device_tables,
3680555d414SChiYuan Huang 	},
369*964e1865SUwe Kleine-König 	.probe = rtq2134_probe,
3700555d414SChiYuan Huang };
3710555d414SChiYuan Huang module_i2c_driver(rtq2134_driver);
3720555d414SChiYuan Huang 
3730555d414SChiYuan Huang MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
3740555d414SChiYuan Huang MODULE_DESCRIPTION("Richtek RTQ2134 Regulator Driver");
3750555d414SChiYuan Huang MODULE_LICENSE("GPL v2");
376