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

Configure Feed

Select the types of activity you want to include in your feed.

Add Richtek RT8092 support

Merge series from cy_huang@richtek.com:

This patch series add rt8092 regulator support.

+328
+5
Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml
··· 15 15 supply of 2.5V to 5.5V. It can provide up to 3.5A continuous current 16 16 capability at over 80% high efficiency. 17 17 18 + The RT8092 is similar type buck converter. Compared to RT5739, it can offer 19 + up to 4A output current and more output voltage range to meet the application 20 + on most mobile products. 21 + 18 22 allOf: 19 23 - $ref: regulator.yaml# 20 24 ··· 27 23 enum: 28 24 - richtek,rt5733 29 25 - richtek,rt5739 26 + - richtek,rt8092 30 27 31 28 reg: 32 29 maxItems: 1
+9
drivers/regulator/Kconfig
··· 1403 1403 It can support up to 14A output current and adjustable output voltage 1404 1404 from 0.4375V to 1.3875V, per step 12.5mV. 1405 1405 1406 + config REGULATOR_RT8092 1407 + tristate "Richtek RT8092 voltage regulator" 1408 + depends on I2C 1409 + select REGMAP_I2C 1410 + help 1411 + The RT8092 is a peak-current mode PWM step-down DC/DC converter with 1412 + I2C control interface. It is capable of delivering 4A continuing 1413 + current over a wide input range from 2.5V to 5.5V. 1414 + 1406 1415 config REGULATOR_RTQ2134 1407 1416 tristate "Richtek RTQ2134 SubPMIC Regulator" 1408 1417 depends on I2C
+1
drivers/regulator/Makefile
··· 162 162 obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o 163 163 obj-$(CONFIG_REGULATOR_RT6190) += rt6190-regulator.o 164 164 obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o 165 + obj-$(CONFIG_REGULATOR_RT8092) += rt8092.o 165 166 obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o 166 167 obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o 167 168 obj-$(CONFIG_REGULATOR_RTQ6752) += rtq6752-regulator.o
+313
drivers/regulator/rt8092.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // 3 + // Copyright (c) 2025 Richtek Technology Corp. 4 + // 5 + // Author: ChiYuan Huang <cy_huang@richtek.com> 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/bits.h> 9 + #include <linux/gpio/consumer.h> 10 + #include <linux/i2c.h> 11 + #include <linux/mod_devicetable.h> 12 + #include <linux/module.h> 13 + #include <linux/property.h> 14 + #include <linux/regmap.h> 15 + #include <linux/regulator/consumer.h> 16 + #include <linux/regulator/driver.h> 17 + #include <linux/regulator/of_regulator.h> 18 + 19 + #define RT8092_REG_MNTRPT 0x00 20 + #define RT8092_REG_VOUTH 0x10 21 + #define RT8092_REG_VOUTL 0x11 22 + #define RT8092_REG_PWMMODE 0x14 23 + #define RT8092_REG_EVENT 0x18 24 + #define RT8092_REG_VBANKH 0x1C 25 + #define RT8092_REG_VBANKL 0x1D 26 + #define RT8092_REG_VBOUND 0x1E 27 + 28 + #define RT8092_TSDEVT_MASK BIT(7) 29 + #define RT8092_PGEVT_MASK BIT(0) 30 + #define RT8092_VSEL_MASK GENMASK(6, 0) 31 + #define RT8092_VOUTEN_MASK BIT(7) 32 + #define RT8092_FPWML_MASK BIT(7) 33 + #define RT8092_FPWMH_MASK BIT(6) 34 + #define RT8092_OCPEVT_MASK BIT(7) 35 + #define RT8092_SCPEVT_MASK BIT(4) 36 + #define RT8092_VINUVEVT_MASK BIT(1) 37 + #define RT8092_VBANK_MASK GENMASK(1, 0) 38 + 39 + #define RT8092_MODE_AUTO 0 40 + #define RT8092_MODE_FPWM 1 41 + #define RT8092_VOUT_BASEUV 303125 42 + #define RT8092_VOUT_STEPUV 3125 43 + #define RT8092_VOUT_MINSEL 15 44 + #define RT8092_NUM_VOLTS 128 45 + #define RT8092_INITSS_US 400 46 + 47 + static int rt8092_get_vbank_index(struct regmap *regmap, bool vsel_high, unsigned int *vbank_idx) 48 + { 49 + unsigned int vbank_reg = vsel_high ? RT8092_REG_VBANKH : RT8092_REG_VBANKL; 50 + unsigned int index; 51 + int ret; 52 + 53 + ret = regmap_read(regmap, vbank_reg, &index); 54 + if (ret) 55 + return ret; 56 + 57 + *vbank_idx = FIELD_GET(RT8092_VBANK_MASK, index); 58 + return 0; 59 + } 60 + 61 + static int rt8092_set_operating_mode(struct regulator_dev *rdev, unsigned int mode) 62 + { 63 + const struct regulator_desc *desc = rdev->desc; 64 + struct regmap *regmap = rdev_get_regmap(rdev); 65 + unsigned int mode_mask, mode_val; 66 + 67 + mode_mask = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_FPWMH_MASK : RT8092_FPWML_MASK; 68 + 69 + switch (mode) { 70 + case REGULATOR_MODE_FAST: 71 + mode_val = mode_mask; 72 + break; 73 + case REGULATOR_MODE_NORMAL: 74 + mode_val = 0; 75 + break; 76 + default: 77 + return -EINVAL; 78 + } 79 + 80 + return regmap_update_bits(regmap, RT8092_REG_PWMMODE, mode_mask, mode_val); 81 + } 82 + 83 + static unsigned int rt8092_get_operating_mode(struct regulator_dev *rdev) 84 + { 85 + const struct regulator_desc *desc = rdev->desc; 86 + struct regmap *regmap = rdev_get_regmap(rdev); 87 + unsigned int mode_mask, mode_val; 88 + int ret; 89 + 90 + mode_mask = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_FPWMH_MASK : RT8092_FPWML_MASK; 91 + 92 + ret = regmap_read(regmap, RT8092_REG_PWMMODE, &mode_val); 93 + if (ret) 94 + return REGULATOR_MODE_INVALID; 95 + 96 + return mode_val & mode_mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; 97 + } 98 + 99 + static int rt8092_get_error_flags(struct regulator_dev *rdev, unsigned int *flags) 100 + { 101 + struct regmap *regmap = rdev_get_regmap(rdev); 102 + unsigned int mntrpt, evtrpt, events = 0; 103 + int ret; 104 + 105 + ret = regmap_read(regmap, RT8092_REG_MNTRPT, &mntrpt); 106 + if (ret) 107 + return ret; 108 + 109 + ret = regmap_read(regmap, RT8092_REG_EVENT, &evtrpt); 110 + if (ret) 111 + return ret; 112 + 113 + if (!(mntrpt & RT8092_PGEVT_MASK) || evtrpt & RT8092_VINUVEVT_MASK) 114 + events |= REGULATOR_ERROR_UNDER_VOLTAGE; 115 + 116 + if (mntrpt & RT8092_TSDEVT_MASK) 117 + events |= REGULATOR_ERROR_OVER_TEMP; 118 + 119 + if (evtrpt & RT8092_OCPEVT_MASK) 120 + events |= REGULATOR_ERROR_OVER_CURRENT; 121 + 122 + if (evtrpt & RT8092_SCPEVT_MASK) 123 + events |= REGULATOR_ERROR_FAIL; 124 + 125 + *flags = events; 126 + return 0; 127 + } 128 + 129 + 130 + static int rt8092_set_suspend_voltage(struct regulator_dev *rdev, int uV) 131 + { 132 + const struct regulator_desc *desc = rdev->desc; 133 + struct regmap *regmap = rdev_get_regmap(rdev); 134 + unsigned int vsel_reg, vsel_val, vbank_idx; 135 + bool vsel_high; 136 + int ret; 137 + 138 + vsel_reg = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_REG_VOUTL : RT8092_REG_VOUTH; 139 + vsel_high = desc->vsel_reg == RT8092_REG_VOUTH; 140 + 141 + ret = rt8092_get_vbank_index(regmap, vsel_high, &vbank_idx); 142 + if (ret) 143 + return ret; 144 + 145 + /* VOUT = (BASEUV + STEPUV * VSEL) * 2^vbank_idx */ 146 + uV >>= vbank_idx; 147 + if (uV < RT8092_VOUT_BASEUV) 148 + return -EINVAL; 149 + 150 + vsel_val = (uV - RT8092_VOUT_BASEUV) / RT8092_VOUT_STEPUV; 151 + if (vsel_val < RT8092_VOUT_MINSEL || vsel_val >= RT8092_NUM_VOLTS) 152 + return -EINVAL; 153 + 154 + return regmap_update_bits(regmap, vsel_reg, RT8092_VSEL_MASK, vsel_val); 155 + } 156 + 157 + static int rt8092_set_suspend_enable(struct regulator_dev *rdev) 158 + { 159 + const struct regulator_desc *desc = rdev->desc; 160 + struct regmap *regmap = rdev_get_regmap(rdev); 161 + unsigned int enable_reg; 162 + 163 + enable_reg = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_REG_VOUTL : RT8092_REG_VOUTH; 164 + return regmap_set_bits(regmap, enable_reg, RT8092_VOUTEN_MASK); 165 + } 166 + 167 + static int rt8092_set_suspend_disable(struct regulator_dev *rdev) 168 + { 169 + const struct regulator_desc *desc = rdev->desc; 170 + struct regmap *regmap = rdev_get_regmap(rdev); 171 + unsigned int enable_reg; 172 + 173 + enable_reg = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_REG_VOUTL : RT8092_REG_VOUTH; 174 + return regmap_clear_bits(regmap, enable_reg, RT8092_VOUTEN_MASK); 175 + } 176 + 177 + static int rt8092_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode) 178 + { 179 + const struct regulator_desc *desc = rdev->desc; 180 + struct regmap *regmap = rdev_get_regmap(rdev); 181 + unsigned int mode_mask, mode_val; 182 + 183 + mode_mask = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_FPWML_MASK : RT8092_FPWMH_MASK; 184 + 185 + switch (mode) { 186 + case REGULATOR_MODE_FAST: 187 + mode_val = mode_mask; 188 + break; 189 + case REGULATOR_MODE_NORMAL: 190 + mode_val = 0; 191 + break; 192 + default: 193 + return -EINVAL; 194 + } 195 + 196 + return regmap_update_bits(regmap, RT8092_REG_PWMMODE, mode_mask, mode_val); 197 + } 198 + 199 + static const struct regulator_ops rt8092_regulator_ops = { 200 + .list_voltage = regulator_list_voltage_linear, 201 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 202 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 203 + .enable = regulator_enable_regmap, 204 + .disable = regulator_disable_regmap, 205 + .is_enabled = regulator_is_enabled_regmap, 206 + .set_mode = rt8092_set_operating_mode, 207 + .get_mode = rt8092_get_operating_mode, 208 + .get_error_flags = rt8092_get_error_flags, 209 + .set_suspend_voltage = rt8092_set_suspend_voltage, 210 + .set_suspend_enable = rt8092_set_suspend_enable, 211 + .set_suspend_disable = rt8092_set_suspend_disable, 212 + .set_suspend_mode = rt8092_set_suspend_mode, 213 + }; 214 + 215 + static unsigned int rt8092_of_map_mode(unsigned int mode) 216 + { 217 + switch (mode) { 218 + case RT8092_MODE_AUTO: 219 + return REGULATOR_MODE_NORMAL; 220 + case RT8092_MODE_FPWM: 221 + return REGULATOR_MODE_FAST; 222 + default: 223 + return REGULATOR_MODE_INVALID; 224 + } 225 + } 226 + 227 + static const struct regmap_config rt8092_regmap_cfg = { 228 + .name = "rt8092", 229 + .reg_bits = 8, 230 + .val_bits = 8, 231 + .max_register = RT8092_REG_VBOUND, 232 + }; 233 + 234 + static int rt8092_probe(struct i2c_client *i2c) 235 + { 236 + unsigned int vbank_idx, min_uV, step_uV; 237 + struct regulator_config cfg = {}; 238 + struct device *dev = &i2c->dev; 239 + struct regulator_desc *desc; 240 + struct regulator_dev *rdev; 241 + struct gpio_desc *enable; 242 + struct regmap *regmap; 243 + bool vsel_high; 244 + int ret; 245 + 246 + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); 247 + if (!desc) 248 + return -ENOMEM; 249 + 250 + enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); 251 + if (IS_ERR(enable)) 252 + return dev_err_probe(dev, PTR_ERR(enable), "Failed get 'enable' gpio\n"); 253 + 254 + regmap = devm_regmap_init_i2c(i2c, &rt8092_regmap_cfg); 255 + if (IS_ERR(regmap)) 256 + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n"); 257 + 258 + vsel_high = device_property_read_bool(dev, "richtek,vsel-active-high"); 259 + 260 + ret = rt8092_get_vbank_index(regmap, vsel_high, &vbank_idx); 261 + if (ret) 262 + return dev_err_probe(dev, ret, "Failed to get VOUT bank index\n"); 263 + 264 + /* 265 + * step VOUT = STEP_UV * 2^vbank_idx 266 + * min VOUT = (BASEUV + STEPUV * VMIN_SEL) * 2^vbank_idx 267 + */ 268 + step_uV = RT8092_VOUT_STEPUV << vbank_idx; 269 + min_uV = (RT8092_VOUT_BASEUV + RT8092_VOUT_STEPUV * RT8092_VOUT_MINSEL) << vbank_idx; 270 + 271 + desc->name = "rt8092"; 272 + desc->owner = THIS_MODULE; 273 + desc->type = REGULATOR_VOLTAGE; 274 + desc->ops = &rt8092_regulator_ops; 275 + desc->n_voltages = RT8092_NUM_VOLTS; 276 + desc->min_uV = min_uV; 277 + desc->uV_step = step_uV; 278 + desc->linear_min_sel = RT8092_VOUT_MINSEL; 279 + desc->enable_reg = desc->vsel_reg = vsel_high ? RT8092_REG_VOUTH : RT8092_REG_VOUTL; 280 + desc->vsel_mask = RT8092_VSEL_MASK; 281 + desc->enable_mask = RT8092_VOUTEN_MASK; 282 + desc->enable_time = RT8092_INITSS_US; 283 + desc->of_map_mode = rt8092_of_map_mode; 284 + 285 + cfg.dev = dev; 286 + cfg.of_node = dev_of_node(dev); 287 + cfg.init_data = of_get_regulator_init_data(dev, dev_of_node(dev), desc); 288 + 289 + rdev = devm_regulator_register(dev, desc, &cfg); 290 + if (IS_ERR(rdev)) 291 + return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n"); 292 + 293 + return 0; 294 + } 295 + 296 + static const struct of_device_id rt8092_device_tables[] = { 297 + { .compatible = "richtek,rt8092" }, 298 + {} 299 + }; 300 + MODULE_DEVICE_TABLE(of, rt8092_device_tables); 301 + 302 + static struct i2c_driver rt8092_driver = { 303 + .driver = { 304 + .name = "rt8092", 305 + .of_match_table = rt8092_device_tables, 306 + }, 307 + .probe = rt8092_probe, 308 + }; 309 + module_i2c_driver(rt8092_driver); 310 + 311 + MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 312 + MODULE_DESCRIPTION("Richtek RT8092 Regulator Driver"); 313 + MODULE_LICENSE("GPL");