rt4801-regulator.c (6056B)
1// SPDX-License-Identifier: GPL-2.0+ 2 3#include <linux/gpio/consumer.h> 4#include <linux/i2c.h> 5#include <linux/kernel.h> 6#include <linux/module.h> 7#include <linux/of.h> 8#include <linux/regmap.h> 9#include <linux/regulator/driver.h> 10 11#define RT4801_REG_VOP 0x00 12#define RT4801_REG_VON 0x01 13#define RT4801_REG_APPS 0x03 14 15#define VOUT_MASK 0x1F 16 17#define MIN_UV 4000000 18#define STEP_UV 100000 19#define MAX_UV 6000000 20#define N_VOLTAGES ((MAX_UV - MIN_UV) / STEP_UV + 1) 21 22#define DSV_OUT_POS 0 23#define DSV_OUT_NEG 1 24#define DSV_OUT_MAX 2 25 26#define DSVP_ENABLE BIT(0) 27#define DSVN_ENABLE BIT(1) 28#define DSVALL_ENABLE (DSVP_ENABLE | DSVN_ENABLE) 29 30struct rt4801_priv { 31 struct device *dev; 32 struct gpio_desc *enable_gpios[DSV_OUT_MAX]; 33 unsigned int enable_flag; 34 unsigned int volt_sel[DSV_OUT_MAX]; 35}; 36 37static int rt4801_of_parse_cb(struct device_node *np, 38 const struct regulator_desc *desc, 39 struct regulator_config *config) 40{ 41 struct rt4801_priv *priv = config->driver_data; 42 int id = desc->id; 43 44 if (priv->enable_gpios[id]) { 45 dev_warn(priv->dev, "duplicated enable-gpios property\n"); 46 return 0; 47 } 48 priv->enable_gpios[id] = devm_fwnode_gpiod_get_index(priv->dev, 49 of_fwnode_handle(np), 50 "enable", 0, 51 GPIOD_OUT_HIGH, 52 "rt4801"); 53 if (IS_ERR(priv->enable_gpios[id])) 54 priv->enable_gpios[id] = NULL; 55 56 return 0; 57} 58 59static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) 60{ 61 struct rt4801_priv *priv = rdev_get_drvdata(rdev); 62 int id = rdev_get_id(rdev), ret; 63 64 if (priv->enable_flag & BIT(id)) { 65 ret = regulator_set_voltage_sel_regmap(rdev, selector); 66 if (ret) 67 return ret; 68 } 69 70 priv->volt_sel[id] = selector; 71 return 0; 72} 73 74static int rt4801_get_voltage_sel(struct regulator_dev *rdev) 75{ 76 struct rt4801_priv *priv = rdev_get_drvdata(rdev); 77 int id = rdev_get_id(rdev); 78 79 if (priv->enable_flag & BIT(id)) 80 return regulator_get_voltage_sel_regmap(rdev); 81 82 return priv->volt_sel[id]; 83} 84 85static int rt4801_enable(struct regulator_dev *rdev) 86{ 87 struct rt4801_priv *priv = rdev_get_drvdata(rdev); 88 int id = rdev_get_id(rdev), ret; 89 90 if (!priv->enable_gpios[id]) { 91 dev_warn(&rdev->dev, "no dedicated gpio can control\n"); 92 goto bypass_gpio; 93 } 94 95 gpiod_set_value(priv->enable_gpios[id], 1); 96 97bypass_gpio: 98 ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, priv->volt_sel[id]); 99 if (ret) 100 return ret; 101 102 priv->enable_flag |= BIT(id); 103 return 0; 104} 105 106static int rt4801_disable(struct regulator_dev *rdev) 107{ 108 struct rt4801_priv *priv = rdev_get_drvdata(rdev); 109 int id = rdev_get_id(rdev); 110 111 if (!priv->enable_gpios[id]) { 112 dev_warn(&rdev->dev, "no dedicated gpio can control\n"); 113 goto bypass_gpio; 114 } 115 116 gpiod_set_value(priv->enable_gpios[id], 0); 117 118bypass_gpio: 119 priv->enable_flag &= ~BIT(id); 120 return 0; 121} 122 123static int rt4801_is_enabled(struct regulator_dev *rdev) 124{ 125 struct rt4801_priv *priv = rdev_get_drvdata(rdev); 126 int id = rdev_get_id(rdev); 127 128 return !!(priv->enable_flag & BIT(id)); 129} 130 131static const struct regulator_ops rt4801_regulator_ops = { 132 .list_voltage = regulator_list_voltage_linear, 133 .set_voltage_sel = rt4801_set_voltage_sel, 134 .get_voltage_sel = rt4801_get_voltage_sel, 135 .enable = rt4801_enable, 136 .disable = rt4801_disable, 137 .is_enabled = rt4801_is_enabled, 138}; 139 140static const struct regulator_desc rt4801_regulator_descs[] = { 141 { 142 .name = "DSVP", 143 .ops = &rt4801_regulator_ops, 144 .of_match = of_match_ptr("DSVP"), 145 .of_parse_cb = rt4801_of_parse_cb, 146 .type = REGULATOR_VOLTAGE, 147 .id = DSV_OUT_POS, 148 .min_uV = MIN_UV, 149 .uV_step = STEP_UV, 150 .n_voltages = N_VOLTAGES, 151 .owner = THIS_MODULE, 152 .vsel_reg = RT4801_REG_VOP, 153 .vsel_mask = VOUT_MASK, 154 }, 155 { 156 .name = "DSVN", 157 .ops = &rt4801_regulator_ops, 158 .of_match = of_match_ptr("DSVN"), 159 .of_parse_cb = rt4801_of_parse_cb, 160 .type = REGULATOR_VOLTAGE, 161 .id = DSV_OUT_NEG, 162 .min_uV = MIN_UV, 163 .uV_step = STEP_UV, 164 .n_voltages = N_VOLTAGES, 165 .owner = THIS_MODULE, 166 .vsel_reg = RT4801_REG_VON, 167 .vsel_mask = VOUT_MASK, 168 }, 169}; 170 171static const struct regmap_config rt4801_regmap_config = { 172 .reg_bits = 8, 173 .val_bits = 8, 174 .max_register = RT4801_REG_APPS, 175}; 176 177static int rt4801_probe(struct i2c_client *i2c) 178{ 179 struct rt4801_priv *priv; 180 struct regmap *regmap; 181 int i; 182 183 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); 184 if (!priv) 185 return -ENOMEM; 186 187 priv->dev = &i2c->dev; 188 /* bootloader will on, driver only reconfigure enable to all output high */ 189 priv->enable_flag = DSVALL_ENABLE; 190 191 regmap = devm_regmap_init_i2c(i2c, &rt4801_regmap_config); 192 if (IS_ERR(regmap)) { 193 dev_err(&i2c->dev, "Failed to init regmap\n"); 194 return PTR_ERR(regmap); 195 } 196 197 for (i = 0; i < DSV_OUT_MAX; i++) { 198 priv->enable_gpios[i] = devm_gpiod_get_index_optional(&i2c->dev, 199 "enable", 200 i, 201 GPIOD_OUT_HIGH); 202 if (IS_ERR(priv->enable_gpios[i])) { 203 dev_err(&i2c->dev, "Failed to get gpios\n"); 204 return PTR_ERR(priv->enable_gpios[i]); 205 } 206 } 207 208 for (i = 0; i < DSV_OUT_MAX; i++) { 209 const struct regulator_desc *desc = rt4801_regulator_descs + i; 210 struct regulator_config config = { .dev = &i2c->dev, .driver_data = priv, 211 .regmap = regmap, }; 212 struct regulator_dev *rdev; 213 unsigned int val; 214 int ret; 215 216 /* initialize volt_sel variable */ 217 ret = regmap_read(regmap, desc->vsel_reg, &val); 218 if (ret) 219 return ret; 220 221 priv->volt_sel[i] = val & desc->vsel_mask; 222 223 rdev = devm_regulator_register(&i2c->dev, desc, &config); 224 if (IS_ERR(rdev)) { 225 dev_err(&i2c->dev, "Failed to register [%d] regulator\n", i); 226 return PTR_ERR(rdev); 227 } 228 } 229 230 return 0; 231} 232 233static const struct of_device_id __maybe_unused rt4801_of_id[] = { 234 { .compatible = "richtek,rt4801", }, 235 { }, 236}; 237MODULE_DEVICE_TABLE(of, rt4801_of_id); 238 239static struct i2c_driver rt4801_driver = { 240 .driver = { 241 .name = "rt4801", 242 .of_match_table = of_match_ptr(rt4801_of_id), 243 }, 244 .probe_new = rt4801_probe, 245}; 246module_i2c_driver(rt4801_driver); 247 248MODULE_AUTHOR("ChiYuan Hwang <cy_huang@richtek.com>"); 249MODULE_DESCRIPTION("Richtek RT4801 Display Bias Driver"); 250MODULE_LICENSE("GPL v2");