max20086-regulator.c (8107B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2// 3// max20086-regulator.c - MAX20086-MAX20089 camera power protector driver 4// 5// Copyright (C) 2022 Laurent Pinchart <laurent.pinchart@idesonboard.com> 6// Copyright (C) 2018 Avnet, Inc. 7 8#include <linux/err.h> 9#include <linux/gpio.h> 10#include <linux/gpio/consumer.h> 11#include <linux/i2c.h> 12#include <linux/module.h> 13#include <linux/regmap.h> 14#include <linux/regulator/driver.h> 15#include <linux/regulator/machine.h> 16#include <linux/regulator/of_regulator.h> 17#include <linux/slab.h> 18 19/* Register Offset */ 20#define MAX20086_REG_MASK 0x00 21#define MAX20086_REG_CONFIG 0x01 22#define MAX20086_REG_ID 0x02 23#define MAX20086_REG_STAT1 0x03 24#define MAX20086_REG_STAT2_L 0x04 25#define MAX20086_REG_STAT2_H 0x05 26#define MAX20086_REG_ADC1 0x06 27#define MAX20086_REG_ADC2 0x07 28#define MAX20086_REG_ADC3 0x08 29#define MAX20086_REG_ADC4 0x09 30 31/* DEVICE IDs */ 32#define MAX20086_DEVICE_ID_MAX20086 0x40 33#define MAX20086_DEVICE_ID_MAX20087 0x20 34#define MAX20086_DEVICE_ID_MAX20088 0x10 35#define MAX20086_DEVICE_ID_MAX20089 0x00 36#define DEVICE_ID_MASK 0xf0 37 38/* Register bits */ 39#define MAX20086_EN_MASK 0x0f 40#define MAX20086_EN_OUT1 0x01 41#define MAX20086_EN_OUT2 0x02 42#define MAX20086_EN_OUT3 0x04 43#define MAX20086_EN_OUT4 0x08 44#define MAX20086_INT_DISABLE_ALL 0x3f 45 46#define MAX20086_MAX_REGULATORS 4 47 48struct max20086_chip_info { 49 u8 id; 50 unsigned int num_outputs; 51}; 52 53struct max20086_regulator { 54 struct device_node *of_node; 55 struct regulator_init_data *init_data; 56 const struct regulator_desc *desc; 57 struct regulator_dev *rdev; 58}; 59 60struct max20086 { 61 struct device *dev; 62 struct regmap *regmap; 63 struct gpio_desc *ena_gpiod; 64 65 const struct max20086_chip_info *info; 66 67 struct max20086_regulator regulators[MAX20086_MAX_REGULATORS]; 68}; 69 70static const struct regulator_ops max20086_buck_ops = { 71 .enable = regulator_enable_regmap, 72 .disable = regulator_disable_regmap, 73 .is_enabled = regulator_is_enabled_regmap, 74}; 75 76#define MAX20086_REGULATOR_DESC(n) \ 77{ \ 78 .name = "OUT"#n, \ 79 .supply_name = "in", \ 80 .id = (n) - 1, \ 81 .ops = &max20086_buck_ops, \ 82 .type = REGULATOR_VOLTAGE, \ 83 .owner = THIS_MODULE, \ 84 .enable_reg = MAX20086_REG_CONFIG, \ 85 .enable_mask = 1 << ((n) - 1), \ 86 .enable_val = 1 << ((n) - 1), \ 87 .disable_val = 0, \ 88} 89 90static const char * const max20086_output_names[] = { 91 "OUT1", 92 "OUT2", 93 "OUT3", 94 "OUT4", 95}; 96 97static const struct regulator_desc max20086_regulators[] = { 98 MAX20086_REGULATOR_DESC(1), 99 MAX20086_REGULATOR_DESC(2), 100 MAX20086_REGULATOR_DESC(3), 101 MAX20086_REGULATOR_DESC(4), 102}; 103 104static int max20086_regulators_register(struct max20086 *chip) 105{ 106 unsigned int i; 107 108 for (i = 0; i < chip->info->num_outputs; i++) { 109 struct max20086_regulator *reg = &chip->regulators[i]; 110 struct regulator_config config = { }; 111 struct regulator_dev *rdev; 112 113 config.dev = chip->dev; 114 config.init_data = reg->init_data; 115 config.driver_data = chip; 116 config.of_node = reg->of_node; 117 config.regmap = chip->regmap; 118 config.ena_gpiod = chip->ena_gpiod; 119 120 rdev = devm_regulator_register(chip->dev, reg->desc, &config); 121 if (IS_ERR(rdev)) { 122 dev_err(chip->dev, 123 "Failed to register regulator output %s\n", 124 reg->desc->name); 125 return PTR_ERR(rdev); 126 } 127 128 reg->rdev = rdev; 129 } 130 131 return 0; 132} 133 134static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on) 135{ 136 struct of_regulator_match matches[MAX20086_MAX_REGULATORS] = { }; 137 struct device_node *node; 138 unsigned int i; 139 int ret; 140 141 node = of_get_child_by_name(chip->dev->of_node, "regulators"); 142 if (!node) { 143 dev_err(chip->dev, "regulators node not found\n"); 144 return -ENODEV; 145 } 146 147 for (i = 0; i < chip->info->num_outputs; ++i) 148 matches[i].name = max20086_output_names[i]; 149 150 ret = of_regulator_match(chip->dev, node, matches, 151 chip->info->num_outputs); 152 of_node_put(node); 153 if (ret < 0) { 154 dev_err(chip->dev, "Failed to match regulators\n"); 155 return -EINVAL; 156 } 157 158 *boot_on = false; 159 160 for (i = 0; i < chip->info->num_outputs; i++) { 161 struct max20086_regulator *reg = &chip->regulators[i]; 162 163 reg->init_data = matches[i].init_data; 164 reg->of_node = matches[i].of_node; 165 reg->desc = &max20086_regulators[i]; 166 167 if (reg->init_data) { 168 if (reg->init_data->constraints.always_on || 169 reg->init_data->constraints.boot_on) 170 *boot_on = true; 171 } 172 } 173 174 return 0; 175} 176 177static int max20086_detect(struct max20086 *chip) 178{ 179 unsigned int data; 180 int ret; 181 182 ret = regmap_read(chip->regmap, MAX20086_REG_ID, &data); 183 if (ret < 0) { 184 dev_err(chip->dev, "Failed to read DEVICE_ID reg: %d\n", ret); 185 return ret; 186 } 187 188 if ((data & DEVICE_ID_MASK) != chip->info->id) { 189 dev_err(chip->dev, "Invalid device ID 0x%02x\n", data); 190 return -ENXIO; 191 } 192 193 return 0; 194} 195 196static bool max20086_gen_is_writeable_reg(struct device *dev, unsigned int reg) 197{ 198 switch (reg) { 199 case MAX20086_REG_MASK: 200 case MAX20086_REG_CONFIG: 201 return true; 202 default: 203 return false; 204 } 205} 206 207static const struct regmap_config max20086_regmap_config = { 208 .reg_bits = 8, 209 .val_bits = 8, 210 .writeable_reg = max20086_gen_is_writeable_reg, 211 .max_register = 0x9, 212 .cache_type = REGCACHE_NONE, 213}; 214 215static int max20086_i2c_probe(struct i2c_client *i2c) 216{ 217 struct max20086 *chip; 218 enum gpiod_flags flags; 219 bool boot_on; 220 int ret; 221 222 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 223 if (!chip) 224 return -ENOMEM; 225 226 chip->dev = &i2c->dev; 227 chip->info = device_get_match_data(chip->dev); 228 229 i2c_set_clientdata(i2c, chip); 230 231 chip->regmap = devm_regmap_init_i2c(i2c, &max20086_regmap_config); 232 if (IS_ERR(chip->regmap)) { 233 ret = PTR_ERR(chip->regmap); 234 dev_err(chip->dev, "Failed to allocate register map: %d\n", ret); 235 return ret; 236 } 237 238 ret = max20086_parse_regulators_dt(chip, &boot_on); 239 if (ret < 0) 240 return ret; 241 242 ret = max20086_detect(chip); 243 if (ret < 0) 244 return ret; 245 246 /* Until IRQ support is added, just disable all interrupts. */ 247 ret = regmap_update_bits(chip->regmap, MAX20086_REG_MASK, 248 MAX20086_INT_DISABLE_ALL, 249 MAX20086_INT_DISABLE_ALL); 250 if (ret < 0) { 251 dev_err(chip->dev, "Failed to disable interrupts: %d\n", ret); 252 return ret; 253 } 254 255 /* 256 * Get the enable GPIO. If any of the outputs is marked as being 257 * enabled at boot, request the GPIO with an initial high state to 258 * avoid disabling outputs that may have been turned on by the boot 259 * loader. Otherwise, request it with a low state to enter lower-power 260 * shutdown. 261 */ 262 flags = boot_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; 263 chip->ena_gpiod = devm_gpiod_get(chip->dev, "enable", flags); 264 if (IS_ERR(chip->ena_gpiod)) { 265 ret = PTR_ERR(chip->ena_gpiod); 266 dev_err(chip->dev, "Failed to get enable GPIO: %d\n", ret); 267 return ret; 268 } 269 270 ret = max20086_regulators_register(chip); 271 if (ret < 0) { 272 dev_err(chip->dev, "Failed to register regulators: %d\n", ret); 273 return ret; 274 } 275 276 return 0; 277} 278 279static const struct i2c_device_id max20086_i2c_id[] = { 280 { "max20086" }, 281 { "max20087" }, 282 { "max20088" }, 283 { "max20089" }, 284 { /* Sentinel */ }, 285}; 286 287MODULE_DEVICE_TABLE(i2c, max20086_i2c_id); 288 289static const struct of_device_id max20086_dt_ids[] = { 290 { 291 .compatible = "maxim,max20086", 292 .data = &(const struct max20086_chip_info) { 293 .id = MAX20086_DEVICE_ID_MAX20086, 294 .num_outputs = 4, 295 } 296 }, { 297 .compatible = "maxim,max20087", 298 .data = &(const struct max20086_chip_info) { 299 .id = MAX20086_DEVICE_ID_MAX20087, 300 .num_outputs = 4, 301 } 302 }, { 303 .compatible = "maxim,max20088", 304 .data = &(const struct max20086_chip_info) { 305 .id = MAX20086_DEVICE_ID_MAX20088, 306 .num_outputs = 2, 307 } 308 }, { 309 .compatible = "maxim,max20089", 310 .data = &(const struct max20086_chip_info) { 311 .id = MAX20086_DEVICE_ID_MAX20089, 312 .num_outputs = 2, 313 } 314 }, 315 { /* Sentinel */ }, 316}; 317 318MODULE_DEVICE_TABLE(of, max20086_dt_ids); 319 320static struct i2c_driver max20086_regulator_driver = { 321 .driver = { 322 .name = "max20086", 323 .of_match_table = of_match_ptr(max20086_dt_ids), 324 }, 325 .probe_new = max20086_i2c_probe, 326 .id_table = max20086_i2c_id, 327}; 328 329module_i2c_driver(max20086_regulator_driver); 330 331MODULE_AUTHOR("Watson Chow <watson.chow@avnet.com>"); 332MODULE_DESCRIPTION("MAX20086-MAX20089 Camera Power Protector Driver"); 333MODULE_LICENSE("GPL");