Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: rt4831: Adds support for Richtek RT4831 DSV regulator

Adds support for Richtek RT4831 DSV Regulator

Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
Link: https://lore.kernel.org/r/1608217244-314-6-git-send-email-u0084500@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

ChiYuan Huang and committed by
Mark Brown
9351ab8b 934b05e8

+209
+10
drivers/regulator/Kconfig
··· 969 969 This adds support for voltage regulators in Richtek RT4801 Display Bias IC. 970 970 The device supports two regulators (DSVP/DSVN). 971 971 972 + config REGULATOR_RT4831 973 + tristate "Richtek RT4831 DSV Regulators" 974 + depends on MFD_RT4831 975 + help 976 + This adds support for voltage regulators in Richtek RT4831. 977 + There are three regulators (VLCM/DSVP/DSVN). 978 + VLCM is a virtual voltage input for DSVP/DSVN inside IC. 979 + And DSVP/DSVN is the real Vout range from 4V to 6.5V. 980 + It's common used to provide the power for the display panel. 981 + 972 982 config REGULATOR_RT5033 973 983 tristate "Richtek RT5033 Regulators" 974 984 depends on MFD_RT5033
+1
drivers/regulator/Makefile
··· 118 118 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o 119 119 obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o 120 120 obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o 121 + obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o 121 122 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o 122 123 obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o 123 124 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
+198
drivers/regulator/rt4831-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/bitops.h> 4 + #include <linux/kernel.h> 5 + #include <linux/module.h> 6 + #include <linux/of.h> 7 + #include <linux/platform_device.h> 8 + #include <linux/regmap.h> 9 + #include <linux/regulator/consumer.h> 10 + #include <linux/regulator/driver.h> 11 + 12 + enum { 13 + DSV_OUT_VLCM = 0, 14 + DSV_OUT_VPOS, 15 + DSV_OUT_VNEG, 16 + DSV_OUT_MAX 17 + }; 18 + 19 + #define RT4831_REG_DSVEN 0x09 20 + #define RT4831_REG_VLCM 0x0c 21 + #define RT4831_REG_VPOS 0x0d 22 + #define RT4831_REG_VNEG 0x0e 23 + #define RT4831_REG_FLAGS 0x0f 24 + 25 + #define RT4831_VOLT_MASK GENMASK(5, 0) 26 + #define RT4831_DSVMODE_SHIFT 5 27 + #define RT4831_DSVMODE_MASK GENMASK(7, 5) 28 + #define RT4831_POSADEN_MASK BIT(4) 29 + #define RT4831_NEGADEN_MASK BIT(3) 30 + #define RT4831_POSEN_MASK BIT(2) 31 + #define RT4831_NEGEN_MASK BIT(1) 32 + 33 + #define RT4831_OTP_MASK BIT(6) 34 + #define RT4831_LCMOVP_MASK BIT(5) 35 + #define RT4831_VPOSSCP_MASK BIT(3) 36 + #define RT4831_VNEGSCP_MASK BIT(2) 37 + 38 + #define DSV_MODE_NORMAL (0x4 << RT4831_DSVMODE_SHIFT) 39 + #define DSV_MODE_BYPASS (0x6 << RT4831_DSVMODE_SHIFT) 40 + #define STEP_UV 50000 41 + #define VLCM_MIN_UV 4000000 42 + #define VLCM_MAX_UV 7150000 43 + #define VLCM_N_VOLTAGES ((VLCM_MAX_UV - VLCM_MIN_UV) / STEP_UV + 1) 44 + #define VPN_MIN_UV 4000000 45 + #define VPN_MAX_UV 6500000 46 + #define VPN_N_VOLTAGES ((VPN_MAX_UV - VPN_MIN_UV) / STEP_UV + 1) 47 + 48 + static int rt4831_get_error_flags(struct regulator_dev *rdev, unsigned int *flags) 49 + { 50 + struct regmap *regmap = rdev_get_regmap(rdev); 51 + int rid = rdev_get_id(rdev); 52 + unsigned int val, events = 0; 53 + int ret; 54 + 55 + ret = regmap_read(regmap, RT4831_REG_FLAGS, &val); 56 + if (ret) 57 + return ret; 58 + 59 + if (val & RT4831_OTP_MASK) 60 + events |= REGULATOR_ERROR_OVER_TEMP; 61 + 62 + if (rid == DSV_OUT_VLCM && (val & RT4831_LCMOVP_MASK)) 63 + events |= REGULATOR_ERROR_OVER_CURRENT; 64 + 65 + if (rid == DSV_OUT_VPOS && (val & RT4831_VPOSSCP_MASK)) 66 + events |= REGULATOR_ERROR_OVER_CURRENT; 67 + 68 + if (rid == DSV_OUT_VNEG && (val & RT4831_VNEGSCP_MASK)) 69 + events |= REGULATOR_ERROR_OVER_CURRENT; 70 + 71 + *flags = events; 72 + return 0; 73 + } 74 + 75 + static const struct regulator_ops rt4831_dsvlcm_ops = { 76 + .list_voltage = regulator_list_voltage_linear, 77 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 78 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 79 + .set_bypass = regulator_set_bypass_regmap, 80 + .get_bypass = regulator_get_bypass_regmap, 81 + .get_error_flags = rt4831_get_error_flags, 82 + }; 83 + 84 + static const struct regulator_ops rt4831_dsvpn_ops = { 85 + .list_voltage = regulator_list_voltage_linear, 86 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 87 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 88 + .enable = regulator_enable_regmap, 89 + .disable = regulator_disable_regmap, 90 + .is_enabled = regulator_is_enabled_regmap, 91 + .set_active_discharge = regulator_set_active_discharge_regmap, 92 + .get_error_flags = rt4831_get_error_flags, 93 + }; 94 + 95 + static const struct regulator_desc rt4831_regulator_descs[] = { 96 + { 97 + .name = "DSVLCM", 98 + .ops = &rt4831_dsvlcm_ops, 99 + .of_match = of_match_ptr("DSVLCM"), 100 + .regulators_node = of_match_ptr("regulators"), 101 + .type = REGULATOR_VOLTAGE, 102 + .id = DSV_OUT_VLCM, 103 + .n_voltages = VLCM_N_VOLTAGES, 104 + .min_uV = VLCM_MIN_UV, 105 + .uV_step = STEP_UV, 106 + .vsel_reg = RT4831_REG_VLCM, 107 + .vsel_mask = RT4831_VOLT_MASK, 108 + .bypass_reg = RT4831_REG_DSVEN, 109 + .bypass_val_on = DSV_MODE_BYPASS, 110 + .bypass_val_off = DSV_MODE_NORMAL, 111 + }, 112 + { 113 + .name = "DSVP", 114 + .ops = &rt4831_dsvpn_ops, 115 + .of_match = of_match_ptr("DSVP"), 116 + .regulators_node = of_match_ptr("regulators"), 117 + .type = REGULATOR_VOLTAGE, 118 + .id = DSV_OUT_VPOS, 119 + .n_voltages = VPN_N_VOLTAGES, 120 + .min_uV = VPN_MIN_UV, 121 + .uV_step = STEP_UV, 122 + .vsel_reg = RT4831_REG_VPOS, 123 + .vsel_mask = RT4831_VOLT_MASK, 124 + .enable_reg = RT4831_REG_DSVEN, 125 + .enable_mask = RT4831_POSEN_MASK, 126 + .active_discharge_reg = RT4831_REG_DSVEN, 127 + .active_discharge_mask = RT4831_POSADEN_MASK, 128 + }, 129 + { 130 + .name = "DSVN", 131 + .ops = &rt4831_dsvpn_ops, 132 + .of_match = of_match_ptr("DSVN"), 133 + .regulators_node = of_match_ptr("regulators"), 134 + .type = REGULATOR_VOLTAGE, 135 + .id = DSV_OUT_VNEG, 136 + .n_voltages = VPN_N_VOLTAGES, 137 + .min_uV = VPN_MIN_UV, 138 + .uV_step = STEP_UV, 139 + .vsel_reg = RT4831_REG_VNEG, 140 + .vsel_mask = RT4831_VOLT_MASK, 141 + .enable_reg = RT4831_REG_DSVEN, 142 + .enable_mask = RT4831_NEGEN_MASK, 143 + .active_discharge_reg = RT4831_REG_DSVEN, 144 + .active_discharge_mask = RT4831_NEGADEN_MASK, 145 + } 146 + }; 147 + 148 + static int rt4831_regulator_probe(struct platform_device *pdev) 149 + { 150 + struct regmap *regmap; 151 + struct regulator_dev *rdev; 152 + struct regulator_config config = {}; 153 + int i, ret; 154 + 155 + regmap = dev_get_regmap(pdev->dev.parent, NULL); 156 + if (IS_ERR(regmap)) { 157 + dev_err(&pdev->dev, "Failed to init regmap\n"); 158 + return PTR_ERR(regmap); 159 + } 160 + 161 + /* Configure DSV mode to normal by default */ 162 + ret = regmap_update_bits(regmap, RT4831_REG_DSVEN, RT4831_DSVMODE_MASK, DSV_MODE_NORMAL); 163 + if (ret) { 164 + dev_err(&pdev->dev, "Failed to configure dsv mode to normal\n"); 165 + return ret; 166 + } 167 + 168 + config.dev = pdev->dev.parent; 169 + config.regmap = regmap; 170 + 171 + for (i = 0; i < DSV_OUT_MAX; i++) { 172 + rdev = devm_regulator_register(&pdev->dev, rt4831_regulator_descs + i, &config); 173 + if (IS_ERR(rdev)) { 174 + dev_err(&pdev->dev, "Failed to register %d regulator\n", i); 175 + return PTR_ERR(rdev); 176 + } 177 + } 178 + 179 + return 0; 180 + } 181 + 182 + static const struct platform_device_id rt4831_regulator_match[] = { 183 + { "rt4831-regulator", 0 }, 184 + {} 185 + }; 186 + MODULE_DEVICE_TABLE(platform, rt4831_regulator_match); 187 + 188 + static struct platform_driver rt4831_regulator_driver = { 189 + .driver = { 190 + .name = "rt4831-regulator", 191 + }, 192 + .id_table = rt4831_regulator_match, 193 + .probe = rt4831_regulator_probe, 194 + }; 195 + module_platform_driver(rt4831_regulator_driver); 196 + 197 + MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 198 + MODULE_LICENSE("GPL v2");