|
1 | 1 | // SPDX-License-Identifier: GPL-2.0
|
2 | 2 | //
|
3 |
| -// MP8869 regulator driver |
| 3 | +// MP8867/MP8869 regulator driver |
4 | 4 | //
|
5 | 5 | // Copyright (C) 2020 Synaptics Incorporated
|
6 | 6 | //
|
@@ -119,6 +119,62 @@ static const struct regulator_ops mp8869_regulator_ops = {
|
119 | 119 | .get_mode = mp886x_get_mode,
|
120 | 120 | };
|
121 | 121 |
|
| 122 | +static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) |
| 123 | +{ |
| 124 | + struct mp886x_device_info *di = rdev_get_drvdata(rdev); |
| 125 | + int ret, delta; |
| 126 | + |
| 127 | + ret = mp8869_set_voltage_sel(rdev, sel); |
| 128 | + if (ret < 0) |
| 129 | + return ret; |
| 130 | + |
| 131 | + delta = di->sel - sel; |
| 132 | + if (abs(delta) <= 5) |
| 133 | + ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, |
| 134 | + MP886X_GO, 0); |
| 135 | + di->sel = sel; |
| 136 | + |
| 137 | + return ret; |
| 138 | +} |
| 139 | + |
| 140 | +static int mp8867_get_voltage_sel(struct regulator_dev *rdev) |
| 141 | +{ |
| 142 | + struct mp886x_device_info *di = rdev_get_drvdata(rdev); |
| 143 | + int ret, uv; |
| 144 | + unsigned int val; |
| 145 | + bool fbloop; |
| 146 | + |
| 147 | + ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); |
| 148 | + if (ret) |
| 149 | + return ret; |
| 150 | + |
| 151 | + fbloop = val & MP886X_V_BOOT; |
| 152 | + |
| 153 | + val &= rdev->desc->vsel_mask; |
| 154 | + val >>= ffs(rdev->desc->vsel_mask) - 1; |
| 155 | + |
| 156 | + if (fbloop) { |
| 157 | + uv = regulator_list_voltage_linear(rdev, val); |
| 158 | + uv = mp8869_scale(uv, di->r[0], di->r[1]); |
| 159 | + return regulator_map_voltage_linear(rdev, uv, uv); |
| 160 | + } |
| 161 | + |
| 162 | + return val; |
| 163 | +} |
| 164 | + |
| 165 | +static const struct regulator_ops mp8867_regulator_ops = { |
| 166 | + .set_voltage_sel = mp8867_set_voltage_sel, |
| 167 | + .get_voltage_sel = mp8867_get_voltage_sel, |
| 168 | + .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 169 | + .map_voltage = regulator_map_voltage_linear, |
| 170 | + .list_voltage = regulator_list_voltage_linear, |
| 171 | + .enable = regulator_enable_regmap, |
| 172 | + .disable = regulator_disable_regmap, |
| 173 | + .is_enabled = regulator_is_enabled_regmap, |
| 174 | + .set_mode = mp886x_set_mode, |
| 175 | + .get_mode = mp886x_get_mode, |
| 176 | +}; |
| 177 | + |
122 | 178 | static int mp886x_regulator_register(struct mp886x_device_info *di,
|
123 | 179 | struct regulator_config *config)
|
124 | 180 | {
|
@@ -201,6 +257,10 @@ static int mp886x_i2c_probe(struct i2c_client *client,
|
201 | 257 | }
|
202 | 258 |
|
203 | 259 | static const struct of_device_id mp886x_dt_ids[] = {
|
| 260 | + { |
| 261 | + .compatible = "mps,mp8867", |
| 262 | + .data = &mp8867_regulator_ops |
| 263 | + }, |
204 | 264 | {
|
205 | 265 | .compatible = "mps,mp8869",
|
206 | 266 | .data = &mp8869_regulator_ops
|
|
0 commit comments