| .. | .. |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Regulator driver for TPS65218 PMIC |
|---|
| 5 | 5 | * |
|---|
| 6 | | - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ |
|---|
| 6 | + * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * This program is free software; you can redistribute it and/or |
|---|
| 9 | 9 | * modify it under the terms of the GNU General Public License version 2 as |
|---|
| .. | .. |
|---|
| 29 | 29 | #include <linux/mfd/tps65218.h> |
|---|
| 30 | 30 | |
|---|
| 31 | 31 | #define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \ |
|---|
| 32 | | - _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \ |
|---|
| 32 | + _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm, \ |
|---|
| 33 | + _ct, _ncl) \ |
|---|
| 33 | 34 | { \ |
|---|
| 34 | 35 | .name = _name, \ |
|---|
| 35 | 36 | .of_match = _of, \ |
|---|
| .. | .. |
|---|
| 42 | 43 | .vsel_mask = _vm, \ |
|---|
| 43 | 44 | .csel_reg = _cr, \ |
|---|
| 44 | 45 | .csel_mask = _cm, \ |
|---|
| 46 | + .curr_table = _ct, \ |
|---|
| 47 | + .n_current_limits = _ncl, \ |
|---|
| 45 | 48 | .enable_reg = _er, \ |
|---|
| 46 | 49 | .enable_mask = _em, \ |
|---|
| 47 | 50 | .volt_table = NULL, \ |
|---|
| .. | .. |
|---|
| 53 | 56 | .bypass_mask = _sm, \ |
|---|
| 54 | 57 | } \ |
|---|
| 55 | 58 | |
|---|
| 56 | | -static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = { |
|---|
| 59 | +static const struct linear_range dcdc1_dcdc2_ranges[] = { |
|---|
| 57 | 60 | REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000), |
|---|
| 58 | 61 | REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000), |
|---|
| 59 | 62 | }; |
|---|
| 60 | 63 | |
|---|
| 61 | | -static const struct regulator_linear_range ldo1_dcdc3_ranges[] = { |
|---|
| 64 | +static const struct linear_range ldo1_dcdc3_ranges[] = { |
|---|
| 62 | 65 | REGULATOR_LINEAR_RANGE(900000, 0x0, 0x1a, 25000), |
|---|
| 63 | 66 | REGULATOR_LINEAR_RANGE(1600000, 0x1b, 0x3f, 50000), |
|---|
| 64 | 67 | }; |
|---|
| 65 | 68 | |
|---|
| 66 | | -static const struct regulator_linear_range dcdc4_ranges[] = { |
|---|
| 69 | +static const struct linear_range dcdc4_ranges[] = { |
|---|
| 67 | 70 | REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), |
|---|
| 68 | 71 | REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000), |
|---|
| 69 | 72 | }; |
|---|
| .. | .. |
|---|
| 125 | 128 | struct tps65218 *tps = rdev_get_drvdata(dev); |
|---|
| 126 | 129 | unsigned int rid = rdev_get_id(dev); |
|---|
| 127 | 130 | |
|---|
| 128 | | - if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) |
|---|
| 131 | + if (rid > TPS65218_LDO_1) |
|---|
| 129 | 132 | return -EINVAL; |
|---|
| 130 | 133 | |
|---|
| 131 | 134 | return tps65218_clear_bits(tps, dev->desc->bypass_reg, |
|---|
| .. | .. |
|---|
| 138 | 141 | struct tps65218 *tps = rdev_get_drvdata(dev); |
|---|
| 139 | 142 | unsigned int rid = rdev_get_id(dev); |
|---|
| 140 | 143 | |
|---|
| 141 | | - if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) |
|---|
| 144 | + if (rid > TPS65218_LDO_1) |
|---|
| 142 | 145 | return -EINVAL; |
|---|
| 143 | 146 | |
|---|
| 144 | 147 | /* |
|---|
| .. | .. |
|---|
| 162 | 165 | } |
|---|
| 163 | 166 | |
|---|
| 164 | 167 | /* Operations permitted on DCDC1, DCDC2 */ |
|---|
| 165 | | -static struct regulator_ops tps65218_dcdc12_ops = { |
|---|
| 168 | +static const struct regulator_ops tps65218_dcdc12_ops = { |
|---|
| 166 | 169 | .is_enabled = regulator_is_enabled_regmap, |
|---|
| 167 | 170 | .enable = tps65218_pmic_enable, |
|---|
| 168 | 171 | .disable = tps65218_pmic_disable, |
|---|
| .. | .. |
|---|
| 176 | 179 | }; |
|---|
| 177 | 180 | |
|---|
| 178 | 181 | /* Operations permitted on DCDC3, DCDC4 and LDO1 */ |
|---|
| 179 | | -static struct regulator_ops tps65218_ldo1_dcdc34_ops = { |
|---|
| 182 | +static const struct regulator_ops tps65218_ldo1_dcdc34_ops = { |
|---|
| 180 | 183 | .is_enabled = regulator_is_enabled_regmap, |
|---|
| 181 | 184 | .enable = tps65218_pmic_enable, |
|---|
| 182 | 185 | .disable = tps65218_pmic_disable, |
|---|
| .. | .. |
|---|
| 188 | 191 | .set_suspend_disable = tps65218_pmic_set_suspend_disable, |
|---|
| 189 | 192 | }; |
|---|
| 190 | 193 | |
|---|
| 191 | | -static const int ls3_currents[] = { 100, 200, 500, 1000 }; |
|---|
| 194 | +static const unsigned int ls3_currents[] = { 100000, 200000, 500000, 1000000 }; |
|---|
| 192 | 195 | |
|---|
| 193 | 196 | static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, |
|---|
| 194 | 197 | int lim_uA) |
|---|
| .. | .. |
|---|
| 204 | 207 | return -EINVAL; |
|---|
| 205 | 208 | |
|---|
| 206 | 209 | return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, |
|---|
| 207 | | - index << 2, TPS65218_PROTECT_L1); |
|---|
| 210 | + index << __builtin_ctz(dev->desc->csel_mask), |
|---|
| 211 | + TPS65218_PROTECT_L1); |
|---|
| 208 | 212 | } |
|---|
| 209 | 213 | |
|---|
| 210 | 214 | static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, |
|---|
| .. | .. |
|---|
| 214 | 218 | unsigned int num_currents = ARRAY_SIZE(ls3_currents); |
|---|
| 215 | 219 | struct tps65218 *tps = rdev_get_drvdata(dev); |
|---|
| 216 | 220 | |
|---|
| 217 | | - while (index < num_currents && ls3_currents[index] < max_uA) |
|---|
| 221 | + while (index < num_currents && ls3_currents[index] <= max_uA) |
|---|
| 218 | 222 | index++; |
|---|
| 219 | 223 | |
|---|
| 220 | 224 | index--; |
|---|
| .. | .. |
|---|
| 223 | 227 | return -EINVAL; |
|---|
| 224 | 228 | |
|---|
| 225 | 229 | return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, |
|---|
| 226 | | - index << 2, TPS65218_PROTECT_L1); |
|---|
| 230 | + index << __builtin_ctz(dev->desc->csel_mask), |
|---|
| 231 | + TPS65218_PROTECT_L1); |
|---|
| 227 | 232 | } |
|---|
| 228 | 233 | |
|---|
| 229 | | -static int tps65218_pmic_get_current_limit(struct regulator_dev *dev) |
|---|
| 230 | | -{ |
|---|
| 231 | | - int retval; |
|---|
| 232 | | - unsigned int index; |
|---|
| 233 | | - struct tps65218 *tps = rdev_get_drvdata(dev); |
|---|
| 234 | | - |
|---|
| 235 | | - retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index); |
|---|
| 236 | | - if (retval < 0) |
|---|
| 237 | | - return retval; |
|---|
| 238 | | - |
|---|
| 239 | | - index = (index & dev->desc->csel_mask) >> 2; |
|---|
| 240 | | - |
|---|
| 241 | | - return ls3_currents[index]; |
|---|
| 242 | | -} |
|---|
| 243 | | - |
|---|
| 244 | | -static struct regulator_ops tps65218_ls3_ops = { |
|---|
| 234 | +static const struct regulator_ops tps65218_ls23_ops = { |
|---|
| 245 | 235 | .is_enabled = regulator_is_enabled_regmap, |
|---|
| 246 | 236 | .enable = tps65218_pmic_enable, |
|---|
| 247 | 237 | .disable = tps65218_pmic_disable, |
|---|
| 248 | 238 | .set_input_current_limit = tps65218_pmic_set_input_current_lim, |
|---|
| 249 | 239 | .set_current_limit = tps65218_pmic_set_current_limit, |
|---|
| 250 | | - .get_current_limit = tps65218_pmic_get_current_limit, |
|---|
| 240 | + .get_current_limit = regulator_get_current_limit_regmap, |
|---|
| 251 | 241 | }; |
|---|
| 252 | 242 | |
|---|
| 253 | 243 | /* Operations permitted on DCDC5, DCDC6 */ |
|---|
| 254 | | -static struct regulator_ops tps65218_dcdc56_pmic_ops = { |
|---|
| 244 | +static const struct regulator_ops tps65218_dcdc56_pmic_ops = { |
|---|
| 255 | 245 | .is_enabled = regulator_is_enabled_regmap, |
|---|
| 256 | 246 | .enable = tps65218_pmic_enable, |
|---|
| 257 | 247 | .disable = tps65218_pmic_disable, |
|---|
| .. | .. |
|---|
| 266 | 256 | TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, |
|---|
| 267 | 257 | TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, |
|---|
| 268 | 258 | 2, 4000, 0, TPS65218_REG_SEQ3, |
|---|
| 269 | | - TPS65218_SEQ3_DC1_SEQ_MASK), |
|---|
| 259 | + TPS65218_SEQ3_DC1_SEQ_MASK, NULL, 0), |
|---|
| 270 | 260 | TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2, |
|---|
| 271 | 261 | REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, |
|---|
| 272 | 262 | TPS65218_REG_CONTROL_DCDC2, |
|---|
| 273 | 263 | TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, |
|---|
| 274 | 264 | TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, |
|---|
| 275 | 265 | 2, 4000, 0, TPS65218_REG_SEQ3, |
|---|
| 276 | | - TPS65218_SEQ3_DC2_SEQ_MASK), |
|---|
| 266 | + TPS65218_SEQ3_DC2_SEQ_MASK, NULL, 0), |
|---|
| 277 | 267 | TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3, |
|---|
| 278 | 268 | REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, |
|---|
| 279 | 269 | TPS65218_REG_CONTROL_DCDC3, |
|---|
| 280 | 270 | TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, |
|---|
| 281 | 271 | TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, |
|---|
| 282 | | - 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK), |
|---|
| 272 | + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK, |
|---|
| 273 | + NULL, 0), |
|---|
| 283 | 274 | TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4, |
|---|
| 284 | 275 | REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53, |
|---|
| 285 | 276 | TPS65218_REG_CONTROL_DCDC4, |
|---|
| 286 | 277 | TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, |
|---|
| 287 | 278 | TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, |
|---|
| 288 | | - 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK), |
|---|
| 279 | + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK, |
|---|
| 280 | + NULL, 0), |
|---|
| 289 | 281 | TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5, |
|---|
| 290 | 282 | REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, |
|---|
| 291 | 283 | -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, |
|---|
| 292 | 284 | 0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5, |
|---|
| 293 | | - TPS65218_SEQ5_DC5_SEQ_MASK), |
|---|
| 285 | + TPS65218_SEQ5_DC5_SEQ_MASK, NULL, 0), |
|---|
| 294 | 286 | TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6, |
|---|
| 295 | 287 | REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, |
|---|
| 296 | 288 | -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, |
|---|
| 297 | 289 | 0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5, |
|---|
| 298 | | - TPS65218_SEQ5_DC6_SEQ_MASK), |
|---|
| 290 | + TPS65218_SEQ5_DC6_SEQ_MASK, NULL, 0), |
|---|
| 299 | 291 | TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1, |
|---|
| 300 | 292 | REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, |
|---|
| 301 | 293 | TPS65218_REG_CONTROL_LDO1, |
|---|
| 302 | 294 | TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, |
|---|
| 303 | 295 | TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, |
|---|
| 304 | 296 | 2, 0, 0, TPS65218_REG_SEQ6, |
|---|
| 305 | | - TPS65218_SEQ6_LDO1_SEQ_MASK), |
|---|
| 297 | + TPS65218_SEQ6_LDO1_SEQ_MASK, NULL, 0), |
|---|
| 298 | + TPS65218_REGULATOR("LS2", "regulator-ls2", TPS65218_LS_2, |
|---|
| 299 | + REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, |
|---|
| 300 | + TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS2_EN, |
|---|
| 301 | + TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS2ILIM_MASK, |
|---|
| 302 | + NULL, 0, 0, 0, 0, 0, ls3_currents, |
|---|
| 303 | + ARRAY_SIZE(ls3_currents)), |
|---|
| 306 | 304 | TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3, |
|---|
| 307 | | - REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0, |
|---|
| 305 | + REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, |
|---|
| 308 | 306 | TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN, |
|---|
| 309 | 307 | TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK, |
|---|
| 310 | | - NULL, 0, 0, 0, 0, 0), |
|---|
| 308 | + NULL, 0, 0, 0, 0, 0, ls3_currents, |
|---|
| 309 | + ARRAY_SIZE(ls3_currents)), |
|---|
| 311 | 310 | }; |
|---|
| 312 | 311 | |
|---|
| 313 | 312 | static int tps65218_regulator_probe(struct platform_device *pdev) |
|---|