| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Regulator driver for LP87565 PMIC |
|---|
| 3 | 4 | * |
|---|
| 4 | | - * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 8 | | - * Free Software Foundation version 2. |
|---|
| 5 | + * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ |
|---|
| 9 | 6 | */ |
|---|
| 10 | 7 | |
|---|
| 11 | 8 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 14 | 11 | |
|---|
| 15 | 12 | #include <linux/mfd/lp87565.h> |
|---|
| 16 | 13 | |
|---|
| 17 | | -#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, _er, _em, \ |
|---|
| 18 | | - _delay, _lr, _cr) \ |
|---|
| 14 | +#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, \ |
|---|
| 15 | + _er, _em, _ev, _delay, _lr, _cr) \ |
|---|
| 19 | 16 | [_id] = { \ |
|---|
| 20 | 17 | .desc = { \ |
|---|
| 21 | 18 | .name = _name, \ |
|---|
| .. | .. |
|---|
| 31 | 28 | .vsel_mask = _vm, \ |
|---|
| 32 | 29 | .enable_reg = _er, \ |
|---|
| 33 | 30 | .enable_mask = _em, \ |
|---|
| 31 | + .enable_val = _ev, \ |
|---|
| 34 | 32 | .ramp_delay = _delay, \ |
|---|
| 35 | 33 | .linear_ranges = _lr, \ |
|---|
| 36 | 34 | .n_linear_ranges = ARRAY_SIZE(_lr), \ |
|---|
| 35 | + .curr_table = lp87565_buck_uA, \ |
|---|
| 36 | + .n_current_limits = ARRAY_SIZE(lp87565_buck_uA),\ |
|---|
| 37 | + .csel_reg = (_cr), \ |
|---|
| 38 | + .csel_mask = LP87565_BUCK_CTRL_2_ILIM, \ |
|---|
| 37 | 39 | }, \ |
|---|
| 38 | 40 | .ctrl2_reg = _cr, \ |
|---|
| 39 | 41 | } |
|---|
| .. | .. |
|---|
| 45 | 47 | |
|---|
| 46 | 48 | static const struct lp87565_regulator regulators[]; |
|---|
| 47 | 49 | |
|---|
| 48 | | -static const struct regulator_linear_range buck0_1_2_3_ranges[] = { |
|---|
| 50 | +static const struct linear_range buck0_1_2_3_ranges[] = { |
|---|
| 49 | 51 | REGULATOR_LINEAR_RANGE(600000, 0xA, 0x17, 10000), |
|---|
| 50 | 52 | REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000), |
|---|
| 51 | 53 | REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), |
|---|
| 52 | 54 | }; |
|---|
| 53 | 55 | |
|---|
| 54 | | -static unsigned int lp87565_buck_ramp_delay[] = { |
|---|
| 56 | +static const unsigned int lp87565_buck_ramp_delay[] = { |
|---|
| 55 | 57 | 30000, 15000, 10000, 7500, 3800, 1900, 940, 470 |
|---|
| 56 | 58 | }; |
|---|
| 57 | 59 | |
|---|
| .. | .. |
|---|
| 64 | 66 | int ramp_delay) |
|---|
| 65 | 67 | { |
|---|
| 66 | 68 | int id = rdev_get_id(rdev); |
|---|
| 67 | | - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); |
|---|
| 68 | 69 | unsigned int reg; |
|---|
| 69 | 70 | int ret; |
|---|
| 70 | 71 | |
|---|
| .. | .. |
|---|
| 85 | 86 | else |
|---|
| 86 | 87 | reg = 0; |
|---|
| 87 | 88 | |
|---|
| 88 | | - ret = regmap_update_bits(lp87565->regmap, regulators[id].ctrl2_reg, |
|---|
| 89 | + ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg, |
|---|
| 89 | 90 | LP87565_BUCK_CTRL_2_SLEW_RATE, |
|---|
| 90 | 91 | reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE)); |
|---|
| 91 | 92 | if (ret) { |
|---|
| 92 | | - dev_err(lp87565->dev, "SLEW RATE write failed: %d\n", ret); |
|---|
| 93 | + dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret); |
|---|
| 93 | 94 | return ret; |
|---|
| 94 | 95 | } |
|---|
| 95 | 96 | |
|---|
| .. | .. |
|---|
| 102 | 103 | return 0; |
|---|
| 103 | 104 | } |
|---|
| 104 | 105 | |
|---|
| 105 | | -static int lp87565_buck_set_current_limit(struct regulator_dev *rdev, |
|---|
| 106 | | - int min_uA, int max_uA) |
|---|
| 107 | | -{ |
|---|
| 108 | | - int id = rdev_get_id(rdev); |
|---|
| 109 | | - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); |
|---|
| 110 | | - int i; |
|---|
| 111 | | - |
|---|
| 112 | | - for (i = ARRAY_SIZE(lp87565_buck_uA) - 1; i >= 0; i--) { |
|---|
| 113 | | - if (lp87565_buck_uA[i] >= min_uA && |
|---|
| 114 | | - lp87565_buck_uA[i] <= max_uA) |
|---|
| 115 | | - return regmap_update_bits(lp87565->regmap, |
|---|
| 116 | | - regulators[id].ctrl2_reg, |
|---|
| 117 | | - LP87565_BUCK_CTRL_2_ILIM, |
|---|
| 118 | | - i << __ffs(LP87565_BUCK_CTRL_2_ILIM)); |
|---|
| 119 | | - } |
|---|
| 120 | | - |
|---|
| 121 | | - return -EINVAL; |
|---|
| 122 | | -} |
|---|
| 123 | | - |
|---|
| 124 | | -static int lp87565_buck_get_current_limit(struct regulator_dev *rdev) |
|---|
| 125 | | -{ |
|---|
| 126 | | - int id = rdev_get_id(rdev); |
|---|
| 127 | | - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); |
|---|
| 128 | | - int ret; |
|---|
| 129 | | - unsigned int val; |
|---|
| 130 | | - |
|---|
| 131 | | - ret = regmap_read(lp87565->regmap, regulators[id].ctrl2_reg, &val); |
|---|
| 132 | | - if (ret) |
|---|
| 133 | | - return ret; |
|---|
| 134 | | - |
|---|
| 135 | | - val = (val & LP87565_BUCK_CTRL_2_ILIM) >> |
|---|
| 136 | | - __ffs(LP87565_BUCK_CTRL_2_ILIM); |
|---|
| 137 | | - |
|---|
| 138 | | - return (val < ARRAY_SIZE(lp87565_buck_uA)) ? |
|---|
| 139 | | - lp87565_buck_uA[val] : -EINVAL; |
|---|
| 140 | | -} |
|---|
| 141 | | - |
|---|
| 142 | | -/* Operations permitted on BUCK0, BUCK1 */ |
|---|
| 143 | | -static struct regulator_ops lp87565_buck_ops = { |
|---|
| 106 | +/* Operations permitted on BUCKs */ |
|---|
| 107 | +static const struct regulator_ops lp87565_buck_ops = { |
|---|
| 144 | 108 | .is_enabled = regulator_is_enabled_regmap, |
|---|
| 145 | 109 | .enable = regulator_enable_regmap, |
|---|
| 146 | 110 | .disable = regulator_disable_regmap, |
|---|
| .. | .. |
|---|
| 150 | 114 | .map_voltage = regulator_map_voltage_linear_range, |
|---|
| 151 | 115 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
|---|
| 152 | 116 | .set_ramp_delay = lp87565_buck_set_ramp_delay, |
|---|
| 153 | | - .set_current_limit = lp87565_buck_set_current_limit, |
|---|
| 154 | | - .get_current_limit = lp87565_buck_get_current_limit, |
|---|
| 117 | + .set_current_limit = regulator_set_current_limit_regmap, |
|---|
| 118 | + .get_current_limit = regulator_get_current_limit_regmap, |
|---|
| 155 | 119 | }; |
|---|
| 156 | 120 | |
|---|
| 157 | 121 | static const struct lp87565_regulator regulators[] = { |
|---|
| 158 | 122 | LP87565_REGULATOR("BUCK0", LP87565_BUCK_0, "buck0", lp87565_buck_ops, |
|---|
| 159 | 123 | 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, |
|---|
| 160 | 124 | LP87565_REG_BUCK0_CTRL_1, |
|---|
| 125 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 126 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
|---|
| 161 | 127 | LP87565_BUCK_CTRL_1_EN, 3230, |
|---|
| 162 | 128 | buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), |
|---|
| 163 | 129 | LP87565_REGULATOR("BUCK1", LP87565_BUCK_1, "buck1", lp87565_buck_ops, |
|---|
| 164 | 130 | 256, LP87565_REG_BUCK1_VOUT, LP87565_BUCK_VSET, |
|---|
| 165 | 131 | LP87565_REG_BUCK1_CTRL_1, |
|---|
| 132 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 133 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
|---|
| 166 | 134 | LP87565_BUCK_CTRL_1_EN, 3230, |
|---|
| 167 | 135 | buck0_1_2_3_ranges, LP87565_REG_BUCK1_CTRL_2), |
|---|
| 168 | 136 | LP87565_REGULATOR("BUCK2", LP87565_BUCK_2, "buck2", lp87565_buck_ops, |
|---|
| 169 | 137 | 256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET, |
|---|
| 170 | 138 | LP87565_REG_BUCK2_CTRL_1, |
|---|
| 139 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 140 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
|---|
| 171 | 141 | LP87565_BUCK_CTRL_1_EN, 3230, |
|---|
| 172 | 142 | buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2), |
|---|
| 173 | 143 | LP87565_REGULATOR("BUCK3", LP87565_BUCK_3, "buck3", lp87565_buck_ops, |
|---|
| 174 | 144 | 256, LP87565_REG_BUCK3_VOUT, LP87565_BUCK_VSET, |
|---|
| 175 | 145 | LP87565_REG_BUCK3_CTRL_1, |
|---|
| 146 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 147 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
|---|
| 176 | 148 | LP87565_BUCK_CTRL_1_EN, 3230, |
|---|
| 177 | 149 | buck0_1_2_3_ranges, LP87565_REG_BUCK3_CTRL_2), |
|---|
| 178 | 150 | LP87565_REGULATOR("BUCK10", LP87565_BUCK_10, "buck10", lp87565_buck_ops, |
|---|
| 179 | 151 | 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, |
|---|
| 180 | 152 | LP87565_REG_BUCK0_CTRL_1, |
|---|
| 181 | 153 | LP87565_BUCK_CTRL_1_EN | |
|---|
| 154 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL | |
|---|
| 155 | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, |
|---|
| 156 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 182 | 157 | LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230, |
|---|
| 183 | 158 | buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), |
|---|
| 184 | 159 | LP87565_REGULATOR("BUCK23", LP87565_BUCK_23, "buck23", lp87565_buck_ops, |
|---|
| 185 | 160 | 256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET, |
|---|
| 186 | 161 | LP87565_REG_BUCK2_CTRL_1, |
|---|
| 162 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 163 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
|---|
| 187 | 164 | LP87565_BUCK_CTRL_1_EN, 3230, |
|---|
| 188 | 165 | buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2), |
|---|
| 166 | + LP87565_REGULATOR("BUCK3210", LP87565_BUCK_3210, "buck3210", |
|---|
| 167 | + lp87565_buck_ops, 256, LP87565_REG_BUCK0_VOUT, |
|---|
| 168 | + LP87565_BUCK_VSET, LP87565_REG_BUCK0_CTRL_1, |
|---|
| 169 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 170 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL | |
|---|
| 171 | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, |
|---|
| 172 | + LP87565_BUCK_CTRL_1_EN | |
|---|
| 173 | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230, |
|---|
| 174 | + buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), |
|---|
| 189 | 175 | }; |
|---|
| 190 | 176 | |
|---|
| 191 | 177 | static int lp87565_regulator_probe(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 193 | 179 | struct lp87565 *lp87565 = dev_get_drvdata(pdev->dev.parent); |
|---|
| 194 | 180 | struct regulator_config config = { }; |
|---|
| 195 | 181 | struct regulator_dev *rdev; |
|---|
| 196 | | - int i, min_idx = LP87565_BUCK_0, max_idx = LP87565_BUCK_3; |
|---|
| 182 | + int i, min_idx, max_idx; |
|---|
| 197 | 183 | |
|---|
| 198 | 184 | platform_set_drvdata(pdev, lp87565); |
|---|
| 199 | 185 | |
|---|
| .. | .. |
|---|
| 202 | 188 | config.driver_data = lp87565; |
|---|
| 203 | 189 | config.regmap = lp87565->regmap; |
|---|
| 204 | 190 | |
|---|
| 205 | | - if (lp87565->dev_type == LP87565_DEVICE_TYPE_LP87565_Q1) { |
|---|
| 191 | + switch (lp87565->dev_type) { |
|---|
| 192 | + case LP87565_DEVICE_TYPE_LP87565_Q1: |
|---|
| 206 | 193 | min_idx = LP87565_BUCK_10; |
|---|
| 207 | 194 | max_idx = LP87565_BUCK_23; |
|---|
| 195 | + break; |
|---|
| 196 | + case LP87565_DEVICE_TYPE_LP87561_Q1: |
|---|
| 197 | + min_idx = LP87565_BUCK_3210; |
|---|
| 198 | + max_idx = LP87565_BUCK_3210; |
|---|
| 199 | + break; |
|---|
| 200 | + default: |
|---|
| 201 | + min_idx = LP87565_BUCK_0; |
|---|
| 202 | + max_idx = LP87565_BUCK_3; |
|---|
| 203 | + break; |
|---|
| 208 | 204 | } |
|---|
| 209 | 205 | |
|---|
| 210 | 206 | for (i = min_idx; i <= max_idx; i++) { |
|---|