462 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2023 Analog Devices, Inc.4 * ADI Regulator driver for the MAX778575 * MAX77859 and MAX77831.6 */7#include <linux/bitfield.h>8#include <linux/i2c.h>9#include <linux/interrupt.h>10#include <linux/module.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#include <linux/util_macros.h>16 17#define MAX77857_REG_INT_SRC 0x1018#define MAX77857_REG_INT_MASK 0x1119#define MAX77857_REG_CONT1 0x1220#define MAX77857_REG_CONT2 0x1321#define MAX77857_REG_CONT3 0x1422 23#define MAX77857_INT_SRC_OCP BIT(0)24#define MAX77857_INT_SRC_THS BIT(1)25#define MAX77857_INT_SRC_HARDSHORT BIT(2)26#define MAX77857_INT_SRC_OVP BIT(3)27#define MAX77857_INT_SRC_POK BIT(4)28 29#define MAX77857_ILIM_MASK GENMASK(2, 0)30#define MAX77857_CONT1_FREQ GENMASK(4, 3)31#define MAX77857_CONT3_FPWM BIT(5)32 33#define MAX77859_REG_INT_SRC 0x1134#define MAX77859_REG_CONT1 0x1335#define MAX77859_REG_CONT2 0x1436#define MAX77859_REG_CONT3 0x1537#define MAX77859_REG_CONT5 0x1738#define MAX77859_CONT2_FPWM BIT(2)39#define MAX77859_CONT2_INTB BIT(3)40#define MAX77859_CONT3_DVS_START BIT(2)41#define MAX77859_VOLTAGE_SEL_MASK GENMASK(9, 0)42 43#define MAX77859_CURRENT_MIN 100000044#define MAX77859_CURRENT_MAX 500000045#define MAX77859_CURRENT_STEP 5000046 47enum max77857_id {48 ID_MAX77831 = 1,49 ID_MAX77857,50 ID_MAX77859,51 ID_MAX77859A,52};53 54static bool max77857_volatile_reg(struct device *dev, unsigned int reg)55{56 enum max77857_id id = (uintptr_t)dev_get_drvdata(dev);57 58 switch (id) {59 case ID_MAX77831:60 case ID_MAX77857:61 return reg == MAX77857_REG_INT_SRC;62 case ID_MAX77859:63 case ID_MAX77859A:64 return reg == MAX77859_REG_INT_SRC;65 default:66 return true;67 }68}69 70static const struct regmap_config max77857_regmap_config = {71 .reg_bits = 8,72 .val_bits = 8,73 .cache_type = REGCACHE_MAPLE,74 .volatile_reg = max77857_volatile_reg,75};76 77static int max77857_get_status(struct regulator_dev *rdev)78{79 unsigned int val;80 int ret;81 82 ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);83 if (ret)84 return ret;85 86 if (FIELD_GET(MAX77857_INT_SRC_POK, val))87 return REGULATOR_STATUS_ON;88 89 return REGULATOR_STATUS_ERROR;90}91 92static unsigned int max77857_get_mode(struct regulator_dev *rdev)93{94 enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);95 unsigned int regval;96 int ret;97 98 switch (id) {99 case ID_MAX77831:100 case ID_MAX77857:101 ret = regmap_read(rdev->regmap, MAX77857_REG_CONT3, ®val);102 if (ret)103 return ret;104 105 if (FIELD_GET(MAX77857_CONT3_FPWM, regval))106 return REGULATOR_MODE_FAST;107 108 break;109 case ID_MAX77859:110 case ID_MAX77859A:111 ret = regmap_read(rdev->regmap, MAX77859_REG_CONT2, ®val);112 if (ret)113 return ret;114 115 if (FIELD_GET(MAX77859_CONT2_FPWM, regval))116 return REGULATOR_MODE_FAST;117 118 break;119 default:120 return -EINVAL;121 }122 123 return REGULATOR_MODE_NORMAL;124}125 126static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode)127{128 enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);129 unsigned int reg, val;130 131 switch (id) {132 case ID_MAX77831:133 case ID_MAX77857:134 reg = MAX77857_REG_CONT3;135 val = MAX77857_CONT3_FPWM;136 break;137 case ID_MAX77859:138 case ID_MAX77859A:139 reg = MAX77859_REG_CONT2;140 val = MAX77859_CONT2_FPWM;141 break;142 default:143 return -EINVAL;144 }145 146 switch (mode) {147 case REGULATOR_MODE_FAST:148 return regmap_set_bits(rdev->regmap, reg, val);149 case REGULATOR_MODE_NORMAL:150 return regmap_clear_bits(rdev->regmap, reg, val);151 default:152 return -EINVAL;153 }154}155 156static int max77857_get_error_flags(struct regulator_dev *rdev,157 unsigned int *flags)158{159 unsigned int val;160 int ret;161 162 ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);163 if (ret)164 return ret;165 166 *flags = 0;167 168 if (FIELD_GET(MAX77857_INT_SRC_OVP, val))169 *flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;170 171 if (FIELD_GET(MAX77857_INT_SRC_OCP, val) ||172 FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val))173 *flags |= REGULATOR_ERROR_OVER_CURRENT;174 175 if (FIELD_GET(MAX77857_INT_SRC_THS, val))176 *flags |= REGULATOR_ERROR_OVER_TEMP;177 178 if (!FIELD_GET(MAX77857_INT_SRC_POK, val))179 *flags |= REGULATOR_ERROR_FAIL;180 181 return 0;182}183 184static struct linear_range max77859_lin_ranges[] = {185 REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000)186};187 188static const unsigned int max77859_ramp_table[4] = {189 1000, 500, 250, 125190};191 192static int max77859_set_voltage_sel(struct regulator_dev *rdev,193 unsigned int sel)194{195 __be16 reg;196 int ret;197 198 reg = cpu_to_be16(sel);199 200 ret = regmap_bulk_write(rdev->regmap, MAX77859_REG_CONT3, ®, 2);201 if (ret)202 return ret;203 204 /* actually apply new voltage */205 return regmap_set_bits(rdev->regmap, MAX77859_REG_CONT3,206 MAX77859_CONT3_DVS_START);207}208 209static int max77859_get_voltage_sel(struct regulator_dev *rdev)210{211 __be16 reg;212 int ret;213 214 ret = regmap_bulk_read(rdev->regmap, MAX77859_REG_CONT3, ®, 2);215 if (ret)216 return ret;217 218 return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg));219}220 221static int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)222{223 u32 selector;224 225 if (max_uA < MAX77859_CURRENT_MIN)226 return -EINVAL;227 228 selector = 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_STEP;229 230 selector = clamp_val(selector, 0x00, 0x7F);231 232 return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector);233}234 235static int max77859_get_current_limit(struct regulator_dev *rdev)236{237 u32 selector;238 int ret;239 240 ret = regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector);241 if (ret)242 return ret;243 244 if (selector <= 0x12)245 return MAX77859_CURRENT_MIN;246 247 if (selector >= 0x64)248 return MAX77859_CURRENT_MAX;249 250 return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP;251}252 253static const struct regulator_ops max77859_regulator_ops = {254 .list_voltage = regulator_list_voltage_linear_range,255 .set_voltage_sel = max77859_set_voltage_sel,256 .get_voltage_sel = max77859_get_voltage_sel,257 .set_ramp_delay = regulator_set_ramp_delay_regmap,258 .get_status = max77857_get_status,259 .set_mode = max77857_set_mode,260 .get_mode = max77857_get_mode,261 .get_error_flags = max77857_get_error_flags,262};263 264static const struct regulator_ops max77859a_regulator_ops = {265 .list_voltage = regulator_list_voltage_linear_range,266 .set_voltage_sel = max77859_set_voltage_sel,267 .get_voltage_sel = max77859_get_voltage_sel,268 .set_current_limit = max77859_set_current_limit,269 .get_current_limit = max77859_get_current_limit,270 .set_ramp_delay = regulator_set_ramp_delay_regmap,271 .get_status = max77857_get_status,272 .set_mode = max77857_set_mode,273 .get_mode = max77857_get_mode,274 .get_error_flags = max77857_get_error_flags,275};276 277static const struct regulator_ops max77857_regulator_ops = {278 .list_voltage = regulator_list_voltage_linear_range,279 .set_voltage_sel = regulator_set_voltage_sel_regmap,280 .get_voltage_sel = regulator_get_voltage_sel_regmap,281 .set_ramp_delay = regulator_set_ramp_delay_regmap,282 .get_status = max77857_get_status,283 .set_mode = max77857_set_mode,284 .get_mode = max77857_get_mode,285 .get_error_flags = max77857_get_error_flags,286};287 288static struct linear_range max77857_lin_ranges[] = {289 REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500)290};291 292static const unsigned int max77857_switch_freq[] = {293 1200000, 1500000, 1800000, 2100000294};295 296#define RAMAP_DELAY_INIT_VAL 1333297 298static const unsigned int max77857_ramp_table[2][4] = {299 { RAMAP_DELAY_INIT_VAL, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */300 { 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */301};302 303static struct regulator_desc max77857_regulator_desc = {304 .ops = &max77857_regulator_ops,305 .name = "max77857",306 .linear_ranges = max77857_lin_ranges,307 .n_linear_ranges = ARRAY_SIZE(max77857_lin_ranges),308 .vsel_mask = 0xFF,309 .vsel_reg = MAX77857_REG_CONT2,310 .ramp_delay_table = max77857_ramp_table[0],311 .n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]),312 .ramp_reg = MAX77857_REG_CONT3,313 .ramp_mask = GENMASK(1, 0),314 .ramp_delay = RAMAP_DELAY_INIT_VAL,315 .owner = THIS_MODULE,316};317 318static void max77857_calc_range(struct device *dev, enum max77857_id id)319{320 struct linear_range *range;321 unsigned long vref_step;322 u32 rtop = 0;323 u32 rbot = 0;324 325 device_property_read_u32(dev, "adi,rtop-ohms", &rtop);326 device_property_read_u32(dev, "adi,rbot-ohms", &rbot);327 328 if (!rbot || !rtop)329 return;330 331 switch (id) {332 case ID_MAX77831:333 case ID_MAX77857:334 range = max77857_lin_ranges;335 vref_step = 4900UL;336 break;337 case ID_MAX77859:338 case ID_MAX77859A:339 range = max77859_lin_ranges;340 vref_step = 1250UL;341 break;342 }343 344 range->step = DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot);345 range->min = range->step * range->min_sel;346}347 348static int max77857_probe(struct i2c_client *client)349{350 const struct i2c_device_id *i2c_id;351 struct device *dev = &client->dev;352 struct regulator_config cfg = { };353 struct regulator_dev *rdev;354 struct regmap *regmap;355 enum max77857_id id;356 u32 switch_freq = 0;357 int ret;358 359 i2c_id = i2c_client_get_device_id(client);360 if (!i2c_id)361 return -EINVAL;362 363 id = i2c_id->driver_data;364 365 dev_set_drvdata(dev, (void *)id);366 367 if (id == ID_MAX77859 || id == ID_MAX77859A) {368 max77857_regulator_desc.ops = &max77859_regulator_ops;369 max77857_regulator_desc.linear_ranges = max77859_lin_ranges;370 max77857_regulator_desc.ramp_delay_table = max77859_ramp_table;371 max77857_regulator_desc.ramp_delay = max77859_ramp_table[0];372 }373 374 if (id == ID_MAX77859A)375 max77857_regulator_desc.ops = &max77859a_regulator_ops;376 377 max77857_calc_range(dev, id);378 379 regmap = devm_regmap_init_i2c(client, &max77857_regmap_config);380 if (IS_ERR(regmap))381 return dev_err_probe(dev, PTR_ERR(regmap),382 "cannot initialize regmap\n");383 384 device_property_read_u32(dev, "adi,switch-frequency-hz", &switch_freq);385 if (switch_freq) {386 switch_freq = find_closest(switch_freq, max77857_switch_freq,387 ARRAY_SIZE(max77857_switch_freq));388 389 if (id == ID_MAX77831 && switch_freq == 3)390 switch_freq = 2;391 392 switch (id) {393 case ID_MAX77831:394 case ID_MAX77857:395 ret = regmap_update_bits(regmap, MAX77857_REG_CONT1,396 MAX77857_CONT1_FREQ, switch_freq);397 398 if (switch_freq >= 2)399 break;400 401 max77857_regulator_desc.ramp_delay_table = max77857_ramp_table[1];402 max77857_regulator_desc.ramp_delay = max77857_ramp_table[1][0];403 break;404 case ID_MAX77859:405 case ID_MAX77859A:406 ret = regmap_update_bits(regmap, MAX77859_REG_CONT1,407 MAX77857_CONT1_FREQ, switch_freq);408 break;409 }410 if (ret)411 return ret;412 }413 414 cfg.dev = dev;415 cfg.driver_data = (void *)id;416 cfg.regmap = regmap;417 cfg.init_data = of_get_regulator_init_data(dev, dev->of_node,418 &max77857_regulator_desc);419 if (!cfg.init_data)420 return -ENOMEM;421 422 rdev = devm_regulator_register(dev, &max77857_regulator_desc, &cfg);423 if (IS_ERR(rdev))424 return dev_err_probe(dev, PTR_ERR(rdev),425 "cannot register regulator\n");426 427 return 0;428}429 430static const struct i2c_device_id max77857_id[] = {431 { "max77831", ID_MAX77831 },432 { "max77857", ID_MAX77857 },433 { "max77859", ID_MAX77859 },434 { "max77859a", ID_MAX77859A },435 { }436};437MODULE_DEVICE_TABLE(i2c, max77857_id);438 439static const struct of_device_id max77857_of_id[] = {440 { .compatible = "adi,max77831", .data = (void *)ID_MAX77831 },441 { .compatible = "adi,max77857", .data = (void *)ID_MAX77857 },442 { .compatible = "adi,max77859", .data = (void *)ID_MAX77859 },443 { .compatible = "adi,max77859a", .data = (void *)ID_MAX77859A },444 { }445};446MODULE_DEVICE_TABLE(of, max77857_of_id);447 448static struct i2c_driver max77857_driver = {449 .driver = {450 .name = "max77857",451 .of_match_table = max77857_of_id,452 },453 .id_table = max77857_id,454 .probe = max77857_probe,455};456module_i2c_driver(max77857_driver);457 458MODULE_DESCRIPTION("Analog Devices MAX77857 Buck-Boost Converter Driver");459MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>");460MODULE_AUTHOR("Okan Sahin <Okan.Sahin@analog.com>");461MODULE_LICENSE("GPL");462