summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2020-08-05 14:07:46 +0800
committerCommit Bot <commit-bot@chromium.org>2020-09-16 09:21:17 +0000
commitee3c56a04cd0888b1005fd75d8be186ef3c49ca2 (patch)
treebd2d798ee364f3e93300f6984187619d6adbe0b1
parent13b3ad768f2c46fdf4083ee1c5d315f74fe00114 (diff)
downloadchrome-ec-ee3c56a04cd0888b1005fd75d8be186ef3c49ca2.tar.gz
mt6360: support buck regulator
BUG=b:147789962 TEST=With chromium:2409487, emerge ec-utils; cros deploy ec-utils ectool regularinfo; ectool regulatorget; ectool regulatorset BRANCH=none Change-Id: I571a6a3903c7c88837c8d0666f833f3252756dcf Signed-off-by: Eric Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2337862 Reviewed-by: Ting Shen <phoenixshen@chromium.org> Commit-Queue: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--driver/bc12/mt6360.c91
-rw-r--r--driver/bc12/mt6360.h25
2 files changed, 107 insertions, 9 deletions
diff --git a/driver/bc12/mt6360.c b/driver/bc12/mt6360.c
index 00860fd9a3..e4f99d4088 100644
--- a/driver/bc12/mt6360.c
+++ b/driver/bc12/mt6360.c
@@ -318,8 +318,32 @@ struct mt6360_regulator_data regulator_data[MT6360_REGULATOR_COUNT] = {
.shift_vosel = MT6360_MASK_LDO7_VOSEL_SHIFT,
.mask_vocal = MT6360_MASK_LDO7_VOCAL,
},
+ [MT6360_BUCK1] = {
+ .name = "mt6360_buck1",
+ .addr = MT6360_PMIC_SLAVE_ADDR_FLAGS,
+ .reg_en_ctrl2 = MT6360_REG_BUCK1_EN_CTRL2,
+ .reg_ctrl3 = MT6360_REG_BUCK1_VOSEL,
+ .mask_vosel = MT6360_MASK_BUCK1_VOSEL,
+ .shift_vosel = MT6360_MASK_BUCK1_VOSEL_SHIFT,
+ .mask_vocal = MT6360_MASK_BUCK1_VOCAL,
+ },
+ [MT6360_BUCK2] = {
+ .name = "mt6360_buck2",
+ .addr = MT6360_PMIC_SLAVE_ADDR_FLAGS,
+ .reg_en_ctrl2 = MT6360_REG_BUCK2_EN_CTRL2,
+ .reg_ctrl3 = MT6360_REG_BUCK2_VOSEL,
+ .mask_vosel = MT6360_MASK_BUCK2_VOSEL,
+ .shift_vosel = MT6360_MASK_BUCK2_VOSEL_SHIFT,
+ .mask_vocal = MT6360_MASK_BUCK2_VOCAL,
+ },
};
+static bool is_buck_regulator(const struct mt6360_regulator_data *data)
+{
+ /* There's no ldo_vosel_table, it's a buck. */
+ return !(data->ldo_vosel_table);
+}
+
int mt6360_regulator_get_info(enum mt6360_regulator_id id, char *name,
uint16_t *num_voltages, uint16_t *voltages_mv)
{
@@ -332,16 +356,33 @@ int mt6360_regulator_get_info(enum mt6360_regulator_id id, char *name,
data = &regulator_data[id];
strzcpy(name, data->name, EC_REGULATOR_NAME_MAX_LEN);
- for (i = 0; i < data->ldo_vosel_table_len; i++) {
- int mv = data->ldo_vosel_table[i];
- if (!mv)
- continue;
- if (cnt < EC_REGULATOR_VOLTAGE_MAX_COUNT)
- voltages_mv[cnt++] = mv;
- else
- CPRINTS("%s voltage info overflow: %d", data->name, mv);
+ if (is_buck_regulator(data)) {
+ for (i = 0; i < MT6360_BUCK_VOSEL_MAX_STEP; ++i) {
+ int mv = MT6360_BUCK_VOSEL_MIN +
+ i * MT6360_BUCK_VOSEL_STEP_MV;
+
+ if (cnt < EC_REGULATOR_VOLTAGE_MAX_COUNT)
+ voltages_mv[cnt++] = mv;
+ else
+ CPRINTS("%s voltage info overflow: %d-%d",
+ data->name, mv, MT6360_BUCK_VOSEL_MAX);
+ }
+ } else {
+ /* It's a LDO */
+ for (i = 0; i < data->ldo_vosel_table_len; i++) {
+ int mv = data->ldo_vosel_table[i];
+
+ if (!mv)
+ continue;
+ if (cnt < EC_REGULATOR_VOLTAGE_MAX_COUNT)
+ voltages_mv[cnt++] = mv;
+ else
+ CPRINTS("%s voltage info overflow: %d",
+ data->name, mv);
+ }
}
+
*num_voltages = cnt;
return EC_SUCCESS;
}
@@ -397,6 +438,29 @@ int mt6360_regulator_set_voltage(enum mt6360_regulator_id id, int min_mv,
return EC_ERROR_INVAL;
data = &regulator_data[id];
+ if (is_buck_regulator(data)) {
+ int mv;
+ int step;
+
+ if (max_mv < MT6360_BUCK_VOSEL_MIN)
+ goto error;
+
+ if (min_mv > MT6360_BUCK_VOSEL_MAX)
+ goto error;
+
+ mv = DIV_ROUND_UP((min_mv + max_mv) / 2,
+ MT6360_BUCK_VOSEL_STEP_MV) *
+ MT6360_BUCK_VOSEL_STEP_MV;
+ mv = MIN(MAX(mv, MT6360_BUCK_VOSEL_MIN), MT6360_BUCK_VOSEL_MAX);
+
+ step = (mv - MT6360_BUCK_VOSEL_MIN) / MT6360_BUCK_VOSEL_STEP_MV;
+
+ return mt6360_regulator_update_bits(data->addr,
+ data->reg_ctrl3,
+ data->mask_vosel, step);
+ }
+
+ /* It's a LDO. */
for (i = 0; i < data->ldo_vosel_table_len; i++) {
int mv = data->ldo_vosel_table[i];
int step;
@@ -419,6 +483,8 @@ int mt6360_regulator_set_voltage(enum mt6360_regulator_id id, int min_mv,
data->mask_vosel | data->mask_vocal,
(i << data->shift_vosel) | step);
}
+
+error:
CPRINTS("%s voltage %d - %d out of range", data->name, min_mv, max_mv);
return EC_ERROR_INVAL;
}
@@ -438,6 +504,15 @@ int mt6360_regulator_get_voltage(enum mt6360_regulator_id id, int *voltage_mv)
CPRINTS("Error reading %s ctrl3: %d", data->name, rv);
return rv;
}
+
+ /* BUCK */
+ if (is_buck_regulator(data)) {
+ *voltage_mv = MT6360_BUCK_VOSEL_MIN +
+ value * MT6360_BUCK_VOSEL_STEP_MV;
+ return EC_SUCCESS;
+ }
+
+ /* LDO */
*voltage_mv = data->ldo_vosel_table[(value & data->mask_vosel) >>
data->shift_vosel];
if (*voltage_mv == 0) {
diff --git a/driver/bc12/mt6360.h b/driver/bc12/mt6360.h
index 6af946a006..e5fb47384c 100644
--- a/driver/bc12/mt6360.h
+++ b/driver/bc12/mt6360.h
@@ -63,18 +63,41 @@
#define MT6360_MASK_LDO7_VOSEL_SHIFT 4
#define MT6360_MASK_LDO7_VOCAL 0x0F
-/* This is same for LDO{1,2,3,5,6,7}_EN_CTRL2 */
+#define MT6360_REG_BUCK1_EN_CTRL2 0x17
+
+#define MT6360_REG_BUCK1_VOSEL 0x10
+#define MT6360_MASK_BUCK1_VOSEL 0xFF
+#define MT6360_MASK_BUCK1_VOSEL_SHIFT 0
+#define MT6360_MASK_BUCK1_VOCAL 0x0
+
+#define MT6360_REG_BUCK2_EN_CTRL2 0x26
+
+#define MT6360_REG_BUCK2_VOSEL 0x20
+#define MT6360_MASK_BUCK2_VOSEL 0xFF
+#define MT6360_MASK_BUCK2_VOSEL_SHIFT 0
+#define MT6360_MASK_BUCK2_VOCAL 0x0
+
+/* This is same for LDO{1,2,3,5,6,7}_EN_CTRL2, BUCK{1,2}_EN_CTRL2 */
#define MT6360_MASK_RGL_SW_OP_EN BIT(7)
#define MT6360_MASK_RGL_SW_EN BIT(6)
#define MT6360_LDO_VOCAL_STEP_MV 10
#define MT6360_LDO_VOCAL_MAX_STEP 10
+#define MT6360_BUCK_VOSEL_STEP_MV 5
+#define MT6360_BUCK_VOSEL_MAX_STEP 200
+#define MT6360_BUCK_VOSEL_MIN 300
+#define MT6360_BUCK_VOSEL_MAX \
+ (MT6360_BUCK_VOSEL_MIN + \
+ MT6360_BUCK_VOSEL_STEP_MV * MT6360_BUCK_VOSEL_MAX_STEP)
+
enum mt6360_regulator_id {
MT6360_LDO3,
MT6360_LDO5,
MT6360_LDO6,
MT6360_LDO7,
+ MT6360_BUCK1,
+ MT6360_BUCK2,
MT6360_REGULATOR_COUNT,
};