Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

regulator: ltc3589: Convert to use simplified DT parsing

Use regulator core's simplified DT parsing code to simplify the driver
implementation.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Axel Lin and committed by
Mark Brown
ce62ba3a 362af736

+58 -136
+58 -136
drivers/regulator/ltc3589.c
··· 86 86 87 87 struct ltc3589_regulator { 88 88 struct regulator_desc desc; 89 - 90 - /* External feedback voltage divider */ 91 - unsigned int r1; 92 - unsigned int r2; 93 89 }; 94 90 95 91 struct ltc3589 { ··· 192 196 .get_voltage_sel = regulator_get_voltage_sel_regmap, 193 197 }; 194 198 199 + static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) 200 + { 201 + uint64_t tmp; 195 202 196 - #define LTC3589_REG(_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit) \ 203 + if (uV == 0) 204 + return 0; 205 + 206 + tmp = (uint64_t)uV * r1; 207 + do_div(tmp, r2); 208 + return uV + (unsigned int)tmp; 209 + } 210 + 211 + static int ltc3589_of_parse_cb(struct device_node *np, 212 + const struct regulator_desc *desc, 213 + struct regulator_config *config) 214 + { 215 + struct ltc3589 *ltc3589 = config->driver_data; 216 + struct ltc3589_regulator *rdesc = &ltc3589->regulator_descs[desc->id]; 217 + u32 r[2]; 218 + int ret; 219 + 220 + /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ 221 + if (desc->id >= LTC3589_LDO3) 222 + return 0; 223 + 224 + ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", r, 2); 225 + if (ret) { 226 + dev_err(ltc3589->dev, "Failed to parse voltage divider: %d\n", 227 + ret); 228 + return ret; 229 + } 230 + 231 + if (!r[0] || !r[1]) 232 + return 0; 233 + 234 + rdesc->desc.min_uV = ltc3589_scale(desc->min_uV, r[0], r[1]); 235 + rdesc->desc.uV_step = ltc3589_scale(desc->uV_step, r[0], r[1]); 236 + rdesc->desc.fixed_uV = ltc3589_scale(desc->fixed_uV, r[0], r[1]); 237 + 238 + return 0; 239 + } 240 + 241 + #define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit)\ 197 242 [LTC3589_ ## _name] = { \ 198 243 .desc = { \ 199 244 .name = #_name, \ 245 + .of_match = of_match_ptr(#_of_name), \ 246 + .regulators_node = of_match_ptr("regulators"), \ 247 + .of_parse_cb = ltc3589_of_parse_cb, \ 200 248 .n_voltages = (dtv_mask) + 1, \ 201 249 .min_uV = (go_bit) ? 362500 : 0, \ 202 250 .uV_step = (go_bit) ? 12500 : 0, \ ··· 259 219 }, \ 260 220 } 261 221 262 - #define LTC3589_LINEAR_REG(_name, _dtv1) \ 263 - LTC3589_REG(_name, linear, LTC3589_OVEN_ ## _name, \ 222 + #define LTC3589_LINEAR_REG(_name, _of_name, _dtv1) \ 223 + LTC3589_REG(_name, _of_name, linear, LTC3589_OVEN_ ## _name, \ 264 224 LTC3589_ ## _dtv1, 0x1f, \ 265 225 LTC3589_VCCR_ ## _name ## _GO) 266 226 267 - #define LTC3589_FIXED_REG(_name) \ 268 - LTC3589_REG(_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) 227 + #define LTC3589_FIXED_REG(_name, _of_name) \ 228 + LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) 269 229 270 230 static struct ltc3589_regulator ltc3589_regulators[LTC3589_NUM_REGULATORS] = { 271 - LTC3589_LINEAR_REG(SW1, B1DTV1), 272 - LTC3589_LINEAR_REG(SW2, B2DTV1), 273 - LTC3589_LINEAR_REG(SW3, B3DTV1), 274 - LTC3589_FIXED_REG(BB_OUT), 275 - LTC3589_REG(LDO1, fixed_standby, 0, 0, 0, 0), 276 - LTC3589_LINEAR_REG(LDO2, L2DTV1), 277 - LTC3589_FIXED_REG(LDO3), 278 - LTC3589_REG(LDO4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60, 0), 231 + LTC3589_LINEAR_REG(SW1, sw1, B1DTV1), 232 + LTC3589_LINEAR_REG(SW2, sw2, B2DTV1), 233 + LTC3589_LINEAR_REG(SW3, sw3, B3DTV1), 234 + LTC3589_FIXED_REG(BB_OUT, bb-out), 235 + LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0), 236 + LTC3589_LINEAR_REG(LDO2, ldo2, L2DTV1), 237 + LTC3589_FIXED_REG(LDO3, ldo3), 238 + LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 239 + 0x60, 0), 279 240 }; 280 - 281 - #ifdef CONFIG_OF 282 - static struct of_regulator_match ltc3589_matches[LTC3589_NUM_REGULATORS] = { 283 - { .name = "sw1", }, 284 - { .name = "sw2", }, 285 - { .name = "sw3", }, 286 - { .name = "bb-out", }, 287 - { .name = "ldo1", }, /* standby */ 288 - { .name = "ldo2", }, 289 - { .name = "ldo3", }, 290 - { .name = "ldo4", }, 291 - }; 292 - 293 - static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) 294 - { 295 - struct device *dev = ltc3589->dev; 296 - struct device_node *node; 297 - int i, ret; 298 - 299 - node = of_get_child_by_name(dev->of_node, "regulators"); 300 - if (!node) { 301 - dev_err(dev, "regulators node not found\n"); 302 - return -EINVAL; 303 - } 304 - 305 - ret = of_regulator_match(dev, node, ltc3589_matches, 306 - ARRAY_SIZE(ltc3589_matches)); 307 - of_node_put(node); 308 - if (ret < 0) { 309 - dev_err(dev, "Error parsing regulator init data: %d\n", ret); 310 - return ret; 311 - } 312 - if (ret != LTC3589_NUM_REGULATORS) { 313 - dev_err(dev, "Only %d regulators described in device tree\n", 314 - ret); 315 - return -EINVAL; 316 - } 317 - 318 - /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ 319 - for (i = 0; i < LTC3589_LDO3; i++) { 320 - struct ltc3589_regulator *desc = &ltc3589->regulator_descs[i]; 321 - struct device_node *np = ltc3589_matches[i].of_node; 322 - u32 vdiv[2]; 323 - 324 - ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", 325 - vdiv, 2); 326 - if (ret) { 327 - dev_err(dev, "Failed to parse voltage divider: %d\n", 328 - ret); 329 - return ret; 330 - } 331 - 332 - desc->r1 = vdiv[0]; 333 - desc->r2 = vdiv[1]; 334 - } 335 - 336 - return 0; 337 - } 338 - 339 - static inline struct regulator_init_data *match_init_data(int index) 340 - { 341 - return ltc3589_matches[index].init_data; 342 - } 343 - 344 - static inline struct device_node *match_of_node(int index) 345 - { 346 - return ltc3589_matches[index].of_node; 347 - } 348 - #else 349 - static inline int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) 350 - { 351 - return 0; 352 - } 353 - 354 - static inline struct regulator_init_data *match_init_data(int index) 355 - { 356 - return NULL; 357 - } 358 - 359 - static inline struct device_node *match_of_node(int index) 360 - { 361 - return NULL; 362 - } 363 - #endif 364 241 365 242 static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg) 366 243 { ··· 366 409 .cache_type = REGCACHE_RBTREE, 367 410 }; 368 411 369 - 370 412 static irqreturn_t ltc3589_isr(int irq, void *dev_id) 371 413 { 372 414 struct ltc3589 *ltc3589 = dev_id; ··· 397 441 regmap_write(ltc3589->regmap, LTC3589_CLIRQ, 0); 398 442 399 443 return IRQ_HANDLED; 400 - } 401 - 402 - static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) 403 - { 404 - uint64_t tmp; 405 - if (uV == 0) 406 - return 0; 407 - tmp = (uint64_t)uV * r1; 408 - do_div(tmp, r2); 409 - return uV + (unsigned int)tmp; 410 - } 411 - 412 - static void ltc3589_apply_fb_voltage_divider(struct ltc3589_regulator *rdesc) 413 - { 414 - struct regulator_desc *desc = &rdesc->desc; 415 - 416 - if (!rdesc->r1 || !rdesc->r2) 417 - return; 418 - 419 - desc->min_uV = ltc3589_scale(desc->min_uV, rdesc->r1, rdesc->r2); 420 - desc->uV_step = ltc3589_scale(desc->uV_step, rdesc->r1, rdesc->r2); 421 - desc->fixed_uV = ltc3589_scale(desc->fixed_uV, rdesc->r1, rdesc->r2); 422 444 } 423 445 424 446 static int ltc3589_probe(struct i2c_client *client, ··· 436 502 return ret; 437 503 } 438 504 439 - ret = ltc3589_parse_regulators_dt(ltc3589); 440 - if (ret) 441 - return ret; 442 - 443 505 for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { 444 506 struct ltc3589_regulator *rdesc = &ltc3589->regulator_descs[i]; 445 507 struct regulator_desc *desc = &rdesc->desc; 446 - struct regulator_init_data *init_data; 447 508 struct regulator_config config = { }; 448 509 449 - init_data = match_init_data(i); 450 - 451 - if (i < LTC3589_LDO3) 452 - ltc3589_apply_fb_voltage_divider(rdesc); 453 - 454 510 config.dev = dev; 455 - config.init_data = init_data; 456 511 config.driver_data = ltc3589; 457 - config.of_node = match_of_node(i); 458 512 459 513 ltc3589->regulators[i] = devm_regulator_register(dev, desc, 460 514 &config);