1*0959b670SJoy Zou // SPDX-License-Identifier: GPL-2.0 2*0959b670SJoy Zou /* 3*0959b670SJoy Zou * Copyright 2024 NXP. 4*0959b670SJoy Zou * NXP PF9453 pmic driver 5*0959b670SJoy Zou */ 6*0959b670SJoy Zou 7*0959b670SJoy Zou #include <linux/bits.h> 8*0959b670SJoy Zou #include <linux/err.h> 9*0959b670SJoy Zou #include <linux/gpio/consumer.h> 10*0959b670SJoy Zou #include <linux/i2c.h> 11*0959b670SJoy Zou #include <linux/interrupt.h> 12*0959b670SJoy Zou #include <linux/kernel.h> 13*0959b670SJoy Zou #include <linux/module.h> 14*0959b670SJoy Zou #include <linux/of.h> 15*0959b670SJoy Zou #include <linux/platform_device.h> 16*0959b670SJoy Zou #include <linux/regmap.h> 17*0959b670SJoy Zou #include <linux/regulator/driver.h> 18*0959b670SJoy Zou #include <linux/regulator/machine.h> 19*0959b670SJoy Zou #include <linux/regulator/of_regulator.h> 20*0959b670SJoy Zou 21*0959b670SJoy Zou struct pf9453_dvs_config { 22*0959b670SJoy Zou unsigned int run_reg; /* dvs0 */ 23*0959b670SJoy Zou unsigned int run_mask; 24*0959b670SJoy Zou unsigned int standby_reg; /* dvs1 */ 25*0959b670SJoy Zou unsigned int standby_mask; 26*0959b670SJoy Zou }; 27*0959b670SJoy Zou 28*0959b670SJoy Zou struct pf9453_regulator_desc { 29*0959b670SJoy Zou struct regulator_desc desc; 30*0959b670SJoy Zou const struct pf9453_dvs_config dvs; 31*0959b670SJoy Zou }; 32*0959b670SJoy Zou 33*0959b670SJoy Zou struct pf9453 { 34*0959b670SJoy Zou struct device *dev; 35*0959b670SJoy Zou struct regmap *regmap; 36*0959b670SJoy Zou struct gpio_desc *sd_vsel_gpio; 37*0959b670SJoy Zou int irq; 38*0959b670SJoy Zou }; 39*0959b670SJoy Zou 40*0959b670SJoy Zou enum { 41*0959b670SJoy Zou PF9453_BUCK1 = 0, 42*0959b670SJoy Zou PF9453_BUCK2, 43*0959b670SJoy Zou PF9453_BUCK3, 44*0959b670SJoy Zou PF9453_BUCK4, 45*0959b670SJoy Zou PF9453_LDO1, 46*0959b670SJoy Zou PF9453_LDO2, 47*0959b670SJoy Zou PF9453_LDOSNVS, 48*0959b670SJoy Zou PF9453_REGULATOR_CNT 49*0959b670SJoy Zou }; 50*0959b670SJoy Zou 51*0959b670SJoy Zou enum { 52*0959b670SJoy Zou PF9453_DVS_LEVEL_RUN = 0, 53*0959b670SJoy Zou PF9453_DVS_LEVEL_STANDBY, 54*0959b670SJoy Zou PF9453_DVS_LEVEL_DPSTANDBY, 55*0959b670SJoy Zou PF9453_DVS_LEVEL_MAX 56*0959b670SJoy Zou }; 57*0959b670SJoy Zou 58*0959b670SJoy Zou #define PF9453_BUCK1_VOLTAGE_NUM 0x80 59*0959b670SJoy Zou #define PF9453_BUCK2_VOLTAGE_NUM 0x80 60*0959b670SJoy Zou #define PF9453_BUCK3_VOLTAGE_NUM 0x80 61*0959b670SJoy Zou #define PF9453_BUCK4_VOLTAGE_NUM 0x80 62*0959b670SJoy Zou 63*0959b670SJoy Zou #define PF9453_LDO1_VOLTAGE_NUM 0x65 64*0959b670SJoy Zou #define PF9453_LDO2_VOLTAGE_NUM 0x3b 65*0959b670SJoy Zou #define PF9453_LDOSNVS_VOLTAGE_NUM 0x59 66*0959b670SJoy Zou 67*0959b670SJoy Zou enum { 68*0959b670SJoy Zou PF9453_REG_DEV_ID = 0x00, 69*0959b670SJoy Zou PF9453_REG_OTP_VER = 0x01, 70*0959b670SJoy Zou PF9453_REG_INT1 = 0x02, 71*0959b670SJoy Zou PF9453_REG_INT1_MASK = 0x03, 72*0959b670SJoy Zou PF9453_REG_INT1_STATUS = 0x04, 73*0959b670SJoy Zou PF9453_REG_VRFLT1_INT = 0x05, 74*0959b670SJoy Zou PF9453_REG_VRFLT1_MASK = 0x06, 75*0959b670SJoy Zou PF9453_REG_PWRON_STAT = 0x07, 76*0959b670SJoy Zou PF9453_REG_RESET_CTRL = 0x08, 77*0959b670SJoy Zou PF9453_REG_SW_RST = 0x09, 78*0959b670SJoy Zou PF9453_REG_PWR_CTRL = 0x0a, 79*0959b670SJoy Zou PF9453_REG_CONFIG1 = 0x0b, 80*0959b670SJoy Zou PF9453_REG_CONFIG2 = 0x0c, 81*0959b670SJoy Zou PF9453_REG_32K_CONFIG = 0x0d, 82*0959b670SJoy Zou PF9453_REG_BUCK1CTRL = 0x10, 83*0959b670SJoy Zou PF9453_REG_BUCK1OUT = 0x11, 84*0959b670SJoy Zou PF9453_REG_BUCK2CTRL = 0x14, 85*0959b670SJoy Zou PF9453_REG_BUCK2OUT = 0x15, 86*0959b670SJoy Zou PF9453_REG_BUCK2OUT_STBY = 0x1d, 87*0959b670SJoy Zou PF9453_REG_BUCK2OUT_MAX_LIMIT = 0x1f, 88*0959b670SJoy Zou PF9453_REG_BUCK2OUT_MIN_LIMIT = 0x20, 89*0959b670SJoy Zou PF9453_REG_BUCK3CTRL = 0x21, 90*0959b670SJoy Zou PF9453_REG_BUCK3OUT = 0x22, 91*0959b670SJoy Zou PF9453_REG_BUCK4CTRL = 0x2e, 92*0959b670SJoy Zou PF9453_REG_BUCK4OUT = 0x2f, 93*0959b670SJoy Zou PF9453_REG_LDO1OUT_L = 0x36, 94*0959b670SJoy Zou PF9453_REG_LDO1CFG = 0x37, 95*0959b670SJoy Zou PF9453_REG_LDO1OUT_H = 0x38, 96*0959b670SJoy Zou PF9453_REG_LDOSNVS_CFG1 = 0x39, 97*0959b670SJoy Zou PF9453_REG_LDOSNVS_CFG2 = 0x3a, 98*0959b670SJoy Zou PF9453_REG_LDO2CFG = 0x3b, 99*0959b670SJoy Zou PF9453_REG_LDO2OUT = 0x3c, 100*0959b670SJoy Zou PF9453_REG_BUCK_POK = 0x3d, 101*0959b670SJoy Zou PF9453_REG_LSW_CTRL1 = 0x40, 102*0959b670SJoy Zou PF9453_REG_LSW_CTRL2 = 0x41, 103*0959b670SJoy Zou PF9453_REG_LOCK = 0x4e, 104*0959b670SJoy Zou PF9453_MAX_REG 105*0959b670SJoy Zou }; 106*0959b670SJoy Zou 107*0959b670SJoy Zou #define PF9453_UNLOCK_KEY 0x5c 108*0959b670SJoy Zou #define PF9453_LOCK_KEY 0x0 109*0959b670SJoy Zou 110*0959b670SJoy Zou /* PF9453 BUCK ENMODE bits */ 111*0959b670SJoy Zou #define BUCK_ENMODE_OFF 0x00 112*0959b670SJoy Zou #define BUCK_ENMODE_ONREQ 0x01 113*0959b670SJoy Zou #define BUCK_ENMODE_ONREQ_STBY 0x02 114*0959b670SJoy Zou #define BUCK_ENMODE_ONREQ_STBY_DPSTBY 0x03 115*0959b670SJoy Zou 116*0959b670SJoy Zou /* PF9453 BUCK ENMODE bits */ 117*0959b670SJoy Zou #define LDO_ENMODE_OFF 0x00 118*0959b670SJoy Zou #define LDO_ENMODE_ONREQ 0x01 119*0959b670SJoy Zou #define LDO_ENMODE_ONREQ_STBY 0x02 120*0959b670SJoy Zou #define LDO_ENMODE_ONREQ_STBY_DPSTBY 0x03 121*0959b670SJoy Zou 122*0959b670SJoy Zou /* PF9453_REG_BUCK1_CTRL bits */ 123*0959b670SJoy Zou #define BUCK1_LPMODE 0x30 124*0959b670SJoy Zou #define BUCK1_AD 0x08 125*0959b670SJoy Zou #define BUCK1_FPWM 0x04 126*0959b670SJoy Zou #define BUCK1_ENMODE_MASK GENMASK(1, 0) 127*0959b670SJoy Zou 128*0959b670SJoy Zou /* PF9453_REG_BUCK2_CTRL bits */ 129*0959b670SJoy Zou #define BUCK2_RAMP_MASK GENMASK(7, 6) 130*0959b670SJoy Zou #define BUCK2_RAMP_25MV 0x0 131*0959b670SJoy Zou #define BUCK2_RAMP_12P5MV 0x1 132*0959b670SJoy Zou #define BUCK2_RAMP_6P25MV 0x2 133*0959b670SJoy Zou #define BUCK2_RAMP_3P125MV 0x3 134*0959b670SJoy Zou #define BUCK2_LPMODE 0x30 135*0959b670SJoy Zou #define BUCK2_AD 0x08 136*0959b670SJoy Zou #define BUCK2_FPWM 0x04 137*0959b670SJoy Zou #define BUCK2_ENMODE_MASK GENMASK(1, 0) 138*0959b670SJoy Zou 139*0959b670SJoy Zou /* PF9453_REG_BUCK3_CTRL bits */ 140*0959b670SJoy Zou #define BUCK3_LPMODE 0x30 141*0959b670SJoy Zou #define BUCK3_AD 0x08 142*0959b670SJoy Zou #define BUCK3_FPWM 0x04 143*0959b670SJoy Zou #define BUCK3_ENMODE_MASK GENMASK(1, 0) 144*0959b670SJoy Zou 145*0959b670SJoy Zou /* PF9453_REG_BUCK4_CTRL bits */ 146*0959b670SJoy Zou #define BUCK4_LPMODE 0x30 147*0959b670SJoy Zou #define BUCK4_AD 0x08 148*0959b670SJoy Zou #define BUCK4_FPWM 0x04 149*0959b670SJoy Zou #define BUCK4_ENMODE_MASK GENMASK(1, 0) 150*0959b670SJoy Zou 151*0959b670SJoy Zou /* PF9453_REG_BUCK123_PRESET_EN bit */ 152*0959b670SJoy Zou #define BUCK123_PRESET_EN 0x80 153*0959b670SJoy Zou 154*0959b670SJoy Zou /* PF9453_BUCK1OUT bits */ 155*0959b670SJoy Zou #define BUCK1OUT_MASK GENMASK(6, 0) 156*0959b670SJoy Zou 157*0959b670SJoy Zou /* PF9453_BUCK2OUT bits */ 158*0959b670SJoy Zou #define BUCK2OUT_MASK GENMASK(6, 0) 159*0959b670SJoy Zou #define BUCK2OUT_STBY_MASK GENMASK(6, 0) 160*0959b670SJoy Zou 161*0959b670SJoy Zou /* PF9453_REG_BUCK3OUT bits */ 162*0959b670SJoy Zou #define BUCK3OUT_MASK GENMASK(6, 0) 163*0959b670SJoy Zou 164*0959b670SJoy Zou /* PF9453_REG_BUCK4OUT bits */ 165*0959b670SJoy Zou #define BUCK4OUT_MASK GENMASK(6, 0) 166*0959b670SJoy Zou 167*0959b670SJoy Zou /* PF9453_REG_LDO1_VOLT bits */ 168*0959b670SJoy Zou #define LDO1_EN_MASK GENMASK(1, 0) 169*0959b670SJoy Zou #define LDO1OUT_MASK GENMASK(6, 0) 170*0959b670SJoy Zou 171*0959b670SJoy Zou /* PF9453_REG_LDO2_VOLT bits */ 172*0959b670SJoy Zou #define LDO2_EN_MASK GENMASK(1, 0) 173*0959b670SJoy Zou #define LDO2OUT_MASK GENMASK(6, 0) 174*0959b670SJoy Zou 175*0959b670SJoy Zou /* PF9453_REG_LDOSNVS_VOLT bits */ 176*0959b670SJoy Zou #define LDOSNVS_EN_MASK GENMASK(0, 0) 177*0959b670SJoy Zou #define LDOSNVSCFG1_MASK GENMASK(6, 0) 178*0959b670SJoy Zou 179*0959b670SJoy Zou /* PF9453_REG_IRQ bits */ 180*0959b670SJoy Zou #define IRQ_RSVD 0x80 181*0959b670SJoy Zou #define IRQ_RSTB 0x40 182*0959b670SJoy Zou #define IRQ_ONKEY 0x20 183*0959b670SJoy Zou #define IRQ_RESETKEY 0x10 184*0959b670SJoy Zou #define IRQ_VR_FLT1 0x08 185*0959b670SJoy Zou #define IRQ_LOWVSYS 0x04 186*0959b670SJoy Zou #define IRQ_THERM_100 0x02 187*0959b670SJoy Zou #define IRQ_THERM_80 0x01 188*0959b670SJoy Zou 189*0959b670SJoy Zou /* PF9453_REG_RESET_CTRL bits */ 190*0959b670SJoy Zou #define WDOG_B_CFG_MASK GENMASK(7, 6) 191*0959b670SJoy Zou #define WDOG_B_CFG_NONE 0x00 192*0959b670SJoy Zou #define WDOG_B_CFG_WARM 0x40 193*0959b670SJoy Zou #define WDOG_B_CFG_COLD 0x80 194*0959b670SJoy Zou 195*0959b670SJoy Zou /* PF9453_REG_CONFIG2 bits */ 196*0959b670SJoy Zou #define I2C_LT_MASK GENMASK(1, 0) 197*0959b670SJoy Zou #define I2C_LT_FORCE_DISABLE 0x00 198*0959b670SJoy Zou #define I2C_LT_ON_STANDBY_RUN 0x01 199*0959b670SJoy Zou #define I2C_LT_ON_RUN 0x02 200*0959b670SJoy Zou #define I2C_LT_FORCE_ENABLE 0x03 201*0959b670SJoy Zou 202*0959b670SJoy Zou static const struct regmap_range pf9453_status_range = { 203*0959b670SJoy Zou .range_min = PF9453_REG_INT1, 204*0959b670SJoy Zou .range_max = PF9453_REG_PWRON_STAT, 205*0959b670SJoy Zou }; 206*0959b670SJoy Zou 207*0959b670SJoy Zou static const struct regmap_access_table pf9453_volatile_regs = { 208*0959b670SJoy Zou .yes_ranges = &pf9453_status_range, 209*0959b670SJoy Zou .n_yes_ranges = 1, 210*0959b670SJoy Zou }; 211*0959b670SJoy Zou 212*0959b670SJoy Zou static const struct regmap_config pf9453_regmap_config = { 213*0959b670SJoy Zou .reg_bits = 8, 214*0959b670SJoy Zou .val_bits = 8, 215*0959b670SJoy Zou .volatile_table = &pf9453_volatile_regs, 216*0959b670SJoy Zou .max_register = PF9453_MAX_REG - 1, 217*0959b670SJoy Zou .cache_type = REGCACHE_RBTREE, 218*0959b670SJoy Zou }; 219*0959b670SJoy Zou 220*0959b670SJoy Zou /* 221*0959b670SJoy Zou * BUCK2 222*0959b670SJoy Zou * BUCK2RAM[1:0] BUCK2 DVS ramp rate setting 223*0959b670SJoy Zou * 00: 25mV/1usec 224*0959b670SJoy Zou * 01: 25mV/2usec 225*0959b670SJoy Zou * 10: 25mV/4usec 226*0959b670SJoy Zou * 11: 25mV/8usec 227*0959b670SJoy Zou */ 228*0959b670SJoy Zou static const unsigned int pf9453_dvs_buck_ramp_table[] = { 229*0959b670SJoy Zou 25000, 12500, 6250, 3125 230*0959b670SJoy Zou }; 231*0959b670SJoy Zou 232*0959b670SJoy Zou static bool is_reg_protect(uint reg) 233*0959b670SJoy Zou { 234*0959b670SJoy Zou switch (reg) { 235*0959b670SJoy Zou case PF9453_REG_BUCK1OUT: 236*0959b670SJoy Zou case PF9453_REG_BUCK2OUT: 237*0959b670SJoy Zou case PF9453_REG_BUCK3OUT: 238*0959b670SJoy Zou case PF9453_REG_BUCK4OUT: 239*0959b670SJoy Zou case PF9453_REG_LDO1OUT_L: 240*0959b670SJoy Zou case PF9453_REG_LDO1OUT_H: 241*0959b670SJoy Zou case PF9453_REG_LDO2OUT: 242*0959b670SJoy Zou case PF9453_REG_LDOSNVS_CFG1: 243*0959b670SJoy Zou case PF9453_REG_BUCK2OUT_MAX_LIMIT: 244*0959b670SJoy Zou case PF9453_REG_BUCK2OUT_MIN_LIMIT: 245*0959b670SJoy Zou return true; 246*0959b670SJoy Zou default: 247*0959b670SJoy Zou return false; 248*0959b670SJoy Zou } 249*0959b670SJoy Zou } 250*0959b670SJoy Zou 251*0959b670SJoy Zou static int pf9453_pmic_write(struct pf9453 *pf9453, unsigned int reg, u8 mask, unsigned int val) 252*0959b670SJoy Zou { 253*0959b670SJoy Zou int ret = -EINVAL; 254*0959b670SJoy Zou u8 data, key; 255*0959b670SJoy Zou u32 rxBuf; 256*0959b670SJoy Zou 257*0959b670SJoy Zou /* If not updating entire register, perform a read-mod-write */ 258*0959b670SJoy Zou data = val; 259*0959b670SJoy Zou key = PF9453_UNLOCK_KEY; 260*0959b670SJoy Zou 261*0959b670SJoy Zou if (mask != 0xffU) { 262*0959b670SJoy Zou /* Read data */ 263*0959b670SJoy Zou ret = regmap_read(pf9453->regmap, reg, &rxBuf); 264*0959b670SJoy Zou if (ret) { 265*0959b670SJoy Zou dev_err(pf9453->dev, "Read reg=%0x error!\n", reg); 266*0959b670SJoy Zou return ret; 267*0959b670SJoy Zou } 268*0959b670SJoy Zou data = (val & mask) | (rxBuf & (~mask)); 269*0959b670SJoy Zou } 270*0959b670SJoy Zou 271*0959b670SJoy Zou if (reg < PF9453_MAX_REG) { 272*0959b670SJoy Zou if (is_reg_protect(reg)) { 273*0959b670SJoy Zou ret = regmap_raw_write(pf9453->regmap, PF9453_REG_LOCK, &key, 1U); 274*0959b670SJoy Zou if (ret) { 275*0959b670SJoy Zou dev_err(pf9453->dev, "Write reg=%0x error!\n", reg); 276*0959b670SJoy Zou return ret; 277*0959b670SJoy Zou } 278*0959b670SJoy Zou 279*0959b670SJoy Zou ret = regmap_raw_write(pf9453->regmap, reg, &data, 1U); 280*0959b670SJoy Zou if (ret) { 281*0959b670SJoy Zou dev_err(pf9453->dev, "Write reg=%0x error!\n", reg); 282*0959b670SJoy Zou return ret; 283*0959b670SJoy Zou } 284*0959b670SJoy Zou 285*0959b670SJoy Zou key = PF9453_LOCK_KEY; 286*0959b670SJoy Zou ret = regmap_raw_write(pf9453->regmap, PF9453_REG_LOCK, &key, 1U); 287*0959b670SJoy Zou if (ret) { 288*0959b670SJoy Zou dev_err(pf9453->dev, "Write reg=%0x error!\n", reg); 289*0959b670SJoy Zou return ret; 290*0959b670SJoy Zou } 291*0959b670SJoy Zou } else { 292*0959b670SJoy Zou ret = regmap_raw_write(pf9453->regmap, reg, &data, 1U); 293*0959b670SJoy Zou if (ret) { 294*0959b670SJoy Zou dev_err(pf9453->dev, "Write reg=%0x error!\n", reg); 295*0959b670SJoy Zou return ret; 296*0959b670SJoy Zou } 297*0959b670SJoy Zou } 298*0959b670SJoy Zou } 299*0959b670SJoy Zou 300*0959b670SJoy Zou return ret; 301*0959b670SJoy Zou } 302*0959b670SJoy Zou 303*0959b670SJoy Zou /** 304*0959b670SJoy Zou * pf9453_regulator_enable_regmap for regmap users 305*0959b670SJoy Zou * 306*0959b670SJoy Zou * @rdev: regulator to operate on 307*0959b670SJoy Zou * 308*0959b670SJoy Zou * Regulators that use regmap for their register I/O can set the 309*0959b670SJoy Zou * enable_reg and enable_mask fields in their descriptor and then use 310*0959b670SJoy Zou * this as their enable() operation, saving some code. 311*0959b670SJoy Zou */ 312*0959b670SJoy Zou static int pf9453_regulator_enable_regmap(struct regulator_dev *rdev) 313*0959b670SJoy Zou { 314*0959b670SJoy Zou struct pf9453 *pf9453 = dev_get_drvdata(rdev->dev.parent); 315*0959b670SJoy Zou unsigned int val; 316*0959b670SJoy Zou 317*0959b670SJoy Zou if (rdev->desc->enable_is_inverted) { 318*0959b670SJoy Zou val = rdev->desc->disable_val; 319*0959b670SJoy Zou } else { 320*0959b670SJoy Zou val = rdev->desc->enable_val; 321*0959b670SJoy Zou if (!val) 322*0959b670SJoy Zou val = rdev->desc->enable_mask; 323*0959b670SJoy Zou } 324*0959b670SJoy Zou 325*0959b670SJoy Zou return pf9453_pmic_write(pf9453, rdev->desc->enable_reg, rdev->desc->enable_mask, val); 326*0959b670SJoy Zou } 327*0959b670SJoy Zou 328*0959b670SJoy Zou /** 329*0959b670SJoy Zou * pf9453_regulator_disable_regmap for regmap users 330*0959b670SJoy Zou * 331*0959b670SJoy Zou * @rdev: regulator to operate on 332*0959b670SJoy Zou * 333*0959b670SJoy Zou * Regulators that use regmap for their register I/O can set the 334*0959b670SJoy Zou * enable_reg and enable_mask fields in their descriptor and then use 335*0959b670SJoy Zou * this as their disable() operation, saving some code. 336*0959b670SJoy Zou */ 337*0959b670SJoy Zou static int pf9453_regulator_disable_regmap(struct regulator_dev *rdev) 338*0959b670SJoy Zou { 339*0959b670SJoy Zou struct pf9453 *pf9453 = dev_get_drvdata(rdev->dev.parent); 340*0959b670SJoy Zou unsigned int val; 341*0959b670SJoy Zou 342*0959b670SJoy Zou if (rdev->desc->enable_is_inverted) { 343*0959b670SJoy Zou val = rdev->desc->enable_val; 344*0959b670SJoy Zou if (!val) 345*0959b670SJoy Zou val = rdev->desc->enable_mask; 346*0959b670SJoy Zou } else { 347*0959b670SJoy Zou val = rdev->desc->disable_val; 348*0959b670SJoy Zou } 349*0959b670SJoy Zou 350*0959b670SJoy Zou return pf9453_pmic_write(pf9453, rdev->desc->enable_reg, rdev->desc->enable_mask, val); 351*0959b670SJoy Zou } 352*0959b670SJoy Zou 353*0959b670SJoy Zou /** 354*0959b670SJoy Zou * pf9453_regulator_set_voltage_sel_regmap for regmap users 355*0959b670SJoy Zou * 356*0959b670SJoy Zou * @rdev: regulator to operate on 357*0959b670SJoy Zou * @sel: Selector to set 358*0959b670SJoy Zou * 359*0959b670SJoy Zou * Regulators that use regmap for their register I/O can set the 360*0959b670SJoy Zou * vsel_reg and vsel_mask fields in their descriptor and then use this 361*0959b670SJoy Zou * as their set_voltage_vsel operation, saving some code. 362*0959b670SJoy Zou */ 363*0959b670SJoy Zou static int pf9453_regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned int sel) 364*0959b670SJoy Zou { 365*0959b670SJoy Zou struct pf9453 *pf9453 = dev_get_drvdata(rdev->dev.parent); 366*0959b670SJoy Zou int ret; 367*0959b670SJoy Zou 368*0959b670SJoy Zou sel <<= ffs(rdev->desc->vsel_mask) - 1; 369*0959b670SJoy Zou ret = pf9453_pmic_write(pf9453, rdev->desc->vsel_reg, rdev->desc->vsel_mask, sel); 370*0959b670SJoy Zou if (ret) 371*0959b670SJoy Zou return ret; 372*0959b670SJoy Zou 373*0959b670SJoy Zou if (rdev->desc->apply_bit) 374*0959b670SJoy Zou ret = pf9453_pmic_write(pf9453, rdev->desc->apply_reg, 375*0959b670SJoy Zou rdev->desc->apply_bit, rdev->desc->apply_bit); 376*0959b670SJoy Zou return ret; 377*0959b670SJoy Zou } 378*0959b670SJoy Zou 379*0959b670SJoy Zou static int find_closest_bigger(unsigned int target, const unsigned int *table, 380*0959b670SJoy Zou unsigned int num_sel, unsigned int *sel) 381*0959b670SJoy Zou { 382*0959b670SJoy Zou unsigned int s, tmp, max, maxsel = 0; 383*0959b670SJoy Zou bool found = false; 384*0959b670SJoy Zou 385*0959b670SJoy Zou max = table[0]; 386*0959b670SJoy Zou 387*0959b670SJoy Zou for (s = 0; s < num_sel; s++) { 388*0959b670SJoy Zou if (table[s] > max) { 389*0959b670SJoy Zou max = table[s]; 390*0959b670SJoy Zou maxsel = s; 391*0959b670SJoy Zou } 392*0959b670SJoy Zou if (table[s] >= target) { 393*0959b670SJoy Zou if (!found || table[s] - target < tmp - target) { 394*0959b670SJoy Zou tmp = table[s]; 395*0959b670SJoy Zou *sel = s; 396*0959b670SJoy Zou found = true; 397*0959b670SJoy Zou if (tmp == target) 398*0959b670SJoy Zou break; 399*0959b670SJoy Zou } 400*0959b670SJoy Zou } 401*0959b670SJoy Zou } 402*0959b670SJoy Zou 403*0959b670SJoy Zou if (!found) { 404*0959b670SJoy Zou *sel = maxsel; 405*0959b670SJoy Zou return -EINVAL; 406*0959b670SJoy Zou } 407*0959b670SJoy Zou 408*0959b670SJoy Zou return 0; 409*0959b670SJoy Zou } 410*0959b670SJoy Zou 411*0959b670SJoy Zou /** 412*0959b670SJoy Zou * pf9453_regulator_set_ramp_delay_regmap 413*0959b670SJoy Zou * 414*0959b670SJoy Zou * @rdev: regulator to operate on 415*0959b670SJoy Zou * 416*0959b670SJoy Zou * Regulators that use regmap for their register I/O can set the ramp_reg 417*0959b670SJoy Zou * and ramp_mask fields in their descriptor and then use this as their 418*0959b670SJoy Zou * set_ramp_delay operation, saving some code. 419*0959b670SJoy Zou */ 420*0959b670SJoy Zou static int pf9453_regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay) 421*0959b670SJoy Zou { 422*0959b670SJoy Zou struct pf9453 *pf9453 = dev_get_drvdata(rdev->dev.parent); 423*0959b670SJoy Zou unsigned int sel; 424*0959b670SJoy Zou int ret; 425*0959b670SJoy Zou 426*0959b670SJoy Zou if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table)) 427*0959b670SJoy Zou return -EINVAL; 428*0959b670SJoy Zou 429*0959b670SJoy Zou ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table, 430*0959b670SJoy Zou rdev->desc->n_ramp_values, &sel); 431*0959b670SJoy Zou 432*0959b670SJoy Zou if (ret) { 433*0959b670SJoy Zou dev_warn(rdev_get_dev(rdev), 434*0959b670SJoy Zou "Can't set ramp-delay %u, setting %u\n", ramp_delay, 435*0959b670SJoy Zou rdev->desc->ramp_delay_table[sel]); 436*0959b670SJoy Zou } 437*0959b670SJoy Zou 438*0959b670SJoy Zou sel <<= ffs(rdev->desc->ramp_mask) - 1; 439*0959b670SJoy Zou 440*0959b670SJoy Zou return pf9453_pmic_write(pf9453, rdev->desc->ramp_reg, 441*0959b670SJoy Zou rdev->desc->ramp_mask, sel); 442*0959b670SJoy Zou } 443*0959b670SJoy Zou 444*0959b670SJoy Zou static const struct regulator_ops pf9453_dvs_buck_regulator_ops = { 445*0959b670SJoy Zou .enable = pf9453_regulator_enable_regmap, 446*0959b670SJoy Zou .disable = pf9453_regulator_disable_regmap, 447*0959b670SJoy Zou .is_enabled = regulator_is_enabled_regmap, 448*0959b670SJoy Zou .list_voltage = regulator_list_voltage_linear_range, 449*0959b670SJoy Zou .set_voltage_sel = pf9453_regulator_set_voltage_sel_regmap, 450*0959b670SJoy Zou .get_voltage_sel = regulator_get_voltage_sel_regmap, 451*0959b670SJoy Zou .set_voltage_time_sel = regulator_set_voltage_time_sel, 452*0959b670SJoy Zou .set_ramp_delay = pf9453_regulator_set_ramp_delay_regmap, 453*0959b670SJoy Zou }; 454*0959b670SJoy Zou 455*0959b670SJoy Zou static const struct regulator_ops pf9453_buck_regulator_ops = { 456*0959b670SJoy Zou .enable = pf9453_regulator_enable_regmap, 457*0959b670SJoy Zou .disable = pf9453_regulator_disable_regmap, 458*0959b670SJoy Zou .is_enabled = regulator_is_enabled_regmap, 459*0959b670SJoy Zou .list_voltage = regulator_list_voltage_linear_range, 460*0959b670SJoy Zou .set_voltage_sel = pf9453_regulator_set_voltage_sel_regmap, 461*0959b670SJoy Zou .get_voltage_sel = regulator_get_voltage_sel_regmap, 462*0959b670SJoy Zou .set_voltage_time_sel = regulator_set_voltage_time_sel, 463*0959b670SJoy Zou }; 464*0959b670SJoy Zou 465*0959b670SJoy Zou static const struct regulator_ops pf9453_ldo_regulator_ops = { 466*0959b670SJoy Zou .enable = pf9453_regulator_enable_regmap, 467*0959b670SJoy Zou .disable = pf9453_regulator_disable_regmap, 468*0959b670SJoy Zou .is_enabled = regulator_is_enabled_regmap, 469*0959b670SJoy Zou .list_voltage = regulator_list_voltage_linear_range, 470*0959b670SJoy Zou .set_voltage_sel = pf9453_regulator_set_voltage_sel_regmap, 471*0959b670SJoy Zou .get_voltage_sel = regulator_get_voltage_sel_regmap, 472*0959b670SJoy Zou }; 473*0959b670SJoy Zou 474*0959b670SJoy Zou /* 475*0959b670SJoy Zou * BUCK1/3/4 476*0959b670SJoy Zou * 0.60 to 3.775V (25mV step) 477*0959b670SJoy Zou */ 478*0959b670SJoy Zou static const struct linear_range pf9453_buck134_volts[] = { 479*0959b670SJoy Zou REGULATOR_LINEAR_RANGE(600000, 0x00, 0x7F, 25000), 480*0959b670SJoy Zou }; 481*0959b670SJoy Zou 482*0959b670SJoy Zou /* 483*0959b670SJoy Zou * BUCK2 484*0959b670SJoy Zou * 0.60 to 2.1875V (12.5mV step) 485*0959b670SJoy Zou */ 486*0959b670SJoy Zou static const struct linear_range pf9453_buck2_volts[] = { 487*0959b670SJoy Zou REGULATOR_LINEAR_RANGE(600000, 0x00, 0x7F, 12500), 488*0959b670SJoy Zou }; 489*0959b670SJoy Zou 490*0959b670SJoy Zou /* 491*0959b670SJoy Zou * LDO1 492*0959b670SJoy Zou * 0.8 to 3.3V (25mV step) 493*0959b670SJoy Zou */ 494*0959b670SJoy Zou static const struct linear_range pf9453_ldo1_volts[] = { 495*0959b670SJoy Zou REGULATOR_LINEAR_RANGE(800000, 0x00, 0x64, 25000), 496*0959b670SJoy Zou }; 497*0959b670SJoy Zou 498*0959b670SJoy Zou /* 499*0959b670SJoy Zou * LDO2 500*0959b670SJoy Zou * 0.5 to 1.95V (25mV step) 501*0959b670SJoy Zou */ 502*0959b670SJoy Zou static const struct linear_range pf9453_ldo2_volts[] = { 503*0959b670SJoy Zou REGULATOR_LINEAR_RANGE(500000, 0x00, 0x3A, 25000), 504*0959b670SJoy Zou }; 505*0959b670SJoy Zou 506*0959b670SJoy Zou /* 507*0959b670SJoy Zou * LDOSNVS 508*0959b670SJoy Zou * 1.2 to 3.4V (25mV step) 509*0959b670SJoy Zou */ 510*0959b670SJoy Zou static const struct linear_range pf9453_ldosnvs_volts[] = { 511*0959b670SJoy Zou REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x58, 25000), 512*0959b670SJoy Zou }; 513*0959b670SJoy Zou 514*0959b670SJoy Zou static int buck_set_dvs(const struct regulator_desc *desc, 515*0959b670SJoy Zou struct device_node *np, struct pf9453 *pf9453, 516*0959b670SJoy Zou char *prop, unsigned int reg, unsigned int mask) 517*0959b670SJoy Zou { 518*0959b670SJoy Zou int ret, i; 519*0959b670SJoy Zou u32 uv; 520*0959b670SJoy Zou 521*0959b670SJoy Zou ret = of_property_read_u32(np, prop, &uv); 522*0959b670SJoy Zou if (ret == -EINVAL) 523*0959b670SJoy Zou return 0; 524*0959b670SJoy Zou else if (ret) 525*0959b670SJoy Zou return ret; 526*0959b670SJoy Zou 527*0959b670SJoy Zou for (i = 0; i < desc->n_voltages; i++) { 528*0959b670SJoy Zou ret = regulator_desc_list_voltage_linear_range(desc, i); 529*0959b670SJoy Zou if (ret < 0) 530*0959b670SJoy Zou continue; 531*0959b670SJoy Zou if (ret == uv) { 532*0959b670SJoy Zou i <<= ffs(desc->vsel_mask) - 1; 533*0959b670SJoy Zou ret = pf9453_pmic_write(pf9453, reg, mask, i); 534*0959b670SJoy Zou break; 535*0959b670SJoy Zou } 536*0959b670SJoy Zou } 537*0959b670SJoy Zou 538*0959b670SJoy Zou if (ret == 0) { 539*0959b670SJoy Zou struct pf9453_regulator_desc *regulator = container_of(desc, 540*0959b670SJoy Zou struct pf9453_regulator_desc, desc); 541*0959b670SJoy Zou 542*0959b670SJoy Zou /* Enable DVS control through PMIC_STBY_REQ for this BUCK */ 543*0959b670SJoy Zou ret = pf9453_pmic_write(pf9453, regulator->desc.enable_reg, 544*0959b670SJoy Zou BUCK2_LPMODE, BUCK2_LPMODE); 545*0959b670SJoy Zou } 546*0959b670SJoy Zou return ret; 547*0959b670SJoy Zou } 548*0959b670SJoy Zou 549*0959b670SJoy Zou static int pf9453_set_dvs_levels(struct device_node *np, const struct regulator_desc *desc, 550*0959b670SJoy Zou struct regulator_config *cfg) 551*0959b670SJoy Zou { 552*0959b670SJoy Zou struct pf9453_regulator_desc *data = container_of(desc, struct pf9453_regulator_desc, desc); 553*0959b670SJoy Zou struct pf9453 *pf9453 = dev_get_drvdata(cfg->dev); 554*0959b670SJoy Zou const struct pf9453_dvs_config *dvs = &data->dvs; 555*0959b670SJoy Zou unsigned int reg, mask; 556*0959b670SJoy Zou int i, ret = 0; 557*0959b670SJoy Zou char *prop; 558*0959b670SJoy Zou 559*0959b670SJoy Zou for (i = 0; i < PF9453_DVS_LEVEL_MAX; i++) { 560*0959b670SJoy Zou switch (i) { 561*0959b670SJoy Zou case PF9453_DVS_LEVEL_RUN: 562*0959b670SJoy Zou prop = "nxp,dvs-run-voltage"; 563*0959b670SJoy Zou reg = dvs->run_reg; 564*0959b670SJoy Zou mask = dvs->run_mask; 565*0959b670SJoy Zou break; 566*0959b670SJoy Zou case PF9453_DVS_LEVEL_DPSTANDBY: 567*0959b670SJoy Zou case PF9453_DVS_LEVEL_STANDBY: 568*0959b670SJoy Zou prop = "nxp,dvs-standby-voltage"; 569*0959b670SJoy Zou reg = dvs->standby_reg; 570*0959b670SJoy Zou mask = dvs->standby_mask; 571*0959b670SJoy Zou break; 572*0959b670SJoy Zou default: 573*0959b670SJoy Zou return -EINVAL; 574*0959b670SJoy Zou } 575*0959b670SJoy Zou 576*0959b670SJoy Zou ret = buck_set_dvs(desc, np, pf9453, prop, reg, mask); 577*0959b670SJoy Zou if (ret) 578*0959b670SJoy Zou break; 579*0959b670SJoy Zou } 580*0959b670SJoy Zou 581*0959b670SJoy Zou return ret; 582*0959b670SJoy Zou } 583*0959b670SJoy Zou 584*0959b670SJoy Zou static const struct pf9453_regulator_desc pf9453_regulators[] = { 585*0959b670SJoy Zou { 586*0959b670SJoy Zou .desc = { 587*0959b670SJoy Zou .name = "buck1", 588*0959b670SJoy Zou .of_match = of_match_ptr("BUCK1"), 589*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 590*0959b670SJoy Zou .id = PF9453_BUCK1, 591*0959b670SJoy Zou .ops = &pf9453_buck_regulator_ops, 592*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 593*0959b670SJoy Zou .n_voltages = PF9453_BUCK1_VOLTAGE_NUM, 594*0959b670SJoy Zou .linear_ranges = pf9453_buck134_volts, 595*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_buck134_volts), 596*0959b670SJoy Zou .vsel_reg = PF9453_REG_BUCK1OUT, 597*0959b670SJoy Zou .vsel_mask = BUCK1OUT_MASK, 598*0959b670SJoy Zou .enable_reg = PF9453_REG_BUCK1CTRL, 599*0959b670SJoy Zou .enable_mask = BUCK1_ENMODE_MASK, 600*0959b670SJoy Zou .enable_val = BUCK_ENMODE_ONREQ, 601*0959b670SJoy Zou .owner = THIS_MODULE, 602*0959b670SJoy Zou }, 603*0959b670SJoy Zou }, 604*0959b670SJoy Zou { 605*0959b670SJoy Zou .desc = { 606*0959b670SJoy Zou .name = "buck2", 607*0959b670SJoy Zou .of_match = of_match_ptr("BUCK2"), 608*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 609*0959b670SJoy Zou .id = PF9453_BUCK2, 610*0959b670SJoy Zou .ops = &pf9453_dvs_buck_regulator_ops, 611*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 612*0959b670SJoy Zou .n_voltages = PF9453_BUCK2_VOLTAGE_NUM, 613*0959b670SJoy Zou .linear_ranges = pf9453_buck2_volts, 614*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_buck2_volts), 615*0959b670SJoy Zou .vsel_reg = PF9453_REG_BUCK2OUT, 616*0959b670SJoy Zou .vsel_mask = BUCK2OUT_MASK, 617*0959b670SJoy Zou .enable_reg = PF9453_REG_BUCK2CTRL, 618*0959b670SJoy Zou .enable_mask = BUCK2_ENMODE_MASK, 619*0959b670SJoy Zou .enable_val = BUCK_ENMODE_ONREQ, 620*0959b670SJoy Zou .ramp_reg = PF9453_REG_BUCK2CTRL, 621*0959b670SJoy Zou .ramp_mask = BUCK2_RAMP_MASK, 622*0959b670SJoy Zou .ramp_delay_table = pf9453_dvs_buck_ramp_table, 623*0959b670SJoy Zou .n_ramp_values = ARRAY_SIZE(pf9453_dvs_buck_ramp_table), 624*0959b670SJoy Zou .owner = THIS_MODULE, 625*0959b670SJoy Zou .of_parse_cb = pf9453_set_dvs_levels, 626*0959b670SJoy Zou }, 627*0959b670SJoy Zou .dvs = { 628*0959b670SJoy Zou .run_reg = PF9453_REG_BUCK2OUT, 629*0959b670SJoy Zou .run_mask = BUCK2OUT_MASK, 630*0959b670SJoy Zou .standby_reg = PF9453_REG_BUCK2OUT_STBY, 631*0959b670SJoy Zou .standby_mask = BUCK2OUT_STBY_MASK, 632*0959b670SJoy Zou }, 633*0959b670SJoy Zou }, 634*0959b670SJoy Zou { 635*0959b670SJoy Zou .desc = { 636*0959b670SJoy Zou .name = "buck3", 637*0959b670SJoy Zou .of_match = of_match_ptr("BUCK3"), 638*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 639*0959b670SJoy Zou .id = PF9453_BUCK3, 640*0959b670SJoy Zou .ops = &pf9453_buck_regulator_ops, 641*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 642*0959b670SJoy Zou .n_voltages = PF9453_BUCK3_VOLTAGE_NUM, 643*0959b670SJoy Zou .linear_ranges = pf9453_buck134_volts, 644*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_buck134_volts), 645*0959b670SJoy Zou .vsel_reg = PF9453_REG_BUCK3OUT, 646*0959b670SJoy Zou .vsel_mask = BUCK3OUT_MASK, 647*0959b670SJoy Zou .enable_reg = PF9453_REG_BUCK3CTRL, 648*0959b670SJoy Zou .enable_mask = BUCK3_ENMODE_MASK, 649*0959b670SJoy Zou .enable_val = BUCK_ENMODE_ONREQ, 650*0959b670SJoy Zou .owner = THIS_MODULE, 651*0959b670SJoy Zou }, 652*0959b670SJoy Zou }, 653*0959b670SJoy Zou { 654*0959b670SJoy Zou .desc = { 655*0959b670SJoy Zou .name = "buck4", 656*0959b670SJoy Zou .of_match = of_match_ptr("BUCK4"), 657*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 658*0959b670SJoy Zou .id = PF9453_BUCK4, 659*0959b670SJoy Zou .ops = &pf9453_buck_regulator_ops, 660*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 661*0959b670SJoy Zou .n_voltages = PF9453_BUCK4_VOLTAGE_NUM, 662*0959b670SJoy Zou .linear_ranges = pf9453_buck134_volts, 663*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_buck134_volts), 664*0959b670SJoy Zou .vsel_reg = PF9453_REG_BUCK4OUT, 665*0959b670SJoy Zou .vsel_mask = BUCK4OUT_MASK, 666*0959b670SJoy Zou .enable_reg = PF9453_REG_BUCK4CTRL, 667*0959b670SJoy Zou .enable_mask = BUCK4_ENMODE_MASK, 668*0959b670SJoy Zou .enable_val = BUCK_ENMODE_ONREQ, 669*0959b670SJoy Zou .owner = THIS_MODULE, 670*0959b670SJoy Zou }, 671*0959b670SJoy Zou }, 672*0959b670SJoy Zou { 673*0959b670SJoy Zou .desc = { 674*0959b670SJoy Zou .name = "ldo1", 675*0959b670SJoy Zou .of_match = of_match_ptr("LDO1"), 676*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 677*0959b670SJoy Zou .id = PF9453_LDO1, 678*0959b670SJoy Zou .ops = &pf9453_ldo_regulator_ops, 679*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 680*0959b670SJoy Zou .n_voltages = PF9453_LDO1_VOLTAGE_NUM, 681*0959b670SJoy Zou .linear_ranges = pf9453_ldo1_volts, 682*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_ldo1_volts), 683*0959b670SJoy Zou .vsel_reg = PF9453_REG_LDO1OUT_H, 684*0959b670SJoy Zou .vsel_mask = LDO1OUT_MASK, 685*0959b670SJoy Zou .enable_reg = PF9453_REG_LDO1CFG, 686*0959b670SJoy Zou .enable_mask = LDO1_EN_MASK, 687*0959b670SJoy Zou .enable_val = LDO_ENMODE_ONREQ, 688*0959b670SJoy Zou .owner = THIS_MODULE, 689*0959b670SJoy Zou }, 690*0959b670SJoy Zou }, 691*0959b670SJoy Zou { 692*0959b670SJoy Zou .desc = { 693*0959b670SJoy Zou .name = "ldo2", 694*0959b670SJoy Zou .of_match = of_match_ptr("LDO2"), 695*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 696*0959b670SJoy Zou .id = PF9453_LDO2, 697*0959b670SJoy Zou .ops = &pf9453_ldo_regulator_ops, 698*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 699*0959b670SJoy Zou .n_voltages = PF9453_LDO2_VOLTAGE_NUM, 700*0959b670SJoy Zou .linear_ranges = pf9453_ldo2_volts, 701*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_ldo2_volts), 702*0959b670SJoy Zou .vsel_reg = PF9453_REG_LDO2OUT, 703*0959b670SJoy Zou .vsel_mask = LDO2OUT_MASK, 704*0959b670SJoy Zou .enable_reg = PF9453_REG_LDO2CFG, 705*0959b670SJoy Zou .enable_mask = LDO2_EN_MASK, 706*0959b670SJoy Zou .enable_val = LDO_ENMODE_ONREQ, 707*0959b670SJoy Zou .owner = THIS_MODULE, 708*0959b670SJoy Zou }, 709*0959b670SJoy Zou }, 710*0959b670SJoy Zou { 711*0959b670SJoy Zou .desc = { 712*0959b670SJoy Zou .name = "ldosnvs", 713*0959b670SJoy Zou .of_match = of_match_ptr("LDO-SNVS"), 714*0959b670SJoy Zou .regulators_node = of_match_ptr("regulators"), 715*0959b670SJoy Zou .id = PF9453_LDOSNVS, 716*0959b670SJoy Zou .ops = &pf9453_ldo_regulator_ops, 717*0959b670SJoy Zou .type = REGULATOR_VOLTAGE, 718*0959b670SJoy Zou .n_voltages = PF9453_LDOSNVS_VOLTAGE_NUM, 719*0959b670SJoy Zou .linear_ranges = pf9453_ldosnvs_volts, 720*0959b670SJoy Zou .n_linear_ranges = ARRAY_SIZE(pf9453_ldosnvs_volts), 721*0959b670SJoy Zou .vsel_reg = PF9453_REG_LDOSNVS_CFG1, 722*0959b670SJoy Zou .vsel_mask = LDOSNVSCFG1_MASK, 723*0959b670SJoy Zou .enable_reg = PF9453_REG_LDOSNVS_CFG2, 724*0959b670SJoy Zou .enable_mask = LDOSNVS_EN_MASK, 725*0959b670SJoy Zou .owner = THIS_MODULE, 726*0959b670SJoy Zou }, 727*0959b670SJoy Zou }, 728*0959b670SJoy Zou { } 729*0959b670SJoy Zou }; 730*0959b670SJoy Zou 731*0959b670SJoy Zou static irqreturn_t pf9453_irq_handler(int irq, void *data) 732*0959b670SJoy Zou { 733*0959b670SJoy Zou struct pf9453 *pf9453 = data; 734*0959b670SJoy Zou struct regmap *regmap = pf9453->regmap; 735*0959b670SJoy Zou unsigned int status; 736*0959b670SJoy Zou int ret; 737*0959b670SJoy Zou 738*0959b670SJoy Zou ret = regmap_read(regmap, PF9453_REG_INT1, &status); 739*0959b670SJoy Zou if (ret < 0) { 740*0959b670SJoy Zou dev_err(pf9453->dev, "Failed to read INT1(%d)\n", ret); 741*0959b670SJoy Zou return IRQ_NONE; 742*0959b670SJoy Zou } 743*0959b670SJoy Zou 744*0959b670SJoy Zou if (status & IRQ_RSTB) 745*0959b670SJoy Zou dev_warn(pf9453->dev, "IRQ_RSTB interrupt.\n"); 746*0959b670SJoy Zou 747*0959b670SJoy Zou if (status & IRQ_ONKEY) 748*0959b670SJoy Zou dev_warn(pf9453->dev, "IRQ_ONKEY interrupt.\n"); 749*0959b670SJoy Zou 750*0959b670SJoy Zou if (status & IRQ_VR_FLT1) 751*0959b670SJoy Zou dev_warn(pf9453->dev, "VRFLT1 interrupt.\n"); 752*0959b670SJoy Zou 753*0959b670SJoy Zou if (status & IRQ_RESETKEY) 754*0959b670SJoy Zou dev_warn(pf9453->dev, "IRQ_RESETKEY interrupt.\n"); 755*0959b670SJoy Zou 756*0959b670SJoy Zou if (status & IRQ_LOWVSYS) 757*0959b670SJoy Zou dev_warn(pf9453->dev, "LOWVSYS interrupt.\n"); 758*0959b670SJoy Zou 759*0959b670SJoy Zou if (status & IRQ_THERM_100) 760*0959b670SJoy Zou dev_warn(pf9453->dev, "IRQ_THERM_100 interrupt.\n"); 761*0959b670SJoy Zou 762*0959b670SJoy Zou if (status & IRQ_THERM_80) 763*0959b670SJoy Zou dev_warn(pf9453->dev, "IRQ_THERM_80 interrupt.\n"); 764*0959b670SJoy Zou 765*0959b670SJoy Zou return IRQ_HANDLED; 766*0959b670SJoy Zou } 767*0959b670SJoy Zou 768*0959b670SJoy Zou static int pf9453_i2c_probe(struct i2c_client *i2c) 769*0959b670SJoy Zou { 770*0959b670SJoy Zou const struct pf9453_regulator_desc *regulator_desc = of_device_get_match_data(&i2c->dev); 771*0959b670SJoy Zou struct regulator_config config = { }; 772*0959b670SJoy Zou unsigned int reset_ctrl; 773*0959b670SJoy Zou unsigned int device_id; 774*0959b670SJoy Zou struct pf9453 *pf9453; 775*0959b670SJoy Zou int ret; 776*0959b670SJoy Zou 777*0959b670SJoy Zou if (!i2c->irq) 778*0959b670SJoy Zou return dev_err_probe(&i2c->dev, -EINVAL, "No IRQ configured?\n"); 779*0959b670SJoy Zou 780*0959b670SJoy Zou pf9453 = devm_kzalloc(&i2c->dev, sizeof(struct pf9453), GFP_KERNEL); 781*0959b670SJoy Zou if (!pf9453) 782*0959b670SJoy Zou return -ENOMEM; 783*0959b670SJoy Zou 784*0959b670SJoy Zou pf9453->regmap = devm_regmap_init_i2c(i2c, &pf9453_regmap_config); 785*0959b670SJoy Zou if (IS_ERR(pf9453->regmap)) 786*0959b670SJoy Zou return dev_err_probe(&i2c->dev, PTR_ERR(pf9453->regmap), 787*0959b670SJoy Zou "regmap initialization failed\n"); 788*0959b670SJoy Zou 789*0959b670SJoy Zou pf9453->irq = i2c->irq; 790*0959b670SJoy Zou pf9453->dev = &i2c->dev; 791*0959b670SJoy Zou 792*0959b670SJoy Zou dev_set_drvdata(&i2c->dev, pf9453); 793*0959b670SJoy Zou 794*0959b670SJoy Zou ret = regmap_read(pf9453->regmap, PF9453_REG_DEV_ID, &device_id); 795*0959b670SJoy Zou if (ret) 796*0959b670SJoy Zou return dev_err_probe(&i2c->dev, ret, "Read device id error\n"); 797*0959b670SJoy Zou 798*0959b670SJoy Zou /* Check your board and dts for match the right pmic */ 799*0959b670SJoy Zou if ((device_id >> 4) != 0xb) 800*0959b670SJoy Zou return dev_err_probe(&i2c->dev, -EINVAL, "Device id(%x) mismatched\n", 801*0959b670SJoy Zou device_id >> 4); 802*0959b670SJoy Zou 803*0959b670SJoy Zou while (regulator_desc->desc.name) { 804*0959b670SJoy Zou const struct regulator_desc *desc; 805*0959b670SJoy Zou struct regulator_dev *rdev; 806*0959b670SJoy Zou 807*0959b670SJoy Zou desc = ®ulator_desc->desc; 808*0959b670SJoy Zou 809*0959b670SJoy Zou config.regmap = pf9453->regmap; 810*0959b670SJoy Zou config.dev = pf9453->dev; 811*0959b670SJoy Zou 812*0959b670SJoy Zou rdev = devm_regulator_register(pf9453->dev, desc, &config); 813*0959b670SJoy Zou if (IS_ERR(rdev)) 814*0959b670SJoy Zou return dev_err_probe(pf9453->dev, PTR_ERR(rdev), 815*0959b670SJoy Zou "Failed to register regulator(%s)\n", desc->name); 816*0959b670SJoy Zou 817*0959b670SJoy Zou regulator_desc++; 818*0959b670SJoy Zou } 819*0959b670SJoy Zou 820*0959b670SJoy Zou ret = devm_request_threaded_irq(pf9453->dev, pf9453->irq, NULL, pf9453_irq_handler, 821*0959b670SJoy Zou (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), 822*0959b670SJoy Zou "pf9453-irq", pf9453); 823*0959b670SJoy Zou if (ret) 824*0959b670SJoy Zou return dev_err_probe(pf9453->dev, ret, "Failed to request IRQ: %d\n", pf9453->irq); 825*0959b670SJoy Zou 826*0959b670SJoy Zou /* Unmask all interrupt except PWRON/WDOG/RSVD */ 827*0959b670SJoy Zou ret = pf9453_pmic_write(pf9453, PF9453_REG_INT1_MASK, 828*0959b670SJoy Zou IRQ_ONKEY | IRQ_RESETKEY | IRQ_RSTB | IRQ_VR_FLT1 829*0959b670SJoy Zou | IRQ_LOWVSYS | IRQ_THERM_100 | IRQ_THERM_80, IRQ_RSVD); 830*0959b670SJoy Zou if (ret) 831*0959b670SJoy Zou return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n"); 832*0959b670SJoy Zou 833*0959b670SJoy Zou if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset")) 834*0959b670SJoy Zou reset_ctrl = WDOG_B_CFG_WARM; 835*0959b670SJoy Zou else 836*0959b670SJoy Zou reset_ctrl = WDOG_B_CFG_COLD; 837*0959b670SJoy Zou 838*0959b670SJoy Zou /* Set reset behavior on assertion of WDOG_B signal */ 839*0959b670SJoy Zou ret = pf9453_pmic_write(pf9453, PF9453_REG_RESET_CTRL, WDOG_B_CFG_MASK, reset_ctrl); 840*0959b670SJoy Zou if (ret) 841*0959b670SJoy Zou return dev_err_probe(&i2c->dev, ret, "Failed to set WDOG_B reset behavior\n"); 842*0959b670SJoy Zou 843*0959b670SJoy Zou /* 844*0959b670SJoy Zou * The driver uses the LDO1OUT_H register to control the LDO1 regulator. 845*0959b670SJoy Zou * This is only valid if the SD_VSEL input of the PMIC is high. Let's 846*0959b670SJoy Zou * check if the pin is available as GPIO and set it to high. 847*0959b670SJoy Zou */ 848*0959b670SJoy Zou pf9453->sd_vsel_gpio = gpiod_get_optional(pf9453->dev, "sd-vsel", GPIOD_OUT_HIGH); 849*0959b670SJoy Zou 850*0959b670SJoy Zou if (IS_ERR(pf9453->sd_vsel_gpio)) 851*0959b670SJoy Zou return dev_err_probe(&i2c->dev, PTR_ERR(pf9453->sd_vsel_gpio), 852*0959b670SJoy Zou "Failed to get SD_VSEL GPIO\n"); 853*0959b670SJoy Zou 854*0959b670SJoy Zou return 0; 855*0959b670SJoy Zou } 856*0959b670SJoy Zou 857*0959b670SJoy Zou static const struct of_device_id pf9453_of_match[] = { 858*0959b670SJoy Zou { 859*0959b670SJoy Zou .compatible = "nxp,pf9453", 860*0959b670SJoy Zou .data = pf9453_regulators, 861*0959b670SJoy Zou }, 862*0959b670SJoy Zou { } 863*0959b670SJoy Zou }; 864*0959b670SJoy Zou MODULE_DEVICE_TABLE(of, pf9453_of_match); 865*0959b670SJoy Zou 866*0959b670SJoy Zou static struct i2c_driver pf9453_i2c_driver = { 867*0959b670SJoy Zou .driver = { 868*0959b670SJoy Zou .name = "nxp-pf9453", 869*0959b670SJoy Zou .probe_type = PROBE_PREFER_ASYNCHRONOUS, 870*0959b670SJoy Zou .of_match_table = pf9453_of_match, 871*0959b670SJoy Zou }, 872*0959b670SJoy Zou .probe = pf9453_i2c_probe, 873*0959b670SJoy Zou }; 874*0959b670SJoy Zou 875*0959b670SJoy Zou module_i2c_driver(pf9453_i2c_driver); 876*0959b670SJoy Zou 877*0959b670SJoy Zou MODULE_AUTHOR("Joy Zou <joy.zou@nxp.com>"); 878*0959b670SJoy Zou MODULE_DESCRIPTION("NXP PF9453 Power Management IC driver"); 879*0959b670SJoy Zou MODULE_LICENSE("GPL"); 880