| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * pv88090-regulator.c - Regulator device driver for PV88090 |
|---|
| 3 | | - * Copyright (C) 2015 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 | +// pv88090-regulator.c - Regulator device driver for PV88090 |
|---|
| 4 | +// Copyright (C) 2015 Powerventure Semiconductor Ltd. |
|---|
| 15 | 5 | |
|---|
| 16 | 6 | #include <linux/err.h> |
|---|
| 17 | 7 | #include <linux/i2c.h> |
|---|
| .. | .. |
|---|
| 42 | 32 | |
|---|
| 43 | 33 | struct pv88090_regulator { |
|---|
| 44 | 34 | struct regulator_desc desc; |
|---|
| 45 | | - /* Current limiting */ |
|---|
| 46 | | - unsigned int n_current_limits; |
|---|
| 47 | | - const int *current_limits; |
|---|
| 48 | | - unsigned int limit_mask; |
|---|
| 49 | 35 | unsigned int conf; |
|---|
| 50 | 36 | unsigned int conf2; |
|---|
| 51 | 37 | }; |
|---|
| .. | .. |
|---|
| 71 | 57 | * Entry indexes corresponds to register values. |
|---|
| 72 | 58 | */ |
|---|
| 73 | 59 | |
|---|
| 74 | | -static const int pv88090_buck1_limits[] = { |
|---|
| 60 | +static const unsigned int pv88090_buck1_limits[] = { |
|---|
| 75 | 61 | 220000, 440000, 660000, 880000, 1100000, 1320000, 1540000, 1760000, |
|---|
| 76 | 62 | 1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000, |
|---|
| 77 | 63 | 3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000, |
|---|
| 78 | 64 | 5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000 |
|---|
| 79 | 65 | }; |
|---|
| 80 | 66 | |
|---|
| 81 | | -static const int pv88090_buck23_limits[] = { |
|---|
| 67 | +static const unsigned int pv88090_buck23_limits[] = { |
|---|
| 82 | 68 | 1496000, 2393000, 3291000, 4189000 |
|---|
| 83 | 69 | }; |
|---|
| 84 | 70 | |
|---|
| .. | .. |
|---|
| 150 | 136 | PV88090_BUCK1_MODE_MASK, val); |
|---|
| 151 | 137 | } |
|---|
| 152 | 138 | |
|---|
| 153 | | -static int pv88090_set_current_limit(struct regulator_dev *rdev, int min, |
|---|
| 154 | | - int max) |
|---|
| 155 | | -{ |
|---|
| 156 | | - struct pv88090_regulator *info = rdev_get_drvdata(rdev); |
|---|
| 157 | | - int i; |
|---|
| 158 | | - |
|---|
| 159 | | - /* search for closest to maximum */ |
|---|
| 160 | | - for (i = info->n_current_limits - 1; i >= 0; i--) { |
|---|
| 161 | | - if (min <= info->current_limits[i] |
|---|
| 162 | | - && max >= info->current_limits[i]) { |
|---|
| 163 | | - return regmap_update_bits(rdev->regmap, |
|---|
| 164 | | - info->conf, |
|---|
| 165 | | - info->limit_mask, |
|---|
| 166 | | - i << PV88090_BUCK1_ILIM_SHIFT); |
|---|
| 167 | | - } |
|---|
| 168 | | - } |
|---|
| 169 | | - |
|---|
| 170 | | - return -EINVAL; |
|---|
| 171 | | -} |
|---|
| 172 | | - |
|---|
| 173 | | -static int pv88090_get_current_limit(struct regulator_dev *rdev) |
|---|
| 174 | | -{ |
|---|
| 175 | | - struct pv88090_regulator *info = rdev_get_drvdata(rdev); |
|---|
| 176 | | - unsigned int data; |
|---|
| 177 | | - int ret; |
|---|
| 178 | | - |
|---|
| 179 | | - ret = regmap_read(rdev->regmap, info->conf, &data); |
|---|
| 180 | | - if (ret < 0) |
|---|
| 181 | | - return ret; |
|---|
| 182 | | - |
|---|
| 183 | | - data = (data & info->limit_mask) >> PV88090_BUCK1_ILIM_SHIFT; |
|---|
| 184 | | - return info->current_limits[data]; |
|---|
| 185 | | -} |
|---|
| 186 | | - |
|---|
| 187 | 139 | static const struct regulator_ops pv88090_buck_ops = { |
|---|
| 188 | 140 | .get_mode = pv88090_buck_get_mode, |
|---|
| 189 | 141 | .set_mode = pv88090_buck_set_mode, |
|---|
| .. | .. |
|---|
| 193 | 145 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
|---|
| 194 | 146 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
|---|
| 195 | 147 | .list_voltage = regulator_list_voltage_linear, |
|---|
| 196 | | - .set_current_limit = pv88090_set_current_limit, |
|---|
| 197 | | - .get_current_limit = pv88090_get_current_limit, |
|---|
| 148 | + .set_current_limit = regulator_set_current_limit_regmap, |
|---|
| 149 | + .get_current_limit = regulator_get_current_limit_regmap, |
|---|
| 198 | 150 | }; |
|---|
| 199 | 151 | |
|---|
| 200 | 152 | static const struct regulator_ops pv88090_ldo_ops = { |
|---|
| .. | .. |
|---|
| 223 | 175 | .enable_mask = PV88090_##regl_name##_EN, \ |
|---|
| 224 | 176 | .vsel_reg = PV88090_REG_##regl_name##_CONF0, \ |
|---|
| 225 | 177 | .vsel_mask = PV88090_V##regl_name##_MASK, \ |
|---|
| 178 | + .curr_table = limits_array, \ |
|---|
| 179 | + .n_current_limits = ARRAY_SIZE(limits_array), \ |
|---|
| 180 | + .csel_reg = PV88090_REG_##regl_name##_CONF1, \ |
|---|
| 181 | + .csel_mask = PV88090_##regl_name##_ILIM_MASK, \ |
|---|
| 226 | 182 | },\ |
|---|
| 227 | | - .current_limits = limits_array, \ |
|---|
| 228 | | - .n_current_limits = ARRAY_SIZE(limits_array), \ |
|---|
| 229 | | - .limit_mask = PV88090_##regl_name##_ILIM_MASK, \ |
|---|
| 230 | 183 | .conf = PV88090_REG_##regl_name##_CONF1, \ |
|---|
| 231 | 184 | .conf2 = PV88090_REG_##regl_name##_CONF2, \ |
|---|
| 232 | 185 | } |
|---|
| .. | .. |
|---|
| 273 | 226 | |
|---|
| 274 | 227 | if (reg_val & PV88090_E_VDD_FLT) { |
|---|
| 275 | 228 | for (i = 0; i < PV88090_MAX_REGULATORS; i++) { |
|---|
| 276 | | - if (chip->rdev[i] != NULL) { |
|---|
| 229 | + if (chip->rdev[i] != NULL) |
|---|
| 277 | 230 | regulator_notifier_call_chain(chip->rdev[i], |
|---|
| 278 | 231 | REGULATOR_EVENT_UNDER_VOLTAGE, |
|---|
| 279 | 232 | NULL); |
|---|
| 280 | | - } |
|---|
| 281 | 233 | } |
|---|
| 282 | 234 | |
|---|
| 283 | 235 | err = regmap_write(chip->regmap, PV88090_REG_EVENT_A, |
|---|
| .. | .. |
|---|
| 290 | 242 | |
|---|
| 291 | 243 | if (reg_val & PV88090_E_OVER_TEMP) { |
|---|
| 292 | 244 | for (i = 0; i < PV88090_MAX_REGULATORS; i++) { |
|---|
| 293 | | - if (chip->rdev[i] != NULL) { |
|---|
| 245 | + if (chip->rdev[i] != NULL) |
|---|
| 294 | 246 | regulator_notifier_call_chain(chip->rdev[i], |
|---|
| 295 | 247 | REGULATOR_EVENT_OVER_TEMP, |
|---|
| 296 | 248 | NULL); |
|---|
| 297 | | - } |
|---|
| 298 | 249 | } |
|---|
| 299 | 250 | |
|---|
| 300 | 251 | err = regmap_write(chip->regmap, PV88090_REG_EVENT_A, |
|---|
| .. | .. |
|---|
| 315 | 266 | /* |
|---|
| 316 | 267 | * I2C driver interface functions |
|---|
| 317 | 268 | */ |
|---|
| 318 | | -static int pv88090_i2c_probe(struct i2c_client *i2c, |
|---|
| 319 | | - const struct i2c_device_id *id) |
|---|
| 269 | +static int pv88090_i2c_probe(struct i2c_client *i2c) |
|---|
| 320 | 270 | { |
|---|
| 321 | 271 | struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); |
|---|
| 322 | 272 | struct pv88090 *chip; |
|---|
| .. | .. |
|---|
| 449 | 399 | .name = "pv88090", |
|---|
| 450 | 400 | .of_match_table = of_match_ptr(pv88090_dt_ids), |
|---|
| 451 | 401 | }, |
|---|
| 452 | | - .probe = pv88090_i2c_probe, |
|---|
| 402 | + .probe_new = pv88090_i2c_probe, |
|---|
| 453 | 403 | .id_table = pv88090_i2c_id, |
|---|
| 454 | 404 | }; |
|---|
| 455 | 405 | |
|---|