|
@@ -246,6 +246,7 @@ enum spmi_common_control_register_index {
|
|
|
|
|
|
/* Minimum voltage stepper delay for each step. */
|
|
/* Minimum voltage stepper delay for each step. */
|
|
#define SPMI_FTSMPS_STEP_DELAY 8
|
|
#define SPMI_FTSMPS_STEP_DELAY 8
|
|
|
|
+#define SPMI_DEFAULT_STEP_DELAY 20
|
|
|
|
|
|
/*
|
|
/*
|
|
* The ratio SPMI_FTSMPS_STEP_MARGIN_NUM/SPMI_FTSMPS_STEP_MARGIN_DEN is used to
|
|
* The ratio SPMI_FTSMPS_STEP_MARGIN_NUM/SPMI_FTSMPS_STEP_MARGIN_DEN is used to
|
|
@@ -254,13 +255,6 @@ enum spmi_common_control_register_index {
|
|
#define SPMI_FTSMPS_STEP_MARGIN_NUM 4
|
|
#define SPMI_FTSMPS_STEP_MARGIN_NUM 4
|
|
#define SPMI_FTSMPS_STEP_MARGIN_DEN 5
|
|
#define SPMI_FTSMPS_STEP_MARGIN_DEN 5
|
|
|
|
|
|
-/*
|
|
|
|
- * This voltage in uV is returned by get_voltage functions when there is no way
|
|
|
|
- * to determine the current voltage level. It is needed because the regulator
|
|
|
|
- * framework treats a 0 uV voltage as an error.
|
|
|
|
- */
|
|
|
|
-#define VOLTAGE_UNKNOWN 1
|
|
|
|
-
|
|
|
|
/* VSET value to decide the range of ULT SMPS */
|
|
/* VSET value to decide the range of ULT SMPS */
|
|
#define ULT_SMPS_RANGE_SPLIT 0x60
|
|
#define ULT_SMPS_RANGE_SPLIT 0x60
|
|
|
|
|
|
@@ -539,12 +533,12 @@ static int spmi_regulator_common_disable(struct regulator_dev *rdev)
|
|
}
|
|
}
|
|
|
|
|
|
static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
|
static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
|
- int min_uV, int max_uV, u8 *range_sel, u8 *voltage_sel,
|
|
|
|
- unsigned *selector)
|
|
|
|
|
|
+ int min_uV, int max_uV)
|
|
{
|
|
{
|
|
const struct spmi_voltage_range *range;
|
|
const struct spmi_voltage_range *range;
|
|
int uV = min_uV;
|
|
int uV = min_uV;
|
|
int lim_min_uV, lim_max_uV, i, range_id, range_max_uV;
|
|
int lim_min_uV, lim_max_uV, i, range_id, range_max_uV;
|
|
|
|
+ int selector, voltage_sel;
|
|
|
|
|
|
/* Check if request voltage is outside of physically settable range. */
|
|
/* Check if request voltage is outside of physically settable range. */
|
|
lim_min_uV = vreg->set_points->range[0].set_point_min_uV;
|
|
lim_min_uV = vreg->set_points->range[0].set_point_min_uV;
|
|
@@ -570,14 +564,13 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
|
|
|
|
|
range_id = i;
|
|
range_id = i;
|
|
range = &vreg->set_points->range[range_id];
|
|
range = &vreg->set_points->range[range_id];
|
|
- *range_sel = range->range_sel;
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Force uV to be an allowed set point by applying a ceiling function to
|
|
* Force uV to be an allowed set point by applying a ceiling function to
|
|
* the uV value.
|
|
* the uV value.
|
|
*/
|
|
*/
|
|
- *voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
|
|
|
- uV = *voltage_sel * range->step_uV + range->min_uV;
|
|
|
|
|
|
+ voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
|
|
|
+ uV = voltage_sel * range->step_uV + range->min_uV;
|
|
|
|
|
|
if (uV > max_uV) {
|
|
if (uV > max_uV) {
|
|
dev_err(vreg->dev,
|
|
dev_err(vreg->dev,
|
|
@@ -587,12 +580,48 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- *selector = 0;
|
|
|
|
|
|
+ selector = 0;
|
|
for (i = 0; i < range_id; i++)
|
|
for (i = 0; i < range_id; i++)
|
|
- *selector += vreg->set_points->range[i].n_voltages;
|
|
|
|
- *selector += (uV - range->set_point_min_uV) / range->step_uV;
|
|
|
|
|
|
+ selector += vreg->set_points->range[i].n_voltages;
|
|
|
|
+ selector += (uV - range->set_point_min_uV) / range->step_uV;
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ return selector;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int spmi_sw_selector_to_hw(struct spmi_regulator *vreg,
|
|
|
|
+ unsigned selector, u8 *range_sel,
|
|
|
|
+ u8 *voltage_sel)
|
|
|
|
+{
|
|
|
|
+ const struct spmi_voltage_range *range, *end;
|
|
|
|
+
|
|
|
|
+ range = vreg->set_points->range;
|
|
|
|
+ end = range + vreg->set_points->count;
|
|
|
|
+
|
|
|
|
+ for (; range < end; range++) {
|
|
|
|
+ if (selector < range->n_voltages) {
|
|
|
|
+ *voltage_sel = selector;
|
|
|
|
+ *range_sel = range->range_sel;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ selector -= range->n_voltages;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -EINVAL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int spmi_hw_selector_to_sw(struct spmi_regulator *vreg, u8 hw_sel,
|
|
|
|
+ const struct spmi_voltage_range *range)
|
|
|
|
+{
|
|
|
|
+ int sw_sel = hw_sel;
|
|
|
|
+ const struct spmi_voltage_range *r = vreg->set_points->range;
|
|
|
|
+
|
|
|
|
+ while (r != range) {
|
|
|
|
+ sw_sel += r->n_voltages;
|
|
|
|
+ r++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return sw_sel;
|
|
}
|
|
}
|
|
|
|
|
|
static const struct spmi_voltage_range *
|
|
static const struct spmi_voltage_range *
|
|
@@ -614,12 +643,11 @@ spmi_regulator_find_range(struct spmi_regulator *vreg)
|
|
}
|
|
}
|
|
|
|
|
|
static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
|
static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
|
- int min_uV, int max_uV, u8 *range_sel, u8 *voltage_sel,
|
|
|
|
- unsigned *selector)
|
|
|
|
|
|
+ int min_uV, int max_uV)
|
|
{
|
|
{
|
|
const struct spmi_voltage_range *range;
|
|
const struct spmi_voltage_range *range;
|
|
int uV = min_uV;
|
|
int uV = min_uV;
|
|
- int i;
|
|
|
|
|
|
+ int i, selector;
|
|
|
|
|
|
range = spmi_regulator_find_range(vreg);
|
|
range = spmi_regulator_find_range(vreg);
|
|
if (!range)
|
|
if (!range)
|
|
@@ -637,8 +665,8 @@ static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
|
* Force uV to be an allowed set point by applying a ceiling function to
|
|
* Force uV to be an allowed set point by applying a ceiling function to
|
|
* the uV value.
|
|
* the uV value.
|
|
*/
|
|
*/
|
|
- *voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
|
|
|
- uV = *voltage_sel * range->step_uV + range->min_uV;
|
|
|
|
|
|
+ uV = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
|
|
|
+ uV = uV * range->step_uV + range->min_uV;
|
|
|
|
|
|
if (uV > max_uV) {
|
|
if (uV > max_uV) {
|
|
/*
|
|
/*
|
|
@@ -648,43 +676,49 @@ static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
|
goto different_range;
|
|
goto different_range;
|
|
}
|
|
}
|
|
|
|
|
|
- *selector = 0;
|
|
|
|
|
|
+ selector = 0;
|
|
for (i = 0; i < vreg->set_points->count; i++) {
|
|
for (i = 0; i < vreg->set_points->count; i++) {
|
|
if (uV >= vreg->set_points->range[i].set_point_min_uV
|
|
if (uV >= vreg->set_points->range[i].set_point_min_uV
|
|
&& uV <= vreg->set_points->range[i].set_point_max_uV) {
|
|
&& uV <= vreg->set_points->range[i].set_point_max_uV) {
|
|
- *selector +=
|
|
|
|
|
|
+ selector +=
|
|
(uV - vreg->set_points->range[i].set_point_min_uV)
|
|
(uV - vreg->set_points->range[i].set_point_min_uV)
|
|
/ vreg->set_points->range[i].step_uV;
|
|
/ vreg->set_points->range[i].step_uV;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- *selector += vreg->set_points->range[i].n_voltages;
|
|
|
|
|
|
+ selector += vreg->set_points->range[i].n_voltages;
|
|
}
|
|
}
|
|
|
|
|
|
- if (*selector >= vreg->set_points->n_voltages)
|
|
|
|
|
|
+ if (selector >= vreg->set_points->n_voltages)
|
|
goto different_range;
|
|
goto different_range;
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ return selector;
|
|
|
|
|
|
different_range:
|
|
different_range:
|
|
- return spmi_regulator_select_voltage(vreg, min_uV, max_uV,
|
|
|
|
- range_sel, voltage_sel, selector);
|
|
|
|
|
|
+ return spmi_regulator_select_voltage(vreg, min_uV, max_uV);
|
|
}
|
|
}
|
|
|
|
|
|
-static int spmi_regulator_common_set_voltage(struct regulator_dev *rdev,
|
|
|
|
- int min_uV, int max_uV, unsigned *selector)
|
|
|
|
|
|
+static int spmi_regulator_common_map_voltage(struct regulator_dev *rdev,
|
|
|
|
+ int min_uV, int max_uV)
|
|
{
|
|
{
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
- int ret;
|
|
|
|
- u8 buf[2];
|
|
|
|
- u8 range_sel, voltage_sel;
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Favor staying in the current voltage range if possible. This avoids
|
|
* Favor staying in the current voltage range if possible. This avoids
|
|
* voltage spikes that occur when changing the voltage range.
|
|
* voltage spikes that occur when changing the voltage range.
|
|
*/
|
|
*/
|
|
- ret = spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV,
|
|
|
|
- &range_sel, &voltage_sel, selector);
|
|
|
|
|
|
+ return spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+spmi_regulator_common_set_voltage(struct regulator_dev *rdev, unsigned selector)
|
|
|
|
+{
|
|
|
|
+ struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
|
|
+ int ret;
|
|
|
|
+ u8 buf[2];
|
|
|
|
+ u8 range_sel, voltage_sel;
|
|
|
|
+
|
|
|
|
+ ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
@@ -719,24 +753,24 @@ static int spmi_regulator_common_get_voltage(struct regulator_dev *rdev)
|
|
|
|
|
|
range = spmi_regulator_find_range(vreg);
|
|
range = spmi_regulator_find_range(vreg);
|
|
if (!range)
|
|
if (!range)
|
|
- return VOLTAGE_UNKNOWN;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
- return range->step_uV * voltage_sel + range->min_uV;
|
|
|
|
|
|
+ return spmi_hw_selector_to_sw(vreg, voltage_sel, range);
|
|
}
|
|
}
|
|
|
|
|
|
-static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev,
|
|
|
|
- int min_uV, int max_uV, unsigned *selector)
|
|
|
|
|
|
+static int spmi_regulator_single_map_voltage(struct regulator_dev *rdev,
|
|
|
|
+ int min_uV, int max_uV)
|
|
{
|
|
{
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
- int ret;
|
|
|
|
- u8 range_sel, sel;
|
|
|
|
|
|
|
|
- ret = spmi_regulator_select_voltage(vreg, min_uV, max_uV, &range_sel,
|
|
|
|
- &sel, selector);
|
|
|
|
- if (ret) {
|
|
|
|
- dev_err(vreg->dev, "could not set voltage, ret=%d\n", ret);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
|
|
+ return spmi_regulator_select_voltage(vreg, min_uV, max_uV);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev,
|
|
|
|
+ unsigned selector)
|
|
|
|
+{
|
|
|
|
+ struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
|
|
+ u8 sel = selector;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Certain types of regulators do not have a range select register so
|
|
* Certain types of regulators do not have a range select register so
|
|
@@ -748,27 +782,24 @@ static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev,
|
|
static int spmi_regulator_single_range_get_voltage(struct regulator_dev *rdev)
|
|
static int spmi_regulator_single_range_get_voltage(struct regulator_dev *rdev)
|
|
{
|
|
{
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
- const struct spmi_voltage_range *range = vreg->set_points->range;
|
|
|
|
- u8 voltage_sel;
|
|
|
|
|
|
+ u8 selector;
|
|
|
|
+ int ret;
|
|
|
|
|
|
- spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_SET, &voltage_sel, 1);
|
|
|
|
|
|
+ ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_SET, &selector, 1);
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
|
|
|
|
- return range->step_uV * voltage_sel + range->min_uV;
|
|
|
|
|
|
+ return selector;
|
|
}
|
|
}
|
|
|
|
|
|
static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,
|
|
static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,
|
|
- int min_uV, int max_uV, unsigned *selector)
|
|
|
|
|
|
+ unsigned selector)
|
|
{
|
|
{
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
|
int ret;
|
|
int ret;
|
|
u8 range_sel, voltage_sel;
|
|
u8 range_sel, voltage_sel;
|
|
|
|
|
|
- /*
|
|
|
|
- * Favor staying in the current voltage range if possible. This avoids
|
|
|
|
- * voltage spikes that occur when changing the voltage range.
|
|
|
|
- */
|
|
|
|
- ret = spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV,
|
|
|
|
- &range_sel, &voltage_sel, selector);
|
|
|
|
|
|
+ ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
@@ -783,7 +814,7 @@ static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,
|
|
voltage_sel |= ULT_SMPS_RANGE_SPLIT;
|
|
voltage_sel |= ULT_SMPS_RANGE_SPLIT;
|
|
|
|
|
|
return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_VOLTAGE_SET,
|
|
return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_VOLTAGE_SET,
|
|
- voltage_sel, 0xff);
|
|
|
|
|
|
+ voltage_sel, 0xff);
|
|
}
|
|
}
|
|
|
|
|
|
static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)
|
|
static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)
|
|
@@ -796,12 +827,12 @@ static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)
|
|
|
|
|
|
range = spmi_regulator_find_range(vreg);
|
|
range = spmi_regulator_find_range(vreg);
|
|
if (!range)
|
|
if (!range)
|
|
- return VOLTAGE_UNKNOWN;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
if (range->range_sel == 1)
|
|
if (range->range_sel == 1)
|
|
voltage_sel &= ~ULT_SMPS_RANGE_SPLIT;
|
|
voltage_sel &= ~ULT_SMPS_RANGE_SPLIT;
|
|
|
|
|
|
- return range->step_uV * voltage_sel + range->min_uV;
|
|
|
|
|
|
+ return spmi_hw_selector_to_sw(vreg, voltage_sel, range);
|
|
}
|
|
}
|
|
|
|
|
|
static int spmi_regulator_common_list_voltage(struct regulator_dev *rdev,
|
|
static int spmi_regulator_common_list_voltage(struct regulator_dev *rdev,
|
|
@@ -1007,8 +1038,10 @@ static struct regulator_ops spmi_smps_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_common_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_common_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_common_set_voltage,
|
|
|
|
+ .set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_common_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_common_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
@@ -1020,8 +1053,9 @@ static struct regulator_ops spmi_ldo_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_common_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_common_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_common_set_voltage,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_common_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_common_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
@@ -1036,8 +1070,9 @@ static struct regulator_ops spmi_ln_ldo_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_common_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_common_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_common_set_voltage,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_common_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_common_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_bypass = spmi_regulator_common_set_bypass,
|
|
.set_bypass = spmi_regulator_common_set_bypass,
|
|
.get_bypass = spmi_regulator_common_get_bypass,
|
|
.get_bypass = spmi_regulator_common_get_bypass,
|
|
@@ -1056,8 +1091,9 @@ static struct regulator_ops spmi_boost_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_single_range_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_single_range_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_single_range_set_voltage,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_single_range_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_single_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_input_current_limit = spmi_regulator_set_ilim,
|
|
.set_input_current_limit = spmi_regulator_set_ilim,
|
|
};
|
|
};
|
|
@@ -1066,9 +1102,10 @@ static struct regulator_ops spmi_ftsmps_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_common_set_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_common_set_voltage,
|
|
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
|
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
|
- .get_voltage = spmi_regulator_common_get_voltage,
|
|
|
|
|
|
+ .get_voltage_sel = spmi_regulator_common_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_common_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
@@ -1080,8 +1117,9 @@ static struct regulator_ops spmi_ult_lo_smps_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_ult_lo_smps_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_ult_lo_smps_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_ult_lo_smps_set_voltage,
|
|
|
|
+ .set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_ult_lo_smps_get_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
@@ -1093,8 +1131,10 @@ static struct regulator_ops spmi_ult_ho_smps_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_single_range_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_single_range_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_single_range_set_voltage,
|
|
|
|
+ .set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_single_range_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_single_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
@@ -1106,8 +1146,9 @@ static struct regulator_ops spmi_ult_ldo_ops = {
|
|
.enable = spmi_regulator_common_enable,
|
|
.enable = spmi_regulator_common_enable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.disable = spmi_regulator_common_disable,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
.is_enabled = spmi_regulator_common_is_enabled,
|
|
- .set_voltage = spmi_regulator_single_range_set_voltage,
|
|
|
|
- .get_voltage = spmi_regulator_single_range_get_voltage,
|
|
|
|
|
|
+ .set_voltage_sel = spmi_regulator_single_range_set_voltage,
|
|
|
|
+ .get_voltage_sel = spmi_regulator_single_range_get_voltage,
|
|
|
|
+ .map_voltage = spmi_regulator_single_map_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.list_voltage = spmi_regulator_common_list_voltage,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.set_mode = spmi_regulator_common_set_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
.get_mode = spmi_regulator_common_get_mode,
|
|
@@ -1201,7 +1242,7 @@ static int spmi_regulator_match(struct spmi_regulator *vreg, u16 force_type)
|
|
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_DIG_MAJOR_REV, version,
|
|
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_DIG_MAJOR_REV, version,
|
|
ARRAY_SIZE(version));
|
|
ARRAY_SIZE(version));
|
|
if (ret) {
|
|
if (ret) {
|
|
- dev_err(vreg->dev, "could not read version registers\n");
|
|
|
|
|
|
+ dev_dbg(vreg->dev, "could not read version registers\n");
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
dig_major_rev = version[SPMI_COMMON_REG_DIG_MAJOR_REV
|
|
dig_major_rev = version[SPMI_COMMON_REG_DIG_MAJOR_REV
|
|
@@ -1245,11 +1286,11 @@ found:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)
|
|
|
|
|
|
+static int spmi_regulator_init_slew_rate(struct spmi_regulator *vreg)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
u8 reg = 0;
|
|
u8 reg = 0;
|
|
- int step, delay, slew_rate;
|
|
|
|
|
|
+ int step, delay, slew_rate, step_delay;
|
|
const struct spmi_voltage_range *range;
|
|
const struct spmi_voltage_range *range;
|
|
|
|
|
|
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_STEP_CTRL, ®, 1);
|
|
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_STEP_CTRL, ®, 1);
|
|
@@ -1262,6 +1303,15 @@ static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)
|
|
if (!range)
|
|
if (!range)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
+ switch (vreg->logical_type) {
|
|
|
|
+ case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS:
|
|
|
|
+ step_delay = SPMI_FTSMPS_STEP_DELAY;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ step_delay = SPMI_DEFAULT_STEP_DELAY;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
step = reg & SPMI_FTSMPS_STEP_CTRL_STEP_MASK;
|
|
step = reg & SPMI_FTSMPS_STEP_CTRL_STEP_MASK;
|
|
step >>= SPMI_FTSMPS_STEP_CTRL_STEP_SHIFT;
|
|
step >>= SPMI_FTSMPS_STEP_CTRL_STEP_SHIFT;
|
|
|
|
|
|
@@ -1270,7 +1320,7 @@ static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)
|
|
|
|
|
|
/* slew_rate has units of uV/us */
|
|
/* slew_rate has units of uV/us */
|
|
slew_rate = SPMI_FTSMPS_CLOCK_RATE * range->step_uV * (1 << step);
|
|
slew_rate = SPMI_FTSMPS_CLOCK_RATE * range->step_uV * (1 << step);
|
|
- slew_rate /= 1000 * (SPMI_FTSMPS_STEP_DELAY << delay);
|
|
|
|
|
|
+ slew_rate /= 1000 * (step_delay << delay);
|
|
slew_rate *= SPMI_FTSMPS_STEP_MARGIN_NUM;
|
|
slew_rate *= SPMI_FTSMPS_STEP_MARGIN_NUM;
|
|
slew_rate /= SPMI_FTSMPS_STEP_MARGIN_DEN;
|
|
slew_rate /= SPMI_FTSMPS_STEP_MARGIN_DEN;
|
|
|
|
|
|
@@ -1411,10 +1461,16 @@ static int spmi_regulator_of_parse(struct device_node *node,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
- if (vreg->logical_type == SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS) {
|
|
|
|
- ret = spmi_regulator_ftsmps_init_slew_rate(vreg);
|
|
|
|
|
|
+ switch (vreg->logical_type) {
|
|
|
|
+ case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS:
|
|
|
|
+ case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS:
|
|
|
|
+ case SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS:
|
|
|
|
+ case SPMI_REGULATOR_LOGICAL_TYPE_SMPS:
|
|
|
|
+ ret = spmi_regulator_init_slew_rate(vreg);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
|
|
if (vreg->logical_type != SPMI_REGULATOR_LOGICAL_TYPE_VS)
|
|
if (vreg->logical_type != SPMI_REGULATOR_LOGICAL_TYPE_VS)
|
|
@@ -1510,10 +1566,61 @@ static const struct spmi_regulator_data pm8916_regulators[] = {
|
|
{ }
|
|
{ }
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static const struct spmi_regulator_data pm8994_regulators[] = {
|
|
|
|
+ { "s1", 0x1400, "vdd_s1", },
|
|
|
|
+ { "s2", 0x1700, "vdd_s2", },
|
|
|
|
+ { "s3", 0x1a00, "vdd_s3", },
|
|
|
|
+ { "s4", 0x1d00, "vdd_s4", },
|
|
|
|
+ { "s5", 0x2000, "vdd_s5", },
|
|
|
|
+ { "s6", 0x2300, "vdd_s6", },
|
|
|
|
+ { "s7", 0x2600, "vdd_s7", },
|
|
|
|
+ { "s8", 0x2900, "vdd_s8", },
|
|
|
|
+ { "s9", 0x2c00, "vdd_s9", },
|
|
|
|
+ { "s10", 0x2f00, "vdd_s10", },
|
|
|
|
+ { "s11", 0x3200, "vdd_s11", },
|
|
|
|
+ { "s12", 0x3500, "vdd_s12", },
|
|
|
|
+ { "l1", 0x4000, "vdd_l1", },
|
|
|
|
+ { "l2", 0x4100, "vdd_l2_l26_l28", },
|
|
|
|
+ { "l3", 0x4200, "vdd_l3_l11", },
|
|
|
|
+ { "l4", 0x4300, "vdd_l4_l27_l31", },
|
|
|
|
+ { "l5", 0x4400, "vdd_l5_l7", },
|
|
|
|
+ { "l6", 0x4500, "vdd_l6_l12_l32", },
|
|
|
|
+ { "l7", 0x4600, "vdd_l5_l7", },
|
|
|
|
+ { "l8", 0x4700, "vdd_l8_l16_l30", },
|
|
|
|
+ { "l9", 0x4800, "vdd_l9_l10_l18_l22", },
|
|
|
|
+ { "l10", 0x4900, "vdd_l9_l10_l18_l22", },
|
|
|
|
+ { "l11", 0x4a00, "vdd_l3_l11", },
|
|
|
|
+ { "l12", 0x4b00, "vdd_l6_l12_l32", },
|
|
|
|
+ { "l13", 0x4c00, "vdd_l13_l19_l23_l24", },
|
|
|
|
+ { "l14", 0x4d00, "vdd_l14_l15", },
|
|
|
|
+ { "l15", 0x4e00, "vdd_l14_l15", },
|
|
|
|
+ { "l16", 0x4f00, "vdd_l8_l16_l30", },
|
|
|
|
+ { "l17", 0x5000, "vdd_l17_l29", },
|
|
|
|
+ { "l18", 0x5100, "vdd_l9_l10_l18_l22", },
|
|
|
|
+ { "l19", 0x5200, "vdd_l13_l19_l23_l24", },
|
|
|
|
+ { "l20", 0x5300, "vdd_l20_l21", },
|
|
|
|
+ { "l21", 0x5400, "vdd_l20_l21", },
|
|
|
|
+ { "l22", 0x5500, "vdd_l9_l10_l18_l22", },
|
|
|
|
+ { "l23", 0x5600, "vdd_l13_l19_l23_l24", },
|
|
|
|
+ { "l24", 0x5700, "vdd_l13_l19_l23_l24", },
|
|
|
|
+ { "l25", 0x5800, "vdd_l25", },
|
|
|
|
+ { "l26", 0x5900, "vdd_l2_l26_l28", },
|
|
|
|
+ { "l27", 0x5a00, "vdd_l4_l27_l31", },
|
|
|
|
+ { "l28", 0x5b00, "vdd_l2_l26_l28", },
|
|
|
|
+ { "l29", 0x5c00, "vdd_l17_l29", },
|
|
|
|
+ { "l30", 0x5d00, "vdd_l8_l16_l30", },
|
|
|
|
+ { "l31", 0x5e00, "vdd_l4_l27_l31", },
|
|
|
|
+ { "l32", 0x5f00, "vdd_l6_l12_l32", },
|
|
|
|
+ { "lvs1", 0x8000, "vdd_lvs_1_2", },
|
|
|
|
+ { "lvs2", 0x8100, "vdd_lvs_1_2", },
|
|
|
|
+ { }
|
|
|
|
+};
|
|
|
|
+
|
|
static const struct of_device_id qcom_spmi_regulator_match[] = {
|
|
static const struct of_device_id qcom_spmi_regulator_match[] = {
|
|
{ .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
|
|
{ .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
|
|
{ .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
|
|
{ .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
|
|
{ .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
|
|
{ .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
|
|
|
|
+ { .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
|
|
{ }
|
|
{ }
|
|
};
|
|
};
|
|
MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);
|
|
MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);
|
|
@@ -1573,7 +1680,7 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
|
|
|
|
|
|
ret = spmi_regulator_match(vreg, reg->force_type);
|
|
ret = spmi_regulator_match(vreg, reg->force_type);
|
|
if (ret)
|
|
if (ret)
|
|
- goto err;
|
|
|
|
|
|
+ continue;
|
|
|
|
|
|
config.dev = dev;
|
|
config.dev = dev;
|
|
config.driver_data = vreg;
|
|
config.driver_data = vreg;
|