Mauro Carvalho Chehab | b660bf6 | 2020-08-17 09:10:45 +0200 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
Mauro Carvalho Chehab | fac4da4 | 2021-01-21 08:18:06 +0100 | [diff] [blame] | 2 | // |
| 3 | // Device driver for regulators in Hisi IC |
| 4 | // |
| 5 | // Copyright (c) 2013 Linaro Ltd. |
Hao Fang | 8d6ee30 | 2021-05-22 18:25:51 +0800 | [diff] [blame] | 6 | // Copyright (c) 2011 HiSilicon Ltd. |
Mauro Carvalho Chehab | e8608f8 | 2021-07-02 09:37:17 +0200 | [diff] [blame] | 7 | // Copyright (c) 2020-2021 Huawei Technologies Co., Ltd. |
Mauro Carvalho Chehab | fac4da4 | 2021-01-21 08:18:06 +0100 | [diff] [blame] | 8 | // |
| 9 | // Guodong Xu <guodong.xu@linaro.org> |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 10 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 11 | #include <linux/delay.h> |
Mauro Carvalho Chehab | 2c4fb70 | 2020-08-17 09:10:59 +0200 | [diff] [blame] | 12 | #include <linux/mfd/hi6421-spmi-pmic.h> |
| 13 | #include <linux/module.h> |
Mauro Carvalho Chehab | 2c4fb70 | 2020-08-17 09:10:59 +0200 | [diff] [blame] | 14 | #include <linux/platform_device.h> |
Mauro Carvalho Chehab | fb02e3e | 2021-01-29 20:51:47 +0100 | [diff] [blame] | 15 | #include <linux/regmap.h> |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 16 | #include <linux/regulator/driver.h> |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 17 | #include <linux/spmi.h> |
| 18 | |
Axel Lin | 9bc146a | 2021-06-22 12:33:29 +0800 | [diff] [blame] | 19 | struct hi6421_spmi_reg_priv { |
Mauro Carvalho Chehab | 6436a125 | 2021-01-21 08:18:09 +0100 | [diff] [blame] | 20 | /* Serialize regulator enable logic */ |
| 21 | struct mutex enable_mutex; |
| 22 | }; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 23 | |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 24 | struct hi6421_spmi_reg_info { |
| 25 | struct regulator_desc desc; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 26 | u8 eco_mode_mask; |
| 27 | u32 eco_uA; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 28 | }; |
| 29 | |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 30 | static const unsigned int range_1v5_to_2v0[] = { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 31 | 1500000, 1550000, 1600000, 1650000, |
| 32 | 1700000, 1725000, 1750000, 1775000, |
| 33 | 1800000, 1825000, 1850000, 1875000, |
| 34 | 1900000, 1925000, 1950000, 2000000 |
| 35 | }; |
| 36 | |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 37 | static const unsigned int range_1v725_to_1v9[] = { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 38 | 1725000, 1750000, 1775000, 1800000, |
| 39 | 1825000, 1850000, 1875000, 1900000 |
| 40 | }; |
| 41 | |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 42 | static const unsigned int range_1v75_to_3v3[] = { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 43 | 1750000, 1800000, 1825000, 2800000, |
| 44 | 2850000, 2950000, 3000000, 3300000 |
| 45 | }; |
| 46 | |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 47 | static const unsigned int range_1v8_to_3v0[] = { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 48 | 1800000, 1850000, 2400000, 2600000, |
| 49 | 2700000, 2850000, 2950000, 3000000 |
| 50 | }; |
| 51 | |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 52 | static const unsigned int range_2v5_to_3v3[] = { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 53 | 2500000, 2600000, 2700000, 2800000, |
| 54 | 3000000, 3100000, 3200000, 3300000 |
| 55 | }; |
| 56 | |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 57 | static const unsigned int range_2v6_to_3v3[] = { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 58 | 2600000, 2700000, 2800000, 2900000, |
| 59 | 3000000, 3100000, 3200000, 3300000 |
| 60 | }; |
| 61 | |
Mauro Carvalho Chehab | 54f1155 | 2021-01-21 08:18:13 +0100 | [diff] [blame] | 62 | /** |
| 63 | * HI6421V600_LDO() - specify a LDO power line |
| 64 | * @_id: LDO id name string |
| 65 | * @vtable: voltage table |
| 66 | * @ereg: enable register |
| 67 | * @emask: enable mask |
| 68 | * @vreg: voltage select register |
| 69 | * @odelay: off/on delay time in uS |
| 70 | * @etime: enable time in uS |
| 71 | * @ecomask: eco mode mask |
| 72 | * @ecoamp: eco mode load uppler limit in uA |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 73 | */ |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 74 | #define HI6421V600_LDO(_id, vtable, ereg, emask, vreg, \ |
| 75 | odelay, etime, ecomask, ecoamp) \ |
Mauro Carvalho Chehab | ccb2a74 | 2021-07-24 12:22:41 +0200 | [diff] [blame] | 76 | [hi6421v600_##_id] = { \ |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 77 | .desc = { \ |
| 78 | .name = #_id, \ |
| 79 | .of_match = of_match_ptr(#_id), \ |
| 80 | .regulators_node = of_match_ptr("regulators"), \ |
| 81 | .ops = &hi6421_spmi_ldo_rops, \ |
| 82 | .type = REGULATOR_VOLTAGE, \ |
Mauro Carvalho Chehab | ccb2a74 | 2021-07-24 12:22:41 +0200 | [diff] [blame] | 83 | .id = hi6421v600_##_id, \ |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 84 | .owner = THIS_MODULE, \ |
| 85 | .volt_table = vtable, \ |
| 86 | .n_voltages = ARRAY_SIZE(vtable), \ |
Axel Lin | 50bec7f | 2021-05-29 09:32:36 +0800 | [diff] [blame] | 87 | .vsel_mask = ARRAY_SIZE(vtable) - 1, \ |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 88 | .vsel_reg = vreg, \ |
| 89 | .enable_reg = ereg, \ |
| 90 | .enable_mask = emask, \ |
| 91 | .enable_time = etime, \ |
| 92 | .ramp_delay = etime, \ |
| 93 | .off_on_delay = odelay, \ |
| 94 | }, \ |
| 95 | .eco_mode_mask = ecomask, \ |
| 96 | .eco_uA = ecoamp, \ |
| 97 | } |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 98 | |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 99 | static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 100 | { |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 101 | struct hi6421_spmi_reg_priv *priv = rdev_get_drvdata(rdev); |
Mauro Carvalho Chehab | 6a5e7aa | 2021-01-21 08:18:10 +0100 | [diff] [blame] | 102 | int ret; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 103 | |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 104 | /* cannot enable more than one regulator at one time */ |
Axel Lin | 9bc146a | 2021-06-22 12:33:29 +0800 | [diff] [blame] | 105 | mutex_lock(&priv->enable_mutex); |
Mauro Carvalho Chehab | 12ca3b2 | 2020-08-17 09:10:44 +0200 | [diff] [blame] | 106 | |
Axel Lin | 4446e6f | 2021-04-30 16:55:55 +0800 | [diff] [blame] | 107 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
Mauro Carvalho Chehab | fb02e3e | 2021-01-29 20:51:47 +0100 | [diff] [blame] | 108 | rdev->desc->enable_mask, |
Atul Gopinathan | 643fd47 | 2021-02-09 13:49:34 +0530 | [diff] [blame] | 109 | rdev->desc->enable_mask); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 110 | |
Mauro Carvalho Chehab | fd765da | 2021-01-21 08:18:12 +0100 | [diff] [blame] | 111 | /* Avoid powering up multiple devices at the same time */ |
| 112 | usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60); |
| 113 | |
Axel Lin | 9bc146a | 2021-06-22 12:33:29 +0800 | [diff] [blame] | 114 | mutex_unlock(&priv->enable_mutex); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 115 | |
Mauro Carvalho Chehab | 6a5e7aa | 2021-01-21 08:18:10 +0100 | [diff] [blame] | 116 | return ret; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 117 | } |
| 118 | |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 119 | static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 120 | { |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 121 | struct hi6421_spmi_reg_info *sreg; |
Axel Lin | 57c045b | 2021-06-19 20:34:23 +0800 | [diff] [blame] | 122 | unsigned int reg_val; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 123 | |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 124 | sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); |
Axel Lin | 4446e6f | 2021-04-30 16:55:55 +0800 | [diff] [blame] | 125 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 126 | |
Mauro Carvalho Chehab | 32f53804 | 2020-08-17 09:10:47 +0200 | [diff] [blame] | 127 | if (reg_val & sreg->eco_mode_mask) |
Mauro Carvalho Chehab | 0b5a562 | 2021-01-21 08:18:08 +0100 | [diff] [blame] | 128 | return REGULATOR_MODE_IDLE; |
Mauro Carvalho Chehab | 9a18329 | 2020-08-17 09:10:48 +0200 | [diff] [blame] | 129 | |
Mauro Carvalho Chehab | 0b5a562 | 2021-01-21 08:18:08 +0100 | [diff] [blame] | 130 | return REGULATOR_MODE_NORMAL; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 131 | } |
| 132 | |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 133 | static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, |
Mauro Carvalho Chehab | 1275f3c | 2020-08-17 09:10:57 +0200 | [diff] [blame] | 134 | unsigned int mode) |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 135 | { |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 136 | struct hi6421_spmi_reg_info *sreg; |
Axel Lin | 57c045b | 2021-06-19 20:34:23 +0800 | [diff] [blame] | 137 | unsigned int val; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 138 | |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 139 | sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 140 | switch (mode) { |
| 141 | case REGULATOR_MODE_NORMAL: |
Mauro Carvalho Chehab | db27f82 | 2020-08-17 09:10:49 +0200 | [diff] [blame] | 142 | val = 0; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 143 | break; |
| 144 | case REGULATOR_MODE_IDLE: |
Axel Lin | 57c045b | 2021-06-19 20:34:23 +0800 | [diff] [blame] | 145 | if (!sreg->eco_mode_mask) |
| 146 | return -EINVAL; |
| 147 | |
| 148 | val = sreg->eco_mode_mask; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 149 | break; |
| 150 | default: |
| 151 | return -EINVAL; |
| 152 | } |
| 153 | |
Axel Lin | 4446e6f | 2021-04-30 16:55:55 +0800 | [diff] [blame] | 154 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
Mauro Carvalho Chehab | fb02e3e | 2021-01-29 20:51:47 +0100 | [diff] [blame] | 155 | sreg->eco_mode_mask, val); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 156 | } |
| 157 | |
Mauro Carvalho Chehab | 1275f3c | 2020-08-17 09:10:57 +0200 | [diff] [blame] | 158 | static unsigned int |
| 159 | hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, |
| 160 | int input_uV, int output_uV, |
| 161 | int load_uA) |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 162 | { |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 163 | struct hi6421_spmi_reg_info *sreg; |
| 164 | |
| 165 | sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 166 | |
Mauro Carvalho Chehab | 75d39eb | 2021-01-21 08:18:14 +0100 | [diff] [blame] | 167 | if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA)) |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 168 | return REGULATOR_MODE_NORMAL; |
Mauro Carvalho Chehab | 2c4fb70 | 2020-08-17 09:10:59 +0200 | [diff] [blame] | 169 | |
| 170 | return REGULATOR_MODE_IDLE; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 171 | } |
| 172 | |
Mauro Carvalho Chehab | 2c4fb70 | 2020-08-17 09:10:59 +0200 | [diff] [blame] | 173 | static const struct regulator_ops hi6421_spmi_ldo_rops = { |
Mauro Carvalho Chehab | 2ba53d0 | 2021-01-29 20:51:48 +0100 | [diff] [blame] | 174 | .is_enabled = regulator_is_enabled_regmap, |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 175 | .enable = hi6421_spmi_regulator_enable, |
Axel Lin | 4446e6f | 2021-04-30 16:55:55 +0800 | [diff] [blame] | 176 | .disable = regulator_disable_regmap, |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 177 | .list_voltage = regulator_list_voltage_table, |
Axel Lin | 00430f7 | 2021-06-10 21:41:28 +0800 | [diff] [blame] | 178 | .map_voltage = regulator_map_voltage_ascend, |
Mauro Carvalho Chehab | 2ba53d0 | 2021-01-29 20:51:48 +0100 | [diff] [blame] | 179 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 180 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 181 | .get_mode = hi6421_spmi_regulator_get_mode, |
| 182 | .set_mode = hi6421_spmi_regulator_set_mode, |
| 183 | .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode, |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 184 | }; |
| 185 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 186 | /* HI6421v600 regulators with known registers */ |
| 187 | enum hi6421_spmi_regulator_id { |
Mauro Carvalho Chehab | ccb2a74 | 2021-07-24 12:22:41 +0200 | [diff] [blame] | 188 | hi6421v600_ldo3, |
| 189 | hi6421v600_ldo4, |
| 190 | hi6421v600_ldo9, |
| 191 | hi6421v600_ldo15, |
| 192 | hi6421v600_ldo16, |
| 193 | hi6421v600_ldo17, |
| 194 | hi6421v600_ldo33, |
| 195 | hi6421v600_ldo34, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 196 | }; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 197 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 198 | static struct hi6421_spmi_reg_info regulator_info[] = { |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 199 | HI6421V600_LDO(ldo3, range_1v5_to_2v0, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 200 | 0x16, 0x01, 0x51, |
| 201 | 20000, 120, |
| 202 | 0, 0), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 203 | HI6421V600_LDO(ldo4, range_1v725_to_1v9, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 204 | 0x17, 0x01, 0x52, |
| 205 | 20000, 120, |
| 206 | 0x10, 10000), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 207 | HI6421V600_LDO(ldo9, range_1v75_to_3v3, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 208 | 0x1c, 0x01, 0x57, |
| 209 | 20000, 360, |
| 210 | 0x10, 10000), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 211 | HI6421V600_LDO(ldo15, range_1v8_to_3v0, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 212 | 0x21, 0x01, 0x5c, |
| 213 | 20000, 360, |
| 214 | 0x10, 10000), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 215 | HI6421V600_LDO(ldo16, range_1v8_to_3v0, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 216 | 0x22, 0x01, 0x5d, |
| 217 | 20000, 360, |
| 218 | 0x10, 10000), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 219 | HI6421V600_LDO(ldo17, range_2v5_to_3v3, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 220 | 0x23, 0x01, 0x5e, |
| 221 | 20000, 120, |
| 222 | 0x10, 10000), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 223 | HI6421V600_LDO(ldo33, range_2v5_to_3v3, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 224 | 0x32, 0x01, 0x6d, |
| 225 | 20000, 120, |
| 226 | 0, 0), |
Mauro Carvalho Chehab | 5e36129 | 2021-07-24 12:22:42 +0200 | [diff] [blame] | 227 | HI6421V600_LDO(ldo34, range_2v6_to_3v3, |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 228 | 0x33, 0x01, 0x6e, |
| 229 | 20000, 120, |
| 230 | 0, 0), |
| 231 | }; |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 232 | |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 233 | static int hi6421_spmi_regulator_probe(struct platform_device *pdev) |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 234 | { |
| 235 | struct device *pmic_dev = pdev->dev.parent; |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 236 | struct regulator_config config = { }; |
Axel Lin | 9bc146a | 2021-06-22 12:33:29 +0800 | [diff] [blame] | 237 | struct hi6421_spmi_reg_priv *priv; |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 238 | struct hi6421_spmi_reg_info *info; |
| 239 | struct device *dev = &pdev->dev; |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 240 | struct hi6421_spmi_pmic *pmic; |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 241 | struct regulator_dev *rdev; |
| 242 | int i; |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 243 | |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 244 | /* |
| 245 | * This driver is meant to be called by hi6421-spmi-core, |
| 246 | * which should first set drvdata. If this doesn't happen, hit |
| 247 | * a warn on and return. |
| 248 | */ |
| 249 | pmic = dev_get_drvdata(pmic_dev); |
| 250 | if (WARN_ON(!pmic)) |
| 251 | return -ENODEV; |
| 252 | |
Axel Lin | 9bc146a | 2021-06-22 12:33:29 +0800 | [diff] [blame] | 253 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
| 254 | if (!priv) |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 255 | return -ENOMEM; |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 256 | |
Axel Lin | 9bc146a | 2021-06-22 12:33:29 +0800 | [diff] [blame] | 257 | mutex_init(&priv->enable_mutex); |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 258 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 259 | for (i = 0; i < ARRAY_SIZE(regulator_info); i++) { |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 260 | info = ®ulator_info[i]; |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 261 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 262 | config.dev = pdev->dev.parent; |
Axel Lin | 5db5dd5 | 2021-06-30 15:42:46 +0800 | [diff] [blame] | 263 | config.driver_data = priv; |
Mauro Carvalho Chehab | fcd7324 | 2021-01-29 20:51:49 +0100 | [diff] [blame] | 264 | config.regmap = pmic->regmap; |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 265 | |
| 266 | rdev = devm_regulator_register(dev, &info->desc, &config); |
| 267 | if (IS_ERR(rdev)) { |
| 268 | dev_err(dev, "failed to register %s\n", |
| 269 | info->desc.name); |
| 270 | return PTR_ERR(rdev); |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 271 | } |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 272 | } |
| 273 | |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 274 | return 0; |
| 275 | } |
| 276 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 277 | static const struct platform_device_id hi6421_spmi_regulator_table[] = { |
Mauro Carvalho Chehab | 75937f8 | 2020-08-17 09:10:46 +0200 | [diff] [blame] | 278 | { .name = "hi6421v600-regulator" }, |
| 279 | {}, |
| 280 | }; |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 281 | MODULE_DEVICE_TABLE(platform, hi6421_spmi_regulator_table); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 282 | |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 283 | static struct platform_driver hi6421_spmi_regulator_driver = { |
| 284 | .id_table = hi6421_spmi_regulator_table, |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 285 | .driver = { |
Mauro Carvalho Chehab | 6a5e7aa | 2021-01-21 08:18:10 +0100 | [diff] [blame] | 286 | .name = "hi6421v600-regulator", |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 287 | }, |
Mauro Carvalho Chehab | c22aeb9 | 2020-08-17 09:10:51 +0200 | [diff] [blame] | 288 | .probe = hi6421_spmi_regulator_probe, |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 289 | }; |
Mauro Carvalho Chehab | d2dfd50a | 2021-01-21 08:18:07 +0100 | [diff] [blame] | 290 | module_platform_driver(hi6421_spmi_regulator_driver); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 291 | |
Mauro Carvalho Chehab | 6a5e7aa | 2021-01-21 08:18:10 +0100 | [diff] [blame] | 292 | MODULE_DESCRIPTION("Hi6421v600 SPMI regulator driver"); |
Mayulong | 42f24d9 | 2020-08-17 09:10:42 +0200 | [diff] [blame] | 293 | MODULE_LICENSE("GPL v2"); |
| 294 | |