1a867bde3SEric Jeong // SPDX-License-Identifier: GPL-2.0+ 2a867bde3SEric Jeong // 3a867bde3SEric Jeong // SLG51000 High PSRR, Multi-Output Regulators 4a867bde3SEric Jeong // Copyright (C) 2019 Dialog Semiconductor 5a867bde3SEric Jeong // 6a867bde3SEric Jeong // Author: Eric Jeong <eric.jeong.opensource@diasemi.com> 7a867bde3SEric Jeong 8a867bde3SEric Jeong #include <linux/err.h> 9a867bde3SEric Jeong #include <linux/gpio/consumer.h> 10a867bde3SEric Jeong #include <linux/i2c.h> 11a867bde3SEric Jeong #include <linux/init.h> 12a867bde3SEric Jeong #include <linux/interrupt.h> 13a867bde3SEric Jeong #include <linux/irq.h> 14a867bde3SEric Jeong #include <linux/module.h> 15a867bde3SEric Jeong #include <linux/of.h> 16a867bde3SEric Jeong #include <linux/regmap.h> 17a867bde3SEric Jeong #include <linux/regulator/driver.h> 18a867bde3SEric Jeong #include <linux/regulator/machine.h> 19a867bde3SEric Jeong #include <linux/regulator/of_regulator.h> 20a867bde3SEric Jeong #include "slg51000-regulator.h" 21a867bde3SEric Jeong 22a867bde3SEric Jeong #define SLG51000_SCTL_EVT 7 23a867bde3SEric Jeong #define SLG51000_MAX_EVT_REGISTER 8 24a867bde3SEric Jeong #define SLG51000_LDOHP_LV_MIN 1200000 25a867bde3SEric Jeong #define SLG51000_LDOHP_HV_MIN 2400000 26a867bde3SEric Jeong 27a867bde3SEric Jeong enum slg51000_regulators { 28a867bde3SEric Jeong SLG51000_REGULATOR_LDO1 = 0, 29a867bde3SEric Jeong SLG51000_REGULATOR_LDO2, 30a867bde3SEric Jeong SLG51000_REGULATOR_LDO3, 31a867bde3SEric Jeong SLG51000_REGULATOR_LDO4, 32a867bde3SEric Jeong SLG51000_REGULATOR_LDO5, 33a867bde3SEric Jeong SLG51000_REGULATOR_LDO6, 34a867bde3SEric Jeong SLG51000_REGULATOR_LDO7, 35a867bde3SEric Jeong SLG51000_MAX_REGULATORS, 36a867bde3SEric Jeong }; 37a867bde3SEric Jeong 38a867bde3SEric Jeong struct slg51000 { 39a867bde3SEric Jeong struct device *dev; 40a867bde3SEric Jeong struct regmap *regmap; 41a867bde3SEric Jeong struct regulator_desc *rdesc[SLG51000_MAX_REGULATORS]; 42a867bde3SEric Jeong struct regulator_dev *rdev[SLG51000_MAX_REGULATORS]; 43a867bde3SEric Jeong struct gpio_desc *cs_gpiod; 44a867bde3SEric Jeong int chip_irq; 45a867bde3SEric Jeong }; 46a867bde3SEric Jeong 47a867bde3SEric Jeong struct slg51000_evt_sta { 48a867bde3SEric Jeong unsigned int ereg; 49a867bde3SEric Jeong unsigned int sreg; 50a867bde3SEric Jeong }; 51a867bde3SEric Jeong 52a867bde3SEric Jeong static const struct slg51000_evt_sta es_reg[SLG51000_MAX_EVT_REGISTER] = { 53a867bde3SEric Jeong {SLG51000_LDO1_EVENT, SLG51000_LDO1_STATUS}, 54a867bde3SEric Jeong {SLG51000_LDO2_EVENT, SLG51000_LDO2_STATUS}, 55a867bde3SEric Jeong {SLG51000_LDO3_EVENT, SLG51000_LDO3_STATUS}, 56a867bde3SEric Jeong {SLG51000_LDO4_EVENT, SLG51000_LDO4_STATUS}, 57a867bde3SEric Jeong {SLG51000_LDO5_EVENT, SLG51000_LDO5_STATUS}, 58a867bde3SEric Jeong {SLG51000_LDO6_EVENT, SLG51000_LDO6_STATUS}, 59a867bde3SEric Jeong {SLG51000_LDO7_EVENT, SLG51000_LDO7_STATUS}, 60a867bde3SEric Jeong {SLG51000_SYSCTL_EVENT, SLG51000_SYSCTL_STATUS}, 61a867bde3SEric Jeong }; 62a867bde3SEric Jeong 63a867bde3SEric Jeong static const struct regmap_range slg51000_writeable_ranges[] = { 64a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_MATRIX_CONF_A, 65a867bde3SEric Jeong SLG51000_SYSCTL_MATRIX_CONF_A), 66a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_VSEL, SLG51000_LDO1_VSEL), 67a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_MINV, SLG51000_LDO1_MAXV), 68a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_IRQ_MASK, SLG51000_LDO1_IRQ_MASK), 69a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_VSEL, SLG51000_LDO2_VSEL), 70a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_MINV, SLG51000_LDO2_MAXV), 71a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_IRQ_MASK, SLG51000_LDO2_IRQ_MASK), 72a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_VSEL, SLG51000_LDO3_VSEL), 73a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_MINV, SLG51000_LDO3_MAXV), 74a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_IRQ_MASK, SLG51000_LDO3_IRQ_MASK), 75a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_VSEL, SLG51000_LDO4_VSEL), 76a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_MINV, SLG51000_LDO4_MAXV), 77a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_IRQ_MASK, SLG51000_LDO4_IRQ_MASK), 78a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_VSEL, SLG51000_LDO5_VSEL), 79a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_MINV, SLG51000_LDO5_MAXV), 80a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_IRQ_MASK, SLG51000_LDO5_IRQ_MASK), 81a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_VSEL, SLG51000_LDO6_VSEL), 82a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_MINV, SLG51000_LDO6_MAXV), 83a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_IRQ_MASK, SLG51000_LDO6_IRQ_MASK), 84a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_VSEL, SLG51000_LDO7_VSEL), 85a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_MINV, SLG51000_LDO7_MAXV), 86a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_IRQ_MASK, SLG51000_LDO7_IRQ_MASK), 87a867bde3SEric Jeong regmap_reg_range(SLG51000_OTP_IRQ_MASK, SLG51000_OTP_IRQ_MASK), 88a867bde3SEric Jeong }; 89a867bde3SEric Jeong 90a867bde3SEric Jeong static const struct regmap_range slg51000_readable_ranges[] = { 91a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_PATN_ID_B0, 92a867bde3SEric Jeong SLG51000_SYSCTL_PATN_ID_B2), 93a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_SYS_CONF_A, 94a867bde3SEric Jeong SLG51000_SYSCTL_SYS_CONF_A), 95a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_SYS_CONF_D, 96a867bde3SEric Jeong SLG51000_SYSCTL_MATRIX_CONF_B), 97a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_REFGEN_CONF_C, 98a867bde3SEric Jeong SLG51000_SYSCTL_UVLO_CONF_A), 99a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_FAULT_LOG1, SLG51000_SYSCTL_IRQ_MASK), 100a867bde3SEric Jeong regmap_reg_range(SLG51000_IO_GPIO1_CONF, SLG51000_IO_GPIO_STATUS), 101a867bde3SEric Jeong regmap_reg_range(SLG51000_LUTARRAY_LUT_VAL_0, 102a867bde3SEric Jeong SLG51000_LUTARRAY_LUT_VAL_11), 103a867bde3SEric Jeong regmap_reg_range(SLG51000_MUXARRAY_INPUT_SEL_0, 104a867bde3SEric Jeong SLG51000_MUXARRAY_INPUT_SEL_63), 105a867bde3SEric Jeong regmap_reg_range(SLG51000_PWRSEQ_RESOURCE_EN_0, 106a867bde3SEric Jeong SLG51000_PWRSEQ_INPUT_SENSE_CONF_B), 107a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_VSEL, SLG51000_LDO1_VSEL), 108a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_MINV, SLG51000_LDO1_MAXV), 109a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_MISC1, SLG51000_LDO1_VSEL_ACTUAL), 110a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_EVENT, SLG51000_LDO1_IRQ_MASK), 111a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_VSEL, SLG51000_LDO2_VSEL), 112a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_MINV, SLG51000_LDO2_MAXV), 113a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_MISC1, SLG51000_LDO2_VSEL_ACTUAL), 114a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_EVENT, SLG51000_LDO2_IRQ_MASK), 115a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_VSEL, SLG51000_LDO3_VSEL), 116a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_MINV, SLG51000_LDO3_MAXV), 117a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_CONF1, SLG51000_LDO3_VSEL_ACTUAL), 118a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_EVENT, SLG51000_LDO3_IRQ_MASK), 119a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_VSEL, SLG51000_LDO4_VSEL), 120a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_MINV, SLG51000_LDO4_MAXV), 121a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_CONF1, SLG51000_LDO4_VSEL_ACTUAL), 122a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_EVENT, SLG51000_LDO4_IRQ_MASK), 123a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_VSEL, SLG51000_LDO5_VSEL), 124a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_MINV, SLG51000_LDO5_MAXV), 125a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_TRIM2, SLG51000_LDO5_TRIM2), 126a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_CONF1, SLG51000_LDO5_VSEL_ACTUAL), 127a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_EVENT, SLG51000_LDO5_IRQ_MASK), 128a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_VSEL, SLG51000_LDO6_VSEL), 129a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_MINV, SLG51000_LDO6_MAXV), 130a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_TRIM2, SLG51000_LDO6_TRIM2), 131a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_CONF1, SLG51000_LDO6_VSEL_ACTUAL), 132a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_EVENT, SLG51000_LDO6_IRQ_MASK), 133a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_VSEL, SLG51000_LDO7_VSEL), 134a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_MINV, SLG51000_LDO7_MAXV), 135a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_CONF1, SLG51000_LDO7_VSEL_ACTUAL), 136a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_EVENT, SLG51000_LDO7_IRQ_MASK), 137a867bde3SEric Jeong regmap_reg_range(SLG51000_OTP_EVENT, SLG51000_OTP_EVENT), 138a867bde3SEric Jeong regmap_reg_range(SLG51000_OTP_IRQ_MASK, SLG51000_OTP_IRQ_MASK), 139a867bde3SEric Jeong regmap_reg_range(SLG51000_OTP_LOCK_OTP_PROG, SLG51000_OTP_LOCK_CTRL), 140a867bde3SEric Jeong regmap_reg_range(SLG51000_LOCK_GLOBAL_LOCK_CTRL1, 141a867bde3SEric Jeong SLG51000_LOCK_GLOBAL_LOCK_CTRL1), 142a867bde3SEric Jeong }; 143a867bde3SEric Jeong 144a867bde3SEric Jeong static const struct regmap_range slg51000_volatile_ranges[] = { 145a867bde3SEric Jeong regmap_reg_range(SLG51000_SYSCTL_FAULT_LOG1, SLG51000_SYSCTL_STATUS), 146a867bde3SEric Jeong regmap_reg_range(SLG51000_IO_GPIO_STATUS, SLG51000_IO_GPIO_STATUS), 147a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO1_EVENT, SLG51000_LDO1_STATUS), 148a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO2_EVENT, SLG51000_LDO2_STATUS), 149a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO3_EVENT, SLG51000_LDO3_STATUS), 150a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO4_EVENT, SLG51000_LDO4_STATUS), 151a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO5_EVENT, SLG51000_LDO5_STATUS), 152a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO6_EVENT, SLG51000_LDO6_STATUS), 153a867bde3SEric Jeong regmap_reg_range(SLG51000_LDO7_EVENT, SLG51000_LDO7_STATUS), 154a867bde3SEric Jeong regmap_reg_range(SLG51000_OTP_EVENT, SLG51000_OTP_EVENT), 155a867bde3SEric Jeong }; 156a867bde3SEric Jeong 157a867bde3SEric Jeong static const struct regmap_access_table slg51000_writeable_table = { 158a867bde3SEric Jeong .yes_ranges = slg51000_writeable_ranges, 159a867bde3SEric Jeong .n_yes_ranges = ARRAY_SIZE(slg51000_writeable_ranges), 160a867bde3SEric Jeong }; 161a867bde3SEric Jeong 162a867bde3SEric Jeong static const struct regmap_access_table slg51000_readable_table = { 163a867bde3SEric Jeong .yes_ranges = slg51000_readable_ranges, 164a867bde3SEric Jeong .n_yes_ranges = ARRAY_SIZE(slg51000_readable_ranges), 165a867bde3SEric Jeong }; 166a867bde3SEric Jeong 167a867bde3SEric Jeong static const struct regmap_access_table slg51000_volatile_table = { 168a867bde3SEric Jeong .yes_ranges = slg51000_volatile_ranges, 169a867bde3SEric Jeong .n_yes_ranges = ARRAY_SIZE(slg51000_volatile_ranges), 170a867bde3SEric Jeong }; 171a867bde3SEric Jeong 172a867bde3SEric Jeong static const struct regmap_config slg51000_regmap_config = { 173a867bde3SEric Jeong .reg_bits = 16, 174a867bde3SEric Jeong .val_bits = 8, 175a867bde3SEric Jeong .max_register = 0x8000, 176a867bde3SEric Jeong .wr_table = &slg51000_writeable_table, 177a867bde3SEric Jeong .rd_table = &slg51000_readable_table, 178a867bde3SEric Jeong .volatile_table = &slg51000_volatile_table, 179a867bde3SEric Jeong }; 180a867bde3SEric Jeong 1810a33d4feSAxel Lin static const struct regulator_ops slg51000_regl_ops = { 182a867bde3SEric Jeong .enable = regulator_enable_regmap, 183a867bde3SEric Jeong .disable = regulator_disable_regmap, 184a867bde3SEric Jeong .is_enabled = regulator_is_enabled_regmap, 185a867bde3SEric Jeong .list_voltage = regulator_list_voltage_linear, 186a867bde3SEric Jeong .map_voltage = regulator_map_voltage_linear, 187a867bde3SEric Jeong .get_voltage_sel = regulator_get_voltage_sel_regmap, 188a867bde3SEric Jeong .set_voltage_sel = regulator_set_voltage_sel_regmap, 189a867bde3SEric Jeong }; 190a867bde3SEric Jeong 1910a33d4feSAxel Lin static const struct regulator_ops slg51000_switch_ops = { 192a867bde3SEric Jeong .enable = regulator_enable_regmap, 193a867bde3SEric Jeong .disable = regulator_disable_regmap, 194a867bde3SEric Jeong .is_enabled = regulator_is_enabled_regmap, 195a867bde3SEric Jeong }; 196a867bde3SEric Jeong 197a867bde3SEric Jeong static int slg51000_of_parse_cb(struct device_node *np, 198a867bde3SEric Jeong const struct regulator_desc *desc, 199a867bde3SEric Jeong struct regulator_config *config) 200a867bde3SEric Jeong { 20112c574d8SAxel Lin struct gpio_desc *ena_gpiod; 202a867bde3SEric Jeong 203*de2cd1a5SDmitry Torokhov ena_gpiod = fwnode_gpiod_get_index(of_fwnode_handle(np), "enable", 0, 204*de2cd1a5SDmitry Torokhov GPIOD_OUT_LOW | 205*de2cd1a5SDmitry Torokhov GPIOD_FLAGS_BIT_NONEXCLUSIVE, 206*de2cd1a5SDmitry Torokhov "gpio-en-ldo"); 207*de2cd1a5SDmitry Torokhov if (!IS_ERR(ena_gpiod)) 20812c574d8SAxel Lin config->ena_gpiod = ena_gpiod; 209a867bde3SEric Jeong 210a867bde3SEric Jeong return 0; 211a867bde3SEric Jeong } 212a867bde3SEric Jeong 213a867bde3SEric Jeong #define SLG51000_REGL_DESC(_id, _name, _s_name, _min, _step) \ 214a867bde3SEric Jeong [SLG51000_REGULATOR_##_id] = { \ 215a867bde3SEric Jeong .name = #_name, \ 216a867bde3SEric Jeong .supply_name = _s_name, \ 217a867bde3SEric Jeong .id = SLG51000_REGULATOR_##_id, \ 218a867bde3SEric Jeong .of_match = of_match_ptr(#_name), \ 219a867bde3SEric Jeong .of_parse_cb = slg51000_of_parse_cb, \ 220a867bde3SEric Jeong .ops = &slg51000_regl_ops, \ 221a867bde3SEric Jeong .regulators_node = of_match_ptr("regulators"), \ 222a867bde3SEric Jeong .n_voltages = 256, \ 223a867bde3SEric Jeong .min_uV = _min, \ 224a867bde3SEric Jeong .uV_step = _step, \ 225a867bde3SEric Jeong .linear_min_sel = 0, \ 226a867bde3SEric Jeong .vsel_mask = SLG51000_VSEL_MASK, \ 227a867bde3SEric Jeong .vsel_reg = SLG51000_##_id##_VSEL, \ 228a867bde3SEric Jeong .enable_reg = SLG51000_SYSCTL_MATRIX_CONF_A, \ 229a867bde3SEric Jeong .enable_mask = BIT(SLG51000_REGULATOR_##_id), \ 230a867bde3SEric Jeong .type = REGULATOR_VOLTAGE, \ 231a867bde3SEric Jeong .owner = THIS_MODULE, \ 232a867bde3SEric Jeong } 233a867bde3SEric Jeong 234a867bde3SEric Jeong static struct regulator_desc regls_desc[SLG51000_MAX_REGULATORS] = { 235a867bde3SEric Jeong SLG51000_REGL_DESC(LDO1, ldo1, NULL, 2400000, 5000), 236a867bde3SEric Jeong SLG51000_REGL_DESC(LDO2, ldo2, NULL, 2400000, 5000), 237a867bde3SEric Jeong SLG51000_REGL_DESC(LDO3, ldo3, "vin3", 1200000, 10000), 238a867bde3SEric Jeong SLG51000_REGL_DESC(LDO4, ldo4, "vin4", 1200000, 10000), 239a867bde3SEric Jeong SLG51000_REGL_DESC(LDO5, ldo5, "vin5", 400000, 5000), 240a867bde3SEric Jeong SLG51000_REGL_DESC(LDO6, ldo6, "vin6", 400000, 5000), 241a867bde3SEric Jeong SLG51000_REGL_DESC(LDO7, ldo7, "vin7", 1200000, 10000), 242a867bde3SEric Jeong }; 243a867bde3SEric Jeong 244a867bde3SEric Jeong static int slg51000_regulator_init(struct slg51000 *chip) 245a867bde3SEric Jeong { 246a867bde3SEric Jeong struct regulator_config config = { }; 247a867bde3SEric Jeong struct regulator_desc *rdesc; 248a867bde3SEric Jeong unsigned int reg, val; 249a867bde3SEric Jeong u8 vsel_range[2]; 250a867bde3SEric Jeong int id, ret = 0; 251a867bde3SEric Jeong const unsigned int min_regs[SLG51000_MAX_REGULATORS] = { 252a867bde3SEric Jeong SLG51000_LDO1_MINV, SLG51000_LDO2_MINV, SLG51000_LDO3_MINV, 253a867bde3SEric Jeong SLG51000_LDO4_MINV, SLG51000_LDO5_MINV, SLG51000_LDO6_MINV, 254a867bde3SEric Jeong SLG51000_LDO7_MINV, 255a867bde3SEric Jeong }; 256a867bde3SEric Jeong 257a867bde3SEric Jeong for (id = 0; id < SLG51000_MAX_REGULATORS; id++) { 258a867bde3SEric Jeong chip->rdesc[id] = ®ls_desc[id]; 259a867bde3SEric Jeong rdesc = chip->rdesc[id]; 260a867bde3SEric Jeong config.regmap = chip->regmap; 261a867bde3SEric Jeong config.dev = chip->dev; 262a867bde3SEric Jeong config.driver_data = chip; 263a867bde3SEric Jeong 264a867bde3SEric Jeong ret = regmap_bulk_read(chip->regmap, min_regs[id], 265a867bde3SEric Jeong vsel_range, 2); 266a867bde3SEric Jeong if (ret < 0) { 267a867bde3SEric Jeong dev_err(chip->dev, 268a867bde3SEric Jeong "Failed to read the MIN register\n"); 269a867bde3SEric Jeong return ret; 270a867bde3SEric Jeong } 271a867bde3SEric Jeong 272a867bde3SEric Jeong switch (id) { 273a867bde3SEric Jeong case SLG51000_REGULATOR_LDO1: 274a867bde3SEric Jeong case SLG51000_REGULATOR_LDO2: 275a867bde3SEric Jeong if (id == SLG51000_REGULATOR_LDO1) 276a867bde3SEric Jeong reg = SLG51000_LDO1_MISC1; 277a867bde3SEric Jeong else 278a867bde3SEric Jeong reg = SLG51000_LDO2_MISC1; 279a867bde3SEric Jeong 280a867bde3SEric Jeong ret = regmap_read(chip->regmap, reg, &val); 281a867bde3SEric Jeong if (ret < 0) { 282a867bde3SEric Jeong dev_err(chip->dev, 283a867bde3SEric Jeong "Failed to read voltage range of ldo%d\n", 284a867bde3SEric Jeong id + 1); 285a867bde3SEric Jeong return ret; 286a867bde3SEric Jeong } 287a867bde3SEric Jeong 288a867bde3SEric Jeong rdesc->linear_min_sel = vsel_range[0]; 289a867bde3SEric Jeong rdesc->n_voltages = vsel_range[1] + 1; 290a867bde3SEric Jeong if (val & SLG51000_SEL_VRANGE_MASK) 291a867bde3SEric Jeong rdesc->min_uV = SLG51000_LDOHP_HV_MIN 292a867bde3SEric Jeong + (vsel_range[0] 293a867bde3SEric Jeong * rdesc->uV_step); 294a867bde3SEric Jeong else 295a867bde3SEric Jeong rdesc->min_uV = SLG51000_LDOHP_LV_MIN 296a867bde3SEric Jeong + (vsel_range[0] 297a867bde3SEric Jeong * rdesc->uV_step); 298a867bde3SEric Jeong break; 299a867bde3SEric Jeong 300a867bde3SEric Jeong case SLG51000_REGULATOR_LDO5: 301a867bde3SEric Jeong case SLG51000_REGULATOR_LDO6: 302a867bde3SEric Jeong if (id == SLG51000_REGULATOR_LDO5) 303a867bde3SEric Jeong reg = SLG51000_LDO5_TRIM2; 304a867bde3SEric Jeong else 305a867bde3SEric Jeong reg = SLG51000_LDO6_TRIM2; 306a867bde3SEric Jeong 307a867bde3SEric Jeong ret = regmap_read(chip->regmap, reg, &val); 308a867bde3SEric Jeong if (ret < 0) { 309a867bde3SEric Jeong dev_err(chip->dev, 310a867bde3SEric Jeong "Failed to read LDO mode register\n"); 311a867bde3SEric Jeong return ret; 312a867bde3SEric Jeong } 313a867bde3SEric Jeong 314a867bde3SEric Jeong if (val & SLG51000_SEL_BYP_MODE_MASK) { 315a867bde3SEric Jeong rdesc->ops = &slg51000_switch_ops; 316a867bde3SEric Jeong rdesc->n_voltages = 0; 317a867bde3SEric Jeong rdesc->min_uV = 0; 318a867bde3SEric Jeong rdesc->uV_step = 0; 319a867bde3SEric Jeong rdesc->linear_min_sel = 0; 320a867bde3SEric Jeong break; 321a867bde3SEric Jeong } 322a867bde3SEric Jeong /* Fall through - to the check below.*/ 323a867bde3SEric Jeong 324a867bde3SEric Jeong default: 325a867bde3SEric Jeong rdesc->linear_min_sel = vsel_range[0]; 326a867bde3SEric Jeong rdesc->n_voltages = vsel_range[1] + 1; 327a867bde3SEric Jeong rdesc->min_uV = rdesc->min_uV 328a867bde3SEric Jeong + (vsel_range[0] * rdesc->uV_step); 329a867bde3SEric Jeong break; 330a867bde3SEric Jeong } 331a867bde3SEric Jeong 332a867bde3SEric Jeong chip->rdev[id] = devm_regulator_register(chip->dev, rdesc, 333a867bde3SEric Jeong &config); 334a867bde3SEric Jeong if (IS_ERR(chip->rdev[id])) { 335a867bde3SEric Jeong ret = PTR_ERR(chip->rdev[id]); 336a867bde3SEric Jeong dev_err(chip->dev, 337a867bde3SEric Jeong "Failed to register regulator(%s):%d\n", 338a867bde3SEric Jeong chip->rdesc[id]->name, ret); 339a867bde3SEric Jeong return ret; 340a867bde3SEric Jeong } 341a867bde3SEric Jeong } 342a867bde3SEric Jeong 343a867bde3SEric Jeong return 0; 344a867bde3SEric Jeong } 345a867bde3SEric Jeong 346a867bde3SEric Jeong static irqreturn_t slg51000_irq_handler(int irq, void *data) 347a867bde3SEric Jeong { 348a867bde3SEric Jeong struct slg51000 *chip = data; 349a867bde3SEric Jeong struct regmap *regmap = chip->regmap; 350a867bde3SEric Jeong enum { R0 = 0, R1, R2, REG_MAX }; 351a867bde3SEric Jeong u8 evt[SLG51000_MAX_EVT_REGISTER][REG_MAX]; 352a867bde3SEric Jeong int ret, i, handled = IRQ_NONE; 353a867bde3SEric Jeong unsigned int evt_otp, mask_otp; 354a867bde3SEric Jeong 355a867bde3SEric Jeong /* Read event[R0], status[R1] and mask[R2] register */ 356a867bde3SEric Jeong for (i = 0; i < SLG51000_MAX_EVT_REGISTER; i++) { 357a867bde3SEric Jeong ret = regmap_bulk_read(regmap, es_reg[i].ereg, evt[i], REG_MAX); 358a867bde3SEric Jeong if (ret < 0) { 359a867bde3SEric Jeong dev_err(chip->dev, 360a867bde3SEric Jeong "Failed to read event registers(%d)\n", ret); 361a867bde3SEric Jeong return IRQ_NONE; 362a867bde3SEric Jeong } 363a867bde3SEric Jeong } 364a867bde3SEric Jeong 365a867bde3SEric Jeong ret = regmap_read(regmap, SLG51000_OTP_EVENT, &evt_otp); 366a867bde3SEric Jeong if (ret < 0) { 367a867bde3SEric Jeong dev_err(chip->dev, 368a867bde3SEric Jeong "Failed to read otp event registers(%d)\n", ret); 369a867bde3SEric Jeong return IRQ_NONE; 370a867bde3SEric Jeong } 371a867bde3SEric Jeong 372a867bde3SEric Jeong ret = regmap_read(regmap, SLG51000_OTP_IRQ_MASK, &mask_otp); 373a867bde3SEric Jeong if (ret < 0) { 374a867bde3SEric Jeong dev_err(chip->dev, 375a867bde3SEric Jeong "Failed to read otp mask register(%d)\n", ret); 376a867bde3SEric Jeong return IRQ_NONE; 377a867bde3SEric Jeong } 378a867bde3SEric Jeong 379a867bde3SEric Jeong if ((evt_otp & SLG51000_EVT_CRC_MASK) && 380a867bde3SEric Jeong !(mask_otp & SLG51000_IRQ_CRC_MASK)) { 381a867bde3SEric Jeong dev_info(chip->dev, 382a867bde3SEric Jeong "OTP has been read or OTP crc is not zero\n"); 383a867bde3SEric Jeong handled = IRQ_HANDLED; 384a867bde3SEric Jeong } 385a867bde3SEric Jeong 386a867bde3SEric Jeong for (i = 0; i < SLG51000_MAX_REGULATORS; i++) { 387a867bde3SEric Jeong if (!(evt[i][R2] & SLG51000_IRQ_ILIM_FLAG_MASK) && 388a867bde3SEric Jeong (evt[i][R0] & SLG51000_EVT_ILIM_FLAG_MASK)) { 389a867bde3SEric Jeong regulator_lock(chip->rdev[i]); 390a867bde3SEric Jeong regulator_notifier_call_chain(chip->rdev[i], 391a867bde3SEric Jeong REGULATOR_EVENT_OVER_CURRENT, NULL); 392a867bde3SEric Jeong regulator_unlock(chip->rdev[i]); 393a867bde3SEric Jeong 394a867bde3SEric Jeong if (evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK) 395a867bde3SEric Jeong dev_warn(chip->dev, 396a867bde3SEric Jeong "Over-current limit(ldo%d)\n", i + 1); 397a867bde3SEric Jeong handled = IRQ_HANDLED; 398a867bde3SEric Jeong } 399a867bde3SEric Jeong } 400a867bde3SEric Jeong 401a867bde3SEric Jeong if (!(evt[SLG51000_SCTL_EVT][R2] & SLG51000_IRQ_HIGH_TEMP_WARN_MASK) && 402a867bde3SEric Jeong (evt[SLG51000_SCTL_EVT][R0] & SLG51000_EVT_HIGH_TEMP_WARN_MASK)) { 403a867bde3SEric Jeong for (i = 0; i < SLG51000_MAX_REGULATORS; i++) { 404a867bde3SEric Jeong if (!(evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK) && 405a867bde3SEric Jeong (evt[i][R1] & SLG51000_STA_VOUT_OK_FLAG_MASK)) { 406a867bde3SEric Jeong regulator_lock(chip->rdev[i]); 407a867bde3SEric Jeong regulator_notifier_call_chain(chip->rdev[i], 408a867bde3SEric Jeong REGULATOR_EVENT_OVER_TEMP, NULL); 409a867bde3SEric Jeong regulator_unlock(chip->rdev[i]); 410a867bde3SEric Jeong } 411a867bde3SEric Jeong } 412a867bde3SEric Jeong handled = IRQ_HANDLED; 413a867bde3SEric Jeong if (evt[SLG51000_SCTL_EVT][R1] & 414a867bde3SEric Jeong SLG51000_STA_HIGH_TEMP_WARN_MASK) 415a867bde3SEric Jeong dev_warn(chip->dev, "High temperature warning!\n"); 416a867bde3SEric Jeong } 417a867bde3SEric Jeong 418a867bde3SEric Jeong return handled; 419a867bde3SEric Jeong } 420a867bde3SEric Jeong 421a867bde3SEric Jeong static void slg51000_clear_fault_log(struct slg51000 *chip) 422a867bde3SEric Jeong { 423a867bde3SEric Jeong unsigned int val = 0; 424a867bde3SEric Jeong int ret = 0; 425a867bde3SEric Jeong 426a867bde3SEric Jeong ret = regmap_read(chip->regmap, SLG51000_SYSCTL_FAULT_LOG1, &val); 427a867bde3SEric Jeong if (ret < 0) { 428a867bde3SEric Jeong dev_err(chip->dev, "Failed to read Fault log register\n"); 429a867bde3SEric Jeong return; 430a867bde3SEric Jeong } 431a867bde3SEric Jeong 432a867bde3SEric Jeong if (val & SLG51000_FLT_OVER_TEMP_MASK) 433a867bde3SEric Jeong dev_dbg(chip->dev, "Fault log: FLT_OVER_TEMP\n"); 434a867bde3SEric Jeong if (val & SLG51000_FLT_POWER_SEQ_CRASH_REQ_MASK) 435a867bde3SEric Jeong dev_dbg(chip->dev, "Fault log: FLT_POWER_SEQ_CRASH_REQ\n"); 436a867bde3SEric Jeong if (val & SLG51000_FLT_RST_MASK) 437a867bde3SEric Jeong dev_dbg(chip->dev, "Fault log: FLT_RST\n"); 438a867bde3SEric Jeong if (val & SLG51000_FLT_POR_MASK) 439a867bde3SEric Jeong dev_dbg(chip->dev, "Fault log: FLT_POR\n"); 440a867bde3SEric Jeong } 441a867bde3SEric Jeong 442a867bde3SEric Jeong static int slg51000_i2c_probe(struct i2c_client *client, 443a867bde3SEric Jeong const struct i2c_device_id *id) 444a867bde3SEric Jeong { 445a867bde3SEric Jeong struct device *dev = &client->dev; 446a867bde3SEric Jeong struct slg51000 *chip; 447c0b91344SDmitry Torokhov struct gpio_desc *cs_gpiod; 448a867bde3SEric Jeong int error, ret; 449a867bde3SEric Jeong 450a867bde3SEric Jeong chip = devm_kzalloc(dev, sizeof(struct slg51000), GFP_KERNEL); 451a867bde3SEric Jeong if (!chip) 452a867bde3SEric Jeong return -ENOMEM; 453a867bde3SEric Jeong 454c0b91344SDmitry Torokhov cs_gpiod = devm_gpiod_get_optional(dev, "dlg,cs", 455c0b91344SDmitry Torokhov GPIOD_OUT_HIGH | 456c0b91344SDmitry Torokhov GPIOD_FLAGS_BIT_NONEXCLUSIVE); 457c0b91344SDmitry Torokhov if (IS_ERR(cs_gpiod)) 458c0b91344SDmitry Torokhov return PTR_ERR(cs_gpiod); 459c0b91344SDmitry Torokhov 460c0b91344SDmitry Torokhov if (cs_gpiod) { 461a867bde3SEric Jeong dev_info(dev, "Found chip selector property\n"); 462a867bde3SEric Jeong chip->cs_gpiod = cs_gpiod; 463a867bde3SEric Jeong } 464a867bde3SEric Jeong 465a867bde3SEric Jeong i2c_set_clientdata(client, chip); 466a867bde3SEric Jeong chip->chip_irq = client->irq; 467a867bde3SEric Jeong chip->dev = dev; 468a867bde3SEric Jeong chip->regmap = devm_regmap_init_i2c(client, &slg51000_regmap_config); 469a867bde3SEric Jeong if (IS_ERR(chip->regmap)) { 470a867bde3SEric Jeong error = PTR_ERR(chip->regmap); 471a867bde3SEric Jeong dev_err(dev, "Failed to allocate register map: %d\n", 472a867bde3SEric Jeong error); 473a867bde3SEric Jeong return error; 474a867bde3SEric Jeong } 475a867bde3SEric Jeong 476a867bde3SEric Jeong ret = slg51000_regulator_init(chip); 477a867bde3SEric Jeong if (ret < 0) { 478a867bde3SEric Jeong dev_err(chip->dev, "Failed to init regulator(%d)\n", ret); 479a867bde3SEric Jeong return ret; 480a867bde3SEric Jeong } 481a867bde3SEric Jeong 482a867bde3SEric Jeong slg51000_clear_fault_log(chip); 483a867bde3SEric Jeong 484a867bde3SEric Jeong if (chip->chip_irq) { 485a867bde3SEric Jeong ret = devm_request_threaded_irq(dev, chip->chip_irq, NULL, 486a867bde3SEric Jeong slg51000_irq_handler, 487a867bde3SEric Jeong (IRQF_TRIGGER_HIGH | 488a867bde3SEric Jeong IRQF_ONESHOT), 489a867bde3SEric Jeong "slg51000-irq", chip); 490a867bde3SEric Jeong if (ret != 0) { 491a867bde3SEric Jeong dev_err(dev, "Failed to request IRQ: %d\n", 492a867bde3SEric Jeong chip->chip_irq); 493a867bde3SEric Jeong return ret; 494a867bde3SEric Jeong } 495a867bde3SEric Jeong } else { 496a867bde3SEric Jeong dev_info(dev, "No IRQ configured\n"); 497a867bde3SEric Jeong } 498a867bde3SEric Jeong 499a867bde3SEric Jeong return ret; 500a867bde3SEric Jeong } 501a867bde3SEric Jeong 502a867bde3SEric Jeong static const struct i2c_device_id slg51000_i2c_id[] = { 503a867bde3SEric Jeong {"slg51000", 0}, 504a867bde3SEric Jeong {}, 505a867bde3SEric Jeong }; 506a867bde3SEric Jeong MODULE_DEVICE_TABLE(i2c, slg51000_i2c_id); 507a867bde3SEric Jeong 508a867bde3SEric Jeong static struct i2c_driver slg51000_regulator_driver = { 509a867bde3SEric Jeong .driver = { 510a867bde3SEric Jeong .name = "slg51000-regulator", 511a867bde3SEric Jeong }, 512a867bde3SEric Jeong .probe = slg51000_i2c_probe, 513a867bde3SEric Jeong .id_table = slg51000_i2c_id, 514a867bde3SEric Jeong }; 515a867bde3SEric Jeong 516a867bde3SEric Jeong module_i2c_driver(slg51000_regulator_driver); 517a867bde3SEric Jeong 518a867bde3SEric Jeong MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@diasemi.com>"); 519a867bde3SEric Jeong MODULE_DESCRIPTION("SLG51000 regulator driver"); 520a867bde3SEric Jeong MODULE_LICENSE("GPL"); 521a867bde3SEric Jeong 522