| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * pv88080-regulator.c - Regulator device driver for PV88080 |
|---|
| 3 | | - * Copyright (C) 2016 Powerventure Semiconductor Ltd. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or |
|---|
| 6 | | - * modify it under the terms of the GNU General Public License |
|---|
| 7 | | - * as published by the Free Software Foundation; either version 2 |
|---|
| 8 | | - * of the License, or (at your option) any later version. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - * GNU General Public License for more details. |
|---|
| 14 | | - */ |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 2 | +// |
|---|
| 3 | +// pv88080-regulator.c - Regulator device driver for PV88080 |
|---|
| 4 | +// Copyright (C) 2016 Powerventure Semiconductor Ltd. |
|---|
| 15 | 5 | |
|---|
| 16 | 6 | #include <linux/err.h> |
|---|
| 17 | 7 | #include <linux/i2c.h> |
|---|
| .. | .. |
|---|
| 45 | 35 | |
|---|
| 46 | 36 | struct pv88080_regulator { |
|---|
| 47 | 37 | struct regulator_desc desc; |
|---|
| 48 | | - /* Current limiting */ |
|---|
| 49 | | - unsigned int n_current_limits; |
|---|
| 50 | | - const int *current_limits; |
|---|
| 51 | | - unsigned int limit_mask; |
|---|
| 52 | 38 | unsigned int mode_reg; |
|---|
| 53 | | - unsigned int limit_reg; |
|---|
| 54 | 39 | unsigned int conf2; |
|---|
| 55 | 40 | unsigned int conf5; |
|---|
| 56 | 41 | }; |
|---|
| .. | .. |
|---|
| 102 | 87 | * Entry indexes corresponds to register values. |
|---|
| 103 | 88 | */ |
|---|
| 104 | 89 | |
|---|
| 105 | | -static const int pv88080_buck1_limits[] = { |
|---|
| 90 | +static const unsigned int pv88080_buck1_limits[] = { |
|---|
| 106 | 91 | 3230000, 5130000, 6960000, 8790000 |
|---|
| 107 | 92 | }; |
|---|
| 108 | 93 | |
|---|
| 109 | | -static const int pv88080_buck23_limits[] = { |
|---|
| 94 | +static const unsigned int pv88080_buck23_limits[] = { |
|---|
| 110 | 95 | 1496000, 2393000, 3291000, 4189000 |
|---|
| 111 | 96 | }; |
|---|
| 112 | 97 | |
|---|
| .. | .. |
|---|
| 272 | 257 | PV88080_BUCK1_MODE_MASK, val); |
|---|
| 273 | 258 | } |
|---|
| 274 | 259 | |
|---|
| 275 | | -static int pv88080_set_current_limit(struct regulator_dev *rdev, int min, |
|---|
| 276 | | - int max) |
|---|
| 277 | | -{ |
|---|
| 278 | | - struct pv88080_regulator *info = rdev_get_drvdata(rdev); |
|---|
| 279 | | - int i; |
|---|
| 280 | | - |
|---|
| 281 | | - /* search for closest to maximum */ |
|---|
| 282 | | - for (i = info->n_current_limits - 1; i >= 0; i--) { |
|---|
| 283 | | - if (min <= info->current_limits[i] |
|---|
| 284 | | - && max >= info->current_limits[i]) { |
|---|
| 285 | | - return regmap_update_bits(rdev->regmap, |
|---|
| 286 | | - info->limit_reg, |
|---|
| 287 | | - info->limit_mask, |
|---|
| 288 | | - i << PV88080_BUCK1_ILIM_SHIFT); |
|---|
| 289 | | - } |
|---|
| 290 | | - } |
|---|
| 291 | | - |
|---|
| 292 | | - return -EINVAL; |
|---|
| 293 | | -} |
|---|
| 294 | | - |
|---|
| 295 | | -static int pv88080_get_current_limit(struct regulator_dev *rdev) |
|---|
| 296 | | -{ |
|---|
| 297 | | - struct pv88080_regulator *info = rdev_get_drvdata(rdev); |
|---|
| 298 | | - unsigned int data; |
|---|
| 299 | | - int ret; |
|---|
| 300 | | - |
|---|
| 301 | | - ret = regmap_read(rdev->regmap, info->limit_reg, &data); |
|---|
| 302 | | - if (ret < 0) |
|---|
| 303 | | - return ret; |
|---|
| 304 | | - |
|---|
| 305 | | - data = (data & info->limit_mask) >> PV88080_BUCK1_ILIM_SHIFT; |
|---|
| 306 | | - return info->current_limits[data]; |
|---|
| 307 | | -} |
|---|
| 308 | | - |
|---|
| 309 | 260 | static const struct regulator_ops pv88080_buck_ops = { |
|---|
| 310 | 261 | .get_mode = pv88080_buck_get_mode, |
|---|
| 311 | 262 | .set_mode = pv88080_buck_set_mode, |
|---|
| .. | .. |
|---|
| 315 | 266 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
|---|
| 316 | 267 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
|---|
| 317 | 268 | .list_voltage = regulator_list_voltage_linear, |
|---|
| 318 | | - .set_current_limit = pv88080_set_current_limit, |
|---|
| 319 | | - .get_current_limit = pv88080_get_current_limit, |
|---|
| 269 | + .set_current_limit = regulator_set_current_limit_regmap, |
|---|
| 270 | + .get_current_limit = regulator_get_current_limit_regmap, |
|---|
| 320 | 271 | }; |
|---|
| 321 | 272 | |
|---|
| 322 | 273 | static const struct regulator_ops pv88080_hvbuck_ops = { |
|---|
| .. | .. |
|---|
| 341 | 292 | .min_uV = min, \ |
|---|
| 342 | 293 | .uV_step = step, \ |
|---|
| 343 | 294 | .n_voltages = ((max) - (min))/(step) + 1, \ |
|---|
| 295 | + .curr_table = limits_array, \ |
|---|
| 296 | + .n_current_limits = ARRAY_SIZE(limits_array), \ |
|---|
| 344 | 297 | },\ |
|---|
| 345 | | - .current_limits = limits_array, \ |
|---|
| 346 | | - .n_current_limits = ARRAY_SIZE(limits_array), \ |
|---|
| 347 | 298 | } |
|---|
| 348 | 299 | |
|---|
| 349 | 300 | #define PV88080_HVBUCK(chip, regl_name, min, step, max) \ |
|---|
| .. | .. |
|---|
| 383 | 334 | |
|---|
| 384 | 335 | if (reg_val & PV88080_E_VDD_FLT) { |
|---|
| 385 | 336 | for (i = 0; i < PV88080_MAX_REGULATORS; i++) { |
|---|
| 386 | | - if (chip->rdev[i] != NULL) { |
|---|
| 337 | + if (chip->rdev[i] != NULL) |
|---|
| 387 | 338 | regulator_notifier_call_chain(chip->rdev[i], |
|---|
| 388 | 339 | REGULATOR_EVENT_UNDER_VOLTAGE, |
|---|
| 389 | 340 | NULL); |
|---|
| 390 | | - } |
|---|
| 391 | 341 | } |
|---|
| 392 | 342 | |
|---|
| 393 | 343 | err = regmap_write(chip->regmap, PV88080_REG_EVENT_A, |
|---|
| .. | .. |
|---|
| 400 | 350 | |
|---|
| 401 | 351 | if (reg_val & PV88080_E_OVER_TEMP) { |
|---|
| 402 | 352 | for (i = 0; i < PV88080_MAX_REGULATORS; i++) { |
|---|
| 403 | | - if (chip->rdev[i] != NULL) { |
|---|
| 353 | + if (chip->rdev[i] != NULL) |
|---|
| 404 | 354 | regulator_notifier_call_chain(chip->rdev[i], |
|---|
| 405 | 355 | REGULATOR_EVENT_OVER_TEMP, |
|---|
| 406 | 356 | NULL); |
|---|
| 407 | | - } |
|---|
| 408 | 357 | } |
|---|
| 409 | 358 | |
|---|
| 410 | 359 | err = regmap_write(chip->regmap, PV88080_REG_EVENT_A, |
|---|
| .. | .. |
|---|
| 521 | 470 | if (init_data) |
|---|
| 522 | 471 | config.init_data = &init_data[i]; |
|---|
| 523 | 472 | |
|---|
| 524 | | - pv88080_regulator_info[i].limit_reg |
|---|
| 473 | + pv88080_regulator_info[i].desc.csel_reg |
|---|
| 525 | 474 | = regmap_config->buck_regmap[i].buck_limit_reg; |
|---|
| 526 | | - pv88080_regulator_info[i].limit_mask |
|---|
| 475 | + pv88080_regulator_info[i].desc.csel_mask |
|---|
| 527 | 476 | = regmap_config->buck_regmap[i].buck_limit_mask; |
|---|
| 528 | 477 | pv88080_regulator_info[i].mode_reg |
|---|
| 529 | 478 | = regmap_config->buck_regmap[i].buck_mode_reg; |
|---|