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