518 lines · c
1// SPDX-License-Identifier: GPL-2.0+2 3#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>4#include <linux/bits.h>5#include <linux/i2c.h>6#include <linux/interrupt.h>7#include <linux/kernel.h>8#include <linux/module.h>9#include <linux/of.h>10#include <linux/property.h>11#include <linux/regmap.h>12#include <linux/regulator/driver.h>13#include <linux/regulator/machine.h>14#include <linux/regulator/of_regulator.h>15 16#define RT5190A_REG_MANUFACTURE 0x0017#define RT5190A_REG_BUCK2VSEL 0x0418#define RT5190A_REG_BUCK3VSEL 0x0519#define RT5190A_REG_DCDCCNTL 0x0620#define RT5190A_REG_ENABLE 0x0721#define RT5190A_REG_DISCHARGE 0x0922#define RT5190A_REG_PROTMODE 0x0A23#define RT5190A_REG_MUTECNTL 0x0B24#define RT5190A_REG_PGSTAT 0x0F25#define RT5190A_REG_OVINT 0x1026#define RT5190A_REG_HOTDIEMASK 0x1727 28#define RT5190A_VSEL_MASK GENMASK(6, 0)29#define RT5190A_RID_BITMASK(rid) BIT(rid + 1)30#define RT5190A_BUCK1_DISCHG_MASK GENMASK(1, 0)31#define RT5190A_BUCK1_DISCHG_ONVAL 0x0132#define RT5190A_OVERVOLT_MASK GENMASK(7, 0)33#define RT5190A_UNDERVOLT_MASK GENMASK(15, 8)34#define RT5190A_CH234OT_MASK BIT(29)35#define RT5190A_CHIPOT_MASK BIT(28)36 37#define RT5190A_BUCK23_MINUV 60000038#define RT5190A_BUCK23_MAXUV 140000039#define RT5190A_BUCK23_STEPUV 1000040#define RT5190A_BUCK23_STEPNUM ((1400000 - 600000) / 10000 + 1)41 42enum {43 RT5190A_IDX_BUCK1 = 0,44 RT5190A_IDX_BUCK2,45 RT5190A_IDX_BUCK3,46 RT5190A_IDX_BUCK4,47 RT5190A_IDX_LDO,48 RT5190A_MAX_IDX49};50 51struct rt5190a_priv {52 struct device *dev;53 struct regmap *regmap;54 struct regulator_desc rdesc[RT5190A_MAX_IDX];55 struct regulator_dev *rdev[RT5190A_MAX_IDX];56};57 58static int rt5190a_get_error_flags(struct regulator_dev *rdev,59 unsigned int *flags)60{61 struct regmap *regmap = rdev_get_regmap(rdev);62 int rid = rdev_get_id(rdev);63 unsigned int pgood_stat;64 int ret;65 66 ret = regmap_read(regmap, RT5190A_REG_PGSTAT, &pgood_stat);67 if (ret)68 return ret;69 70 if (!(pgood_stat & RT5190A_RID_BITMASK(rid)))71 *flags = REGULATOR_ERROR_FAIL;72 else73 *flags = 0;74 75 return 0;76}77 78static int rt5190a_fixed_buck_set_mode(struct regulator_dev *rdev,79 unsigned int mode)80{81 struct regmap *regmap = rdev_get_regmap(rdev);82 int rid = rdev_get_id(rdev);83 unsigned int mask = RT5190A_RID_BITMASK(rid), val;84 85 switch (mode) {86 case REGULATOR_MODE_FAST:87 val = mask;88 break;89 case REGULATOR_MODE_NORMAL:90 val = 0;91 break;92 default:93 return -EINVAL;94 }95 96 return regmap_update_bits(regmap, RT5190A_REG_DCDCCNTL, mask, val);97}98 99static unsigned int rt5190a_fixed_buck_get_mode(struct regulator_dev *rdev)100{101 struct regmap *regmap = rdev_get_regmap(rdev);102 int rid = rdev_get_id(rdev);103 unsigned int val;104 int ret;105 106 ret = regmap_read(regmap, RT5190A_REG_DCDCCNTL, &val);107 if (ret) {108 dev_err(&rdev->dev, "Failed to get mode [%d]\n", ret);109 return ret;110 }111 112 if (val & RT5190A_RID_BITMASK(rid))113 return REGULATOR_MODE_FAST;114 115 return REGULATOR_MODE_NORMAL;116}117 118static const struct regulator_ops rt5190a_ranged_buck_ops = {119 .enable = regulator_enable_regmap,120 .disable = regulator_disable_regmap,121 .is_enabled = regulator_is_enabled_regmap,122 .set_voltage_sel = regulator_set_voltage_sel_regmap,123 .get_voltage_sel = regulator_get_voltage_sel_regmap,124 .list_voltage = regulator_list_voltage_linear,125 .set_active_discharge = regulator_set_active_discharge_regmap,126 .get_error_flags = rt5190a_get_error_flags,127};128 129static const struct regulator_ops rt5190a_fixed_buck_ops = {130 .enable = regulator_enable_regmap,131 .disable = regulator_disable_regmap,132 .is_enabled = regulator_is_enabled_regmap,133 .set_active_discharge = regulator_set_active_discharge_regmap,134 .set_mode = rt5190a_fixed_buck_set_mode,135 .get_mode = rt5190a_fixed_buck_get_mode,136 .get_error_flags = rt5190a_get_error_flags,137};138 139static const struct regulator_ops rt5190a_fixed_ldo_ops = {140 .enable = regulator_enable_regmap,141 .disable = regulator_disable_regmap,142 .is_enabled = regulator_is_enabled_regmap,143 .set_active_discharge = regulator_set_active_discharge_regmap,144 .get_error_flags = rt5190a_get_error_flags,145};146 147static irqreturn_t rt5190a_irq_handler(int irq, void *data)148{149 struct rt5190a_priv *priv = data;150 __le32 raws;151 unsigned int events, fields;152 static const struct {153 unsigned int bitmask;154 unsigned int report;155 } event_tbl[] = {156 { RT5190A_OVERVOLT_MASK, REGULATOR_ERROR_REGULATION_OUT },157 { RT5190A_UNDERVOLT_MASK, REGULATOR_ERROR_UNDER_VOLTAGE }158 };159 int i, j, ret;160 161 ret = regmap_raw_read(priv->regmap, RT5190A_REG_OVINT, &raws,162 sizeof(raws));163 if (ret) {164 dev_err(priv->dev, "Failed to read events\n");165 return IRQ_NONE;166 }167 168 events = le32_to_cpu(raws);169 170 ret = regmap_raw_write(priv->regmap, RT5190A_REG_OVINT, &raws,171 sizeof(raws));172 if (ret)173 dev_err(priv->dev, "Failed to write-clear events\n");174 175 /* Handle OV,UV events */176 for (i = 0; i < ARRAY_SIZE(event_tbl); i++) {177 fields = events & event_tbl[i].bitmask;178 fields >>= ffs(event_tbl[i].bitmask) - 1;179 180 for (j = 0; j < RT5190A_MAX_IDX; j++) {181 if (!(fields & RT5190A_RID_BITMASK(j)))182 continue;183 184 regulator_notifier_call_chain(priv->rdev[j],185 event_tbl[i].report,186 NULL);187 }188 }189 190 /* Handle CH234 OT event */191 if (events & RT5190A_CH234OT_MASK) {192 for (j = RT5190A_IDX_BUCK2; j < RT5190A_IDX_LDO; j++) {193 regulator_notifier_call_chain(priv->rdev[j],194 REGULATOR_ERROR_OVER_TEMP,195 NULL);196 }197 }198 199 /* Warning if CHIP OT occur */200 if (events & RT5190A_CHIPOT_MASK)201 dev_warn(priv->dev, "CHIP overheat\n");202 203 return IRQ_HANDLED;204}205 206static unsigned int rt5190a_of_map_mode(unsigned int mode)207{208 switch (mode) {209 case RT5190A_OPMODE_AUTO:210 return REGULATOR_MODE_NORMAL;211 case RT5190A_OPMODE_FPWM:212 return REGULATOR_MODE_FAST;213 default:214 return REGULATOR_MODE_INVALID;215 }216}217 218static int rt5190a_of_parse_cb(struct rt5190a_priv *priv, int rid,219 struct of_regulator_match *match)220{221 struct regulator_desc *desc = priv->rdesc + rid;222 struct regulator_init_data *init_data = match->init_data;223 struct device_node *np = match->of_node;224 bool latchup_enable;225 unsigned int mask = RT5190A_RID_BITMASK(rid), val;226 227 if (!init_data)228 return 0;229 230 switch (rid) {231 case RT5190A_IDX_BUCK1:232 case RT5190A_IDX_BUCK4:233 case RT5190A_IDX_LDO:234 init_data->constraints.apply_uV = 0;235 236 if (init_data->constraints.min_uV ==237 init_data->constraints.max_uV)238 desc->fixed_uV = init_data->constraints.min_uV;239 else {240 dev_err(priv->dev,241 "Variable voltage for fixed regulator\n");242 return -EINVAL;243 }244 break;245 default:246 break;247 }248 249 latchup_enable = of_property_read_bool(np, "richtek,latchup-enable");250 251 /* latchup: 0, default hiccup: 1 */252 val = !latchup_enable ? mask : 0;253 254 return regmap_update_bits(priv->regmap, RT5190A_REG_PROTMODE, mask, val);255}256 257static void rt5190a_fillin_regulator_desc(struct regulator_desc *desc, int rid)258{259 static const char * const regu_name[] = { "buck1", "buck2",260 "buck3", "buck4",261 "ldo" };262 static const char * const supply[] = { NULL, "vin2", "vin3", "vin4",263 "vinldo" };264 265 desc->name = regu_name[rid];266 desc->supply_name = supply[rid];267 desc->owner = THIS_MODULE;268 desc->type = REGULATOR_VOLTAGE;269 desc->id = rid;270 desc->enable_reg = RT5190A_REG_ENABLE;271 desc->enable_mask = RT5190A_RID_BITMASK(rid);272 desc->active_discharge_reg = RT5190A_REG_DISCHARGE;273 desc->active_discharge_mask = RT5190A_RID_BITMASK(rid);274 desc->active_discharge_on = RT5190A_RID_BITMASK(rid);275 276 switch (rid) {277 case RT5190A_IDX_BUCK1:278 desc->active_discharge_mask = RT5190A_BUCK1_DISCHG_MASK;279 desc->active_discharge_on = RT5190A_BUCK1_DISCHG_ONVAL;280 desc->n_voltages = 1;281 desc->ops = &rt5190a_fixed_buck_ops;282 desc->of_map_mode = rt5190a_of_map_mode;283 break;284 case RT5190A_IDX_BUCK2:285 desc->vsel_reg = RT5190A_REG_BUCK2VSEL;286 desc->vsel_mask = RT5190A_VSEL_MASK;287 desc->min_uV = RT5190A_BUCK23_MINUV;288 desc->uV_step = RT5190A_BUCK23_STEPUV;289 desc->n_voltages = RT5190A_BUCK23_STEPNUM;290 desc->ops = &rt5190a_ranged_buck_ops;291 break;292 case RT5190A_IDX_BUCK3:293 desc->vsel_reg = RT5190A_REG_BUCK3VSEL;294 desc->vsel_mask = RT5190A_VSEL_MASK;295 desc->min_uV = RT5190A_BUCK23_MINUV;296 desc->uV_step = RT5190A_BUCK23_STEPUV;297 desc->n_voltages = RT5190A_BUCK23_STEPNUM;298 desc->ops = &rt5190a_ranged_buck_ops;299 break;300 case RT5190A_IDX_BUCK4:301 desc->n_voltages = 1;302 desc->ops = &rt5190a_fixed_buck_ops;303 desc->of_map_mode = rt5190a_of_map_mode;304 break;305 case RT5190A_IDX_LDO:306 desc->n_voltages = 1;307 desc->ops = &rt5190a_fixed_ldo_ops;308 break;309 }310}311 312static struct of_regulator_match rt5190a_regulator_match[] = {313 { .name = "buck1", },314 { .name = "buck2", },315 { .name = "buck3", },316 { .name = "buck4", },317 { .name = "ldo", }318};319 320static int rt5190a_parse_regulator_dt_data(struct rt5190a_priv *priv)321{322 struct device_node *regulator_np;323 struct regulator_desc *reg_desc;324 struct of_regulator_match *match;325 int i, ret;326 327 for (i = 0; i < RT5190A_MAX_IDX; i++) {328 reg_desc = priv->rdesc + i;329 match = rt5190a_regulator_match + i;330 331 rt5190a_fillin_regulator_desc(reg_desc, i);332 333 match->desc = reg_desc;334 }335 336 regulator_np = of_get_child_by_name(priv->dev->of_node, "regulators");337 if (!regulator_np) {338 dev_err(priv->dev, "Could not find 'regulators' node\n");339 return -ENODEV;340 }341 342 ret = of_regulator_match(priv->dev, regulator_np,343 rt5190a_regulator_match,344 ARRAY_SIZE(rt5190a_regulator_match));345 346 of_node_put(regulator_np);347 348 if (ret < 0) {349 dev_err(priv->dev,350 "Error parsing regulator init data: %d\n", ret);351 return ret;352 }353 354 for (i = 0; i < RT5190A_MAX_IDX; i++) {355 match = rt5190a_regulator_match + i;356 357 ret = rt5190a_of_parse_cb(priv, i, match);358 if (ret) {359 dev_err(priv->dev, "Failed in [%d] of_parse_cb\n", i);360 return ret;361 }362 }363 364 return 0;365}366 367static const struct reg_sequence rt5190a_init_patch[] = {368 { 0x09, 0x3d, },369 { 0x0a, 0x3e, },370 { 0x0b, 0x01, },371 { 0x10, 0xff, },372 { 0x11, 0xff, },373 { 0x12, 0xff, },374 { 0x13, 0xff, },375 { 0x14, 0, },376 { 0x15, 0, },377 { 0x16, 0x3e, },378 { 0x17, 0, }379};380 381static int rt5190a_device_initialize(struct rt5190a_priv *priv)382{383 bool mute_enable;384 int ret;385 386 ret = regmap_register_patch(priv->regmap, rt5190a_init_patch,387 ARRAY_SIZE(rt5190a_init_patch));388 if (ret) {389 dev_err(priv->dev, "Failed to do register patch\n");390 return ret;391 }392 393 mute_enable = device_property_read_bool(priv->dev,394 "richtek,mute-enable");395 396 if (mute_enable) {397 ret = regmap_write(priv->regmap, RT5190A_REG_MUTECNTL, 0x00);398 if (ret) {399 dev_err(priv->dev, "Failed to enable mute function\n");400 return ret;401 }402 }403 404 return 0;405}406 407static int rt5190a_device_check(struct rt5190a_priv *priv)408{409 u16 devid;410 int ret;411 412 ret = regmap_raw_read(priv->regmap, RT5190A_REG_MANUFACTURE, &devid,413 sizeof(devid));414 if (ret)415 return ret;416 417 if (devid) {418 dev_err(priv->dev, "Incorrect device id 0x%04x\n", devid);419 return -ENODEV;420 }421 422 return 0;423}424 425static const struct regmap_config rt5190a_regmap_config = {426 .reg_bits = 8,427 .val_bits = 8,428 .max_register = RT5190A_REG_HOTDIEMASK,429};430 431static int rt5190a_probe(struct i2c_client *i2c)432{433 struct rt5190a_priv *priv;434 struct regulator_config cfg = {};435 int i, ret;436 437 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);438 if (!priv)439 return -ENOMEM;440 441 priv->dev = &i2c->dev;442 443 priv->regmap = devm_regmap_init_i2c(i2c, &rt5190a_regmap_config);444 if (IS_ERR(priv->regmap)) {445 dev_err(&i2c->dev, "Failed to allocate regmap\n");446 return PTR_ERR(priv->regmap);447 }448 449 ret = rt5190a_device_check(priv);450 if (ret) {451 dev_err(&i2c->dev, "Failed to check device %d\n", ret);452 return ret;453 }454 455 ret = rt5190a_device_initialize(priv);456 if (ret) {457 dev_err(&i2c->dev, "Failed to initialize the device\n");458 return ret;459 }460 461 ret = rt5190a_parse_regulator_dt_data(priv);462 if (ret) {463 dev_err(&i2c->dev, "Failed to parse regulator dt\n");464 return ret;465 }466 467 cfg.dev = &i2c->dev;468 cfg.regmap = priv->regmap;469 470 for (i = 0; i < RT5190A_MAX_IDX; i++) {471 struct regulator_desc *desc = priv->rdesc + i;472 struct of_regulator_match *match = rt5190a_regulator_match + i;473 474 cfg.init_data = match->init_data;475 cfg.of_node = match->of_node;476 477 priv->rdev[i] = devm_regulator_register(&i2c->dev, desc, &cfg);478 if (IS_ERR(priv->rdev[i])) {479 dev_err(&i2c->dev, "Failed to register regulator %s\n",480 desc->name);481 return PTR_ERR(priv->rdev[i]);482 }483 }484 485 if (i2c->irq) {486 ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,487 rt5190a_irq_handler,488 IRQF_ONESHOT,489 dev_name(&i2c->dev), priv);490 if (ret) {491 dev_err(&i2c->dev, "Failed to register interrupt\n");492 return ret;493 }494 }495 496 return 0;497}498 499static const struct of_device_id __maybe_unused rt5190a_device_table[] = {500 { .compatible = "richtek,rt5190a", },501 {}502};503MODULE_DEVICE_TABLE(of, rt5190a_device_table);504 505static struct i2c_driver rt5190a_driver = {506 .driver = {507 .name = "rt5190a",508 .probe_type = PROBE_PREFER_ASYNCHRONOUS,509 .of_match_table = rt5190a_device_table,510 },511 .probe = rt5190a_probe,512};513module_i2c_driver(rt5190a_driver);514 515MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");516MODULE_DESCRIPTION("Richtek RT5190A Regulator Driver");517MODULE_LICENSE("GPL v2");518