static void palmas_enable_ldo8_track(struct palmas *palmas) { unsigned int reg; unsigned int addr; int ret; struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; struct palmas_regs_info *rinfo; rinfo = &ddata->palmas_regs_info[PALMAS_REG_LDO8]; addr = rinfo->ctrl_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) { dev_err(palmas->dev, "Error in reading ldo8 control reg\n"); return; } reg |= PALMAS_LDO8_CTRL_LDO_TRACKING_EN; ret = palmas_ldo_write(palmas, addr, reg); if (ret < 0) { dev_err(palmas->dev, "Error in enabling tracking mode\n"); return; } /* * When SMPS45 is set to off and LDO8 tracking is enabled, the LDO8 * output is defined by the LDO8_VOLTAGE.VSEL register divided by two, * and can be set from 0.45 to 1.65 V. */ addr = rinfo->vsel_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) { dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n"); return; } reg = (reg << 1) & PALMAS_LDO8_VOLTAGE_VSEL_MASK; ret = palmas_ldo_write(palmas, addr, reg); if (ret < 0) dev_err(palmas->dev, "Error in setting ldo8 voltage reg\n"); return; }
static int palmas_ldo_init(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { unsigned int reg; unsigned int addr; int ret; struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; addr = rinfo->ctrl_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) return ret; if (reg_init->warm_reset) reg |= PALMAS_LDO1_CTRL_WR_S; else reg &= ~PALMAS_LDO1_CTRL_WR_S; if (reg_init->mode_sleep) reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; else reg &= ~PALMAS_LDO1_CTRL_MODE_SLEEP; ret = palmas_ldo_write(palmas, addr, reg); if (ret) return ret; if (reg_init->roof_floor) { /* Enable externally controlled regulator */ ret = palmas_update_bits(palmas, PALMAS_LDO_BASE, addr, PALMAS_LDO1_CTRL_MODE_ACTIVE, PALMAS_LDO1_CTRL_MODE_ACTIVE); if (ret < 0) { dev_err(palmas->dev, "LDO Register 0x%02x update failed %d\n", addr, ret); return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; }
static int tps65917_ldo_registration(struct palmas_pmic *pmic, struct palmas_pmic_driver_data *ddata, struct palmas_pmic_platform_data *pdata, const char *pdev_name, struct regulator_config config) { int id, ret; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; struct regulator_desc *desc; unsigned int reg; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) reg_init = pdata->reg_init[id]; else reg_init = NULL; /* Miss out regulators which are not available due * to alternate functions. */ rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ desc = &pmic->desc[id]; desc->name = rinfo->name; desc->id = id; desc->type = REGULATOR_VOLTAGE; desc->owner = THIS_MODULE; if (id < TPS65917_REG_REGEN1) { desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_ldo; else desc->ops = &tps65917_ops_ldo; desc->min_uV = 900000; desc->uV_step = 50000; desc->linear_min_sel = 1; desc->enable_time = 500; desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, rinfo->vsel_addr); desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; /* * To be confirmed. Discussion on going with PMIC Team. * It is of the order of ~60mV/uS. */ desc->ramp_delay = 2500; if (id == TPS65917_REG_LDO1 || id == TPS65917_REG_LDO2) { desc->ops = &tps65917_ops_ldo_1_2; desc->bypass_reg = desc->enable_reg; desc->bypass_mask = TPS65917_LDO1_CTRL_BYPASS_EN; /* * OTP Values are set to bypass enable. * Switch to disable so that use count * does not go negative while directly * disabling bypass. */ ret = palmas_ldo_read(pmic->palmas, rinfo->ctrl_addr, ®); if (ret) { dev_err(pmic->dev, "Error reading ldo1 reg\n"); return ret; } reg &= ~TPS65917_LDO1_CTRL_BYPASS_EN; ret = palmas_ldo_write(pmic->palmas, rinfo->ctrl_addr, reg); if (ret) { dev_err(pmic->dev, "Error writing ldo1 reg\n"); return ret; } } } else { desc->n_voltages = 1; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_extreg; else desc->ops = &palmas_ops_extreg; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", pdev_name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ pmic->rdev[id] = rdev; /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { if (id < TPS65917_REG_REGEN1) ret = palmas_ldo_init(pmic->palmas, id, reg_init); else ret = palmas_extreg_init(pmic->palmas, id, reg_init); if (ret) return ret; } } } return 0; }