static int ncp6335d_set_mode(struct regulator_dev *rdev, unsigned int mode) { int rc; struct ncp6335d_info *dd = rdev_get_drvdata(rdev); /* only FAST and NORMAL mode types are supported */ if (mode != REGULATOR_MODE_FAST && mode != REGULATOR_MODE_NORMAL) { dev_err(dd->dev, "Mode %d not supported\n", mode); return -EINVAL; } rc = ncp6335x_update_bits(dd, REG_NCP6335D_COMMAND, dd->mode_bit, (mode == REGULATOR_MODE_FAST) ? dd->mode_bit : 0); if (rc) { dev_err(dd->dev, "Unable to set operating mode rc(%d)", rc); return rc; } rc = ncp6335x_update_bits(dd, REG_NCP6335D_COMMAND, NCP6335D_DVS_PWM_MODE, (mode == REGULATOR_MODE_FAST) ? NCP6335D_DVS_PWM_MODE : 0); if (rc) dev_err(dd->dev, "Unable to set DVS trans. mode rc(%d)", rc); dump_registers(dd, REG_NCP6335D_COMMAND, __func__); return rc; }
static int ncp6335d_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { int rc, set_val, new_uV; struct ncp6335d_info *dd = rdev_get_drvdata(rdev); set_val = DIV_ROUND_UP(min_uV - dd->min_voltage, dd->step_size); new_uV = (set_val * dd->step_size) + dd->min_voltage; if (new_uV > max_uV) { dev_err(dd->dev, "Unable to set volatge (%d %d)\n", min_uV, max_uV); return -EINVAL; } #if 0 rc = ncp6335x_update_bits(dd, dd->vsel_reg, NCP6335D_VOUT_SEL_MASK, (set_val & NCP6335D_VOUT_SEL_MASK)); #else rc = ncp6335x_update_bits(dd, dd->vsel_reg, 0xFF, ((set_val & NCP6335D_VOUT_SEL_MASK)|0x80)); #endif if (rc) { dev_err(dd->dev, "Unable to set volatge (%d %d)\n", min_uV, max_uV); } else { ncp633d_slew_delay(dd, dd->curr_voltage, new_uV); dd->curr_voltage = new_uV; } dump_registers(dd, dd->vsel_reg, __func__); return rc; }
static int ncp6335d_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { int rc, set_val, new_uV; struct ncp6335d_info *dd = rdev_get_drvdata(rdev); //<oliver 20150716>++ modify ncp output voltage for stability static enum msm_cpu cur_cpu; //static variable constraint to this file static char* buf = "0.0"; cur_cpu = socinfo_get_msm_cpu(); buf = OLIVER_socinfo_get_msm_cpu_revision(); set_val = DIV_ROUND_UP(min_uV - dd->min_voltage, dd->step_size); if (!strncmp("3.0",buf,3)) { //printk("OLIVER 3.0 found\n"); } else if ((MSM_CPU_8939 == cur_cpu)&&(asus_PRJ_ID == ASUS_ZE550KL)){ if (!strncmp("3",asus_project_stage,2)||!strncmp("1",asus_project_stage,2)) { if (set_val < 80) set_val = set_val + 5; else if (set_val < 120) { set_val = set_val + 4; if (set_val > 120) set_val = 120; } }else { if (set_val < 80) { set_val = set_val + 4; if (set_val > 80) set_val = 80; } } } //<oliver 20150716>-- new_uV = (set_val * dd->step_size) + dd->min_voltage; if (new_uV > max_uV) { dev_err(dd->dev, "Unable to set volatge (%d %d)\n", min_uV, max_uV); return -EINVAL; } rc = ncp6335x_update_bits(dd, dd->vsel_reg, NCP6335D_VOUT_SEL_MASK, (set_val & NCP6335D_VOUT_SEL_MASK)); if (rc) { dev_err(dd->dev, "Unable to set volatge (%d %d)\n", min_uV, max_uV); } else { ncp633d_slew_delay(dd, dd->curr_voltage, new_uV); dd->curr_voltage = new_uV; } dump_registers(dd, dd->vsel_reg, __func__); return rc; }
static int ncp6335d_restore_working_reg(struct device_node *node, struct ncp6335d_info *dd) { int ret; unsigned int val1; unsigned int val2; unsigned int val3; /* Restore register from back up register */ ret = ncp6335x_read(dd, dd->vsel_backup_reg, &val1); dev_err(dd->dev, "%s: khl NCP6335D: Reg_back1= %x, Val = %x\n", __func__, dd->vsel_backup_reg, val1); if (ret < 0) { dev_err(dd->dev, "Failed to get backup data from reg %d, ret = %d\n", dd->vsel_backup_reg, ret); return ret; } ret = ncp6335x_read(dd, dd->vsel_reg, &val2); dev_err(dd->dev, "%s: khl NCP6335D: Reg_back2= %x, Val = %x\n", __func__, dd->vsel_reg, val2); #if 0 ret = ncp6335x_update_bits(dd, dd->vsel_reg, NCP6335D_VOUT_SEL_MASK, val); #else ret = ncp6335x_update_bits(dd, dd->vsel_reg, 0xFF, (val1 |0x80)); ret = ncp6335x_read(dd, dd->vsel_reg, &val3); dev_err(dd->dev, "%s: khl NCP6335D: Reg_back3= %x, Val = %x\n", __func__, dd->vsel_reg, val3); #endif if (ret < 0) { dev_err(dd->dev, "Failed to update working reg %d, ret = %d\n", dd->vsel_reg, ret); return ret; } return ret; }
static int ncp6335d_disable(struct regulator_dev *rdev) { int rc; struct ncp6335d_info *dd = rdev_get_drvdata(rdev); rc = ncp6335x_update_bits(dd, dd->vsel_reg, NCP6335D_ENABLE, 0); if (rc) dev_err(dd->dev, "Unable to disable regualtor rc(%d)", rc); dump_registers(dd, dd->vsel_reg, __func__); return rc; }
static int ncp6335d_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { int rc = 0, set_val, new_uV; struct ncp6335d_info *dd = rdev_get_drvdata(rdev); set_val = DIV_ROUND_UP(min_uV - dd->min_voltage, dd->step_size); new_uV = (set_val * dd->step_size) + dd->min_voltage; if (new_uV > max_uV) { dev_err(dd->dev, "Unable to set volatge (%d %d)\n", min_uV, max_uV); return -EINVAL; } mutex_lock(&dd->ncp_mutex); if (dd->is_suspend) { dev_info(dd->dev, "Ignore voltage setting after suspend: %d\n", new_uV); goto out; } rc = ncp6335x_update_bits(dd, dd->vsel_reg, NCP6335D_VOUT_SEL_MASK, (set_val & NCP6335D_VOUT_SEL_MASK)); if (rc) { dev_err(dd->dev, "Unable to set volatge (%d %d)\n", min_uV, max_uV); } else { ncp633d_slew_delay(dd, dd->curr_voltage, new_uV); dd->curr_voltage = new_uV; } dump_registers(dd, dd->vsel_reg, __func__); out: mutex_unlock(&dd->ncp_mutex); return rc; }
static int ncp6335d_restore_working_reg(struct device_node *node, struct ncp6335d_info *dd) { int ret; unsigned int val; /* Restore register from back up register */ ret = ncp6335x_read(dd, dd->vsel_backup_reg, &val); if (ret < 0) { dev_err(dd->dev, "Failed to get backup data from reg %d, ret = %d\n", dd->vsel_backup_reg, ret); return ret; } ret = ncp6335x_update_bits(dd, dd->vsel_reg, NCP6335D_VOUT_SEL_MASK, val); if (ret < 0) { dev_err(dd->dev, "Failed to update working reg %d, ret = %d\n", dd->vsel_reg, ret); return ret; } return ret; }
static int ncp6335d_init(struct i2c_client *client, struct ncp6335d_info *dd, const struct ncp6335d_platform_data *pdata) { int rc; unsigned int val; switch (pdata->default_vsel) { case NCP6335D_VSEL0: dd->vsel_reg = REG_NCP6335D_PROGVSEL0; dd->vsel_backup_reg = REG_NCP6335D_PROGVSEL1; dd->mode_bit = NCP6335D_PWM_MODE0; break; case NCP6335D_VSEL1: dd->vsel_reg = REG_NCP6335D_PROGVSEL1; dd->vsel_backup_reg = REG_NCP6335D_PROGVSEL0; dd->mode_bit = NCP6335D_PWM_MODE1; break; default: dev_err(dd->dev, "Invalid VSEL ID %d\n", pdata->default_vsel); return -EINVAL; } if (of_property_read_bool(client->dev.of_node, "onnn,restore-reg")) { rc = ncp6335d_restore_working_reg(client->dev.of_node, dd); if (rc) return rc; } rc = ncp6335d_parse_gpio(client->dev.of_node, dd); if (rc) return rc; /* get the current programmed voltage */ rc = ncp6335x_read(dd, dd->vsel_reg, &val); if (rc) { dev_err(dd->dev, "Unable to get volatge rc(%d)", rc); return rc; } dd->curr_voltage = ((val & NCP6335D_VOUT_SEL_MASK) * dd->step_size) + dd->min_voltage; /* set discharge */ rc = ncp6335x_update_bits(dd, REG_NCP6335D_PGOOD, NCP6335D_PGOOD_DISCHG, (pdata->discharge_enable ? NCP6335D_PGOOD_DISCHG : 0)); if (rc) { dev_err(dd->dev, "Unable to set Active Discharge rc(%d)\n", rc); return -EINVAL; } /* set slew rate */ if (pdata->slew_rate_ns < dd->min_slew_ns || pdata->slew_rate_ns > dd->max_slew_ns) { dev_err(dd->dev, "Invalid slew rate %d\n", pdata->slew_rate_ns); return -EINVAL; } dd->slew_rate = pdata->slew_rate_ns; val = DIV_ROUND_UP(pdata->slew_rate_ns, dd->min_slew_ns); val = ilog2(val); rc = ncp6335x_update_bits(dd, REG_NCP6335D_TIMING, NCP6335D_SLEW_MASK, val << NCP6335D_SLEW_SHIFT); if (rc) dev_err(dd->dev, "Unable to set slew rate rc(%d)\n", rc); /* Set Sleep mode bit */ rc = ncp6335x_update_bits(dd, REG_NCP6335D_COMMAND, NCP6335D_SLEEP_MODE, pdata->sleep_enable ? NCP6335D_SLEEP_MODE : 0); if (rc) dev_err(dd->dev, "Unable to set sleep mode (%d)\n", rc); dump_registers(dd, REG_NCP6335D_COMMAND, __func__); dump_registers(dd, REG_NCP6335D_PROGVSEL0, __func__); dump_registers(dd, REG_NCP6335D_TIMING, __func__); dump_registers(dd, REG_NCP6335D_PGOOD, __func__); return rc; }