| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * da9211-regulator.c - Regulator device driver for DA9211/DA9212 |
|---|
| 3 | | - * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 |
|---|
| 4 | | - * Copyright (C) 2015 Dialog Semiconductor Ltd. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This library is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU Library General Public |
|---|
| 8 | | - * License as published by the Free Software Foundation; either |
|---|
| 9 | | - * version 2 of the License, or (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This library is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 14 | | - * Library General Public License for more details. |
|---|
| 15 | | - */ |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 2 | +// |
|---|
| 3 | +// da9211-regulator.c - Regulator device driver for DA9211/DA9212 |
|---|
| 4 | +// /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 |
|---|
| 5 | +// Copyright (C) 2015 Dialog Semiconductor Ltd. |
|---|
| 16 | 6 | |
|---|
| 17 | 7 | #include <linux/err.h> |
|---|
| 18 | 8 | #include <linux/i2c.h> |
|---|
| .. | .. |
|---|
| 27 | 17 | #include <linux/gpio/consumer.h> |
|---|
| 28 | 18 | #include <linux/regulator/of_regulator.h> |
|---|
| 29 | 19 | #include <linux/regulator/da9211.h> |
|---|
| 20 | +#include <dt-bindings/regulator/dlg,da9211-regulator.h> |
|---|
| 30 | 21 | #include "da9211-regulator.h" |
|---|
| 31 | 22 | |
|---|
| 32 | 23 | /* DEVICE IDs */ |
|---|
| 33 | 24 | #define DA9211_DEVICE_ID 0x22 |
|---|
| 34 | 25 | #define DA9213_DEVICE_ID 0x23 |
|---|
| 35 | 26 | #define DA9215_DEVICE_ID 0x24 |
|---|
| 36 | | - |
|---|
| 37 | | -#define DA9211_BUCK_MODE_SLEEP 1 |
|---|
| 38 | | -#define DA9211_BUCK_MODE_SYNC 2 |
|---|
| 39 | | -#define DA9211_BUCK_MODE_AUTO 3 |
|---|
| 40 | 27 | |
|---|
| 41 | 28 | /* DA9211 REGULATOR IDs */ |
|---|
| 42 | 29 | #define DA9211_ID_BUCKA 0 |
|---|
| .. | .. |
|---|
| 64 | 51 | }, |
|---|
| 65 | 52 | }; |
|---|
| 66 | 53 | |
|---|
| 54 | +static bool da9211_volatile_reg(struct device *dev, unsigned int reg) |
|---|
| 55 | +{ |
|---|
| 56 | + switch (reg) { |
|---|
| 57 | + case DA9211_REG_STATUS_A: |
|---|
| 58 | + case DA9211_REG_STATUS_B: |
|---|
| 59 | + case DA9211_REG_EVENT_A: |
|---|
| 60 | + case DA9211_REG_EVENT_B: |
|---|
| 61 | + return true; |
|---|
| 62 | + } |
|---|
| 63 | + return false; |
|---|
| 64 | +} |
|---|
| 65 | + |
|---|
| 67 | 66 | static const struct regmap_config da9211_regmap_config = { |
|---|
| 68 | 67 | .reg_bits = 8, |
|---|
| 69 | 68 | .val_bits = 8, |
|---|
| 70 | 69 | .max_register = 5 * 128, |
|---|
| 70 | + .volatile_reg = da9211_volatile_reg, |
|---|
| 71 | + .cache_type = REGCACHE_RBTREE, |
|---|
| 71 | 72 | .ranges = da9211_regmap_range, |
|---|
| 72 | 73 | .num_ranges = ARRAY_SIZE(da9211_regmap_range), |
|---|
| 73 | 74 | }; |
|---|
| .. | .. |
|---|
| 98 | 99 | 4000000, 4200000, 4400000, 4600000, 4800000, 5000000, 5200000, 5400000, |
|---|
| 99 | 100 | 5600000, 5800000, 6000000, 6200000, 6400000, 6600000, 6800000, 7000000 |
|---|
| 100 | 101 | }; |
|---|
| 102 | + |
|---|
| 103 | +static unsigned int da9211_map_buck_mode(unsigned int mode) |
|---|
| 104 | +{ |
|---|
| 105 | + switch (mode) { |
|---|
| 106 | + case DA9211_BUCK_MODE_SLEEP: |
|---|
| 107 | + return REGULATOR_MODE_STANDBY; |
|---|
| 108 | + case DA9211_BUCK_MODE_SYNC: |
|---|
| 109 | + return REGULATOR_MODE_FAST; |
|---|
| 110 | + case DA9211_BUCK_MODE_AUTO: |
|---|
| 111 | + return REGULATOR_MODE_NORMAL; |
|---|
| 112 | + default: |
|---|
| 113 | + return REGULATOR_MODE_INVALID; |
|---|
| 114 | + } |
|---|
| 115 | +} |
|---|
| 101 | 116 | |
|---|
| 102 | 117 | static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) |
|---|
| 103 | 118 | { |
|---|
| .. | .. |
|---|
| 246 | 261 | .vsel_reg = DA9211_REG_VBUCKA_A + DA9211_ID_##_id * 2,\ |
|---|
| 247 | 262 | .vsel_mask = DA9211_VBUCK_MASK,\ |
|---|
| 248 | 263 | .owner = THIS_MODULE,\ |
|---|
| 264 | + .of_map_mode = da9211_map_buck_mode,\ |
|---|
| 249 | 265 | } |
|---|
| 250 | 266 | |
|---|
| 251 | 267 | static struct regulator_desc da9211_regulators[] = { |
|---|
| .. | .. |
|---|
| 255 | 271 | |
|---|
| 256 | 272 | #ifdef CONFIG_OF |
|---|
| 257 | 273 | static struct of_regulator_match da9211_matches[] = { |
|---|
| 258 | | - [DA9211_ID_BUCKA] = { .name = "BUCKA" }, |
|---|
| 259 | | - [DA9211_ID_BUCKB] = { .name = "BUCKB" }, |
|---|
| 274 | + [DA9211_ID_BUCKA] = { |
|---|
| 275 | + .name = "BUCKA", |
|---|
| 276 | + .desc = &da9211_regulators[DA9211_ID_BUCKA], |
|---|
| 277 | + }, |
|---|
| 278 | + [DA9211_ID_BUCKB] = { |
|---|
| 279 | + .name = "BUCKB", |
|---|
| 280 | + .desc = &da9211_regulators[DA9211_ID_BUCKB], |
|---|
| 281 | + }, |
|---|
| 260 | 282 | }; |
|---|
| 261 | 283 | |
|---|
| 262 | 284 | static struct da9211_pdata *da9211_parse_regulators_dt( |
|---|
| .. | .. |
|---|
| 293 | 315 | |
|---|
| 294 | 316 | pdata->init_data[n] = da9211_matches[i].init_data; |
|---|
| 295 | 317 | pdata->reg_node[n] = da9211_matches[i].of_node; |
|---|
| 296 | | - pdata->gpiod_ren[n] = devm_gpiod_get_from_of_node(dev, |
|---|
| 297 | | - da9211_matches[i].of_node, |
|---|
| 298 | | - "enable", |
|---|
| 299 | | - 0, |
|---|
| 300 | | - GPIOD_OUT_HIGH, |
|---|
| 301 | | - "da9211-enable"); |
|---|
| 318 | + pdata->gpiod_ren[n] = devm_fwnode_gpiod_get(dev, |
|---|
| 319 | + of_fwnode_handle(pdata->reg_node[n]), |
|---|
| 320 | + "enable", |
|---|
| 321 | + GPIOD_OUT_HIGH | |
|---|
| 322 | + GPIOD_FLAGS_BIT_NONEXCLUSIVE, |
|---|
| 323 | + "da9211-enable"); |
|---|
| 324 | + if (IS_ERR(pdata->gpiod_ren[n])) |
|---|
| 325 | + pdata->gpiod_ren[n] = NULL; |
|---|
| 302 | 326 | n++; |
|---|
| 303 | 327 | } |
|---|
| 304 | 328 | |
|---|
| .. | .. |
|---|
| 389 | 413 | else |
|---|
| 390 | 414 | config.ena_gpiod = NULL; |
|---|
| 391 | 415 | |
|---|
| 416 | + /* |
|---|
| 417 | + * Hand the GPIO descriptor management over to the regulator |
|---|
| 418 | + * core, remove it from GPIO devres management. |
|---|
| 419 | + */ |
|---|
| 420 | + if (config.ena_gpiod) |
|---|
| 421 | + devm_gpiod_unhinge(chip->dev, config.ena_gpiod); |
|---|
| 392 | 422 | chip->rdev[i] = devm_regulator_register(chip->dev, |
|---|
| 393 | 423 | &da9211_regulators[i], &config); |
|---|
| 394 | 424 | if (IS_ERR(chip->rdev[i])) { |
|---|
| .. | .. |
|---|
| 414 | 444 | /* |
|---|
| 415 | 445 | * I2C driver interface functions |
|---|
| 416 | 446 | */ |
|---|
| 417 | | -static int da9211_i2c_probe(struct i2c_client *i2c, |
|---|
| 418 | | - const struct i2c_device_id *id) |
|---|
| 447 | +static int da9211_i2c_probe(struct i2c_client *i2c) |
|---|
| 419 | 448 | { |
|---|
| 420 | 449 | struct da9211 *chip; |
|---|
| 421 | 450 | int error, ret; |
|---|
| .. | .. |
|---|
| 524 | 553 | .name = "da9211", |
|---|
| 525 | 554 | .of_match_table = of_match_ptr(da9211_dt_ids), |
|---|
| 526 | 555 | }, |
|---|
| 527 | | - .probe = da9211_i2c_probe, |
|---|
| 556 | + .probe_new = da9211_i2c_probe, |
|---|
| 528 | 557 | .id_table = da9211_i2c_id, |
|---|
| 529 | 558 | }; |
|---|
| 530 | 559 | |
|---|