static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); u8 addr, mask, val; int ret; switch (buck) { case LP8720_ID_BUCK: addr = LP8720_BUCK_VOUT2; mask = LP8720_BUCK_FPWM_M; break; case LP8725_ID_BUCK1: addr = LP8725_BUCK_CTRL; mask = LP8725_BUCK1_FPWM_M; break; case LP8725_ID_BUCK2: addr = LP8725_BUCK_CTRL; mask = LP8725_BUCK2_FPWM_M; break; default: return -EINVAL; } ret = lp872x_read_byte(lp, addr, &val); if (ret) return ret; return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; }
static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); u8 addr, val; int ret; switch (buck) { case LP8725_ID_BUCK1: addr = LP8725_BUCK1_VOUT2; break; case LP8725_ID_BUCK2: addr = LP8725_BUCK2_VOUT2; break; default: return -EINVAL; } ret = lp872x_read_byte(lp, addr, &val); if (ret) return ret; val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S; return (val < ARRAY_SIZE(lp8725_buck_uA)) ? lp8725_buck_uA[val] : -EINVAL; }
static int lp872x_get_timestep_usec(struct lp872x *lp) { enum lp872x_id chip = lp->chipid; u8 val, mask, shift; int *time_usec, size, ret; int lp8720_time_usec[] = { 25, 50 }; int lp8725_time_usec[] = { 32, 64, 128, 256 }; switch (chip) { case LP8720: mask = LP8720_TIMESTEP_M; shift = LP8720_TIMESTEP_S; time_usec = &lp8720_time_usec[0]; size = ARRAY_SIZE(lp8720_time_usec); break; case LP8725: mask = LP8725_TIMESTEP_M; shift = LP8725_TIMESTEP_S; time_usec = &lp8725_time_usec[0]; size = ARRAY_SIZE(lp8725_time_usec); break; default: return -EINVAL; } ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); if (ret) return -EINVAL; val = (val & mask) >> shift; if (val >= size) return -EINVAL; return *(time_usec + val); }
static int lp872x_regulator_enable_time(struct regulator_dev *rdev) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id rid = rdev_get_id(rdev); int time_step_us = lp872x_get_timestep_usec(lp); int ret; u8 addr, val; if (time_step_us < 0) return time_step_us; switch (rid) { case LP8720_ID_LDO1 ... LP8720_ID_BUCK: addr = LP872X_LDO1_VOUT + rid; break; case LP8725_ID_LDO1 ... LP8725_ID_BUCK1: addr = LP872X_LDO1_VOUT + rid - LP8725_ID_BASE; break; case LP8725_ID_BUCK2: addr = LP8725_BUCK2_VOUT1; break; default: return -EINVAL; } ret = lp872x_read_byte(lp, addr, &val); if (ret) return ret; val = (val & LP872X_START_DELAY_M) >> LP872X_START_DELAY_S; return val > MAX_DELAY ? 0 : val * time_step_us; }
static u8 lp872x_select_buck_vout_addr(struct lp872x *lp, enum lp872x_regulator_id buck) { u8 val, addr; if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val)) return 0; switch (buck) { case LP8720_ID_BUCK: if (val & LP8720_EXT_DVS_M) { addr = (lp->dvs_pin == DVS_HIGH) ? LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; } else { if (lp872x_read_byte(lp, LP8720_ENABLE, &val)) return 0; addr = val & LP8720_DVS_SEL_M ? LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; } break; case LP8725_ID_BUCK1: if (val & LP8725_DVS1_M) addr = LP8725_BUCK1_VOUT1; else addr = (lp->dvs_pin == DVS_HIGH) ? LP8725_BUCK1_VOUT1 : LP8725_BUCK1_VOUT2; break; case LP8725_ID_BUCK2: addr = val & LP8725_DVS2_M ? LP8725_BUCK2_VOUT1 : LP8725_BUCK2_VOUT2; break; default: return 0; } return addr; }
static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); u8 addr, val; int ret; addr = lp872x_select_buck_vout_addr(lp, buck); if (!lp872x_is_valid_buck_addr(addr)) return -EINVAL; ret = lp872x_read_byte(lp, addr, &val); if (ret) return ret; return val & LP872X_VOUT_M; }
static int lp872x_check_dvs_validity(struct lp872x *lp) { struct lp872x_dvs *dvs = lp->pdata->dvs; u8 val = 0; int ret; ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); if (ret) return ret; ret = 0; if (lp->chipid == LP8720) { if (val & LP8720_EXT_DVS_M) ret = dvs ? 0 : -EINVAL; } else { if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED) ret = dvs ? 0 : -EINVAL; } return ret; }