summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2020-08-04 16:22:20 +0800
committerCommit Bot <commit-bot@chromium.org>2020-09-16 09:21:14 +0000
commit13b3ad768f2c46fdf4083ee1c5d315f74fe00114 (patch)
treece47cd83bf42d6adff445be52cb1b3c968d10b43
parent2ecf69126084bc0339ec0c1c997e6168c73752ba (diff)
downloadchrome-ec-13b3ad768f2c46fdf4083ee1c5d315f74fe00114.tar.gz
mt6360: support regulator LDO6/LDO7
1. LDO6/7 uses different sub address to LDO3/5, so adding a additional addr entry in the config. 2. Renames LDO for regulator since that we also have buck. BUG=b:147789962 TEST=With chromium:2409487, emerge ec-utils; cros deploy ec-utils ectool regularinfo; ectool regulatorget; ectool regulatorset BRANCH=none Change-Id: I6d901ac3617479af56cbc3135b7dc8274cfed46c Signed-off-by: Eric Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2337860 Reviewed-by: Ting Shen <phoenixshen@chromium.org> Commit-Queue: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--board/asurada/board.c21
-rw-r--r--driver/bc12/mt6360.c170
-rw-r--r--driver/bc12/mt6360.h39
3 files changed, 150 insertions, 80 deletions
diff --git a/board/asurada/board.c b/board/asurada/board.c
index 075ec39128..249ee967c0 100644
--- a/board/asurada/board.c
+++ b/board/asurada/board.c
@@ -590,38 +590,39 @@ void lid_angle_peripheral_enable(int enable)
int board_regulator_get_info(uint32_t index, char *name,
uint16_t *num_voltages, uint16_t *voltages_mv)
{
- enum mt6360_ldo_id ldo_id = index;
+ enum mt6360_regulator_id id = index;
- return mt6360_ldo_get_info(ldo_id, name, num_voltages, voltages_mv);
+ return mt6360_regulator_get_info(id, name, num_voltages,
+ voltages_mv);
}
int board_regulator_enable(uint32_t index, uint8_t enable)
{
- enum mt6360_ldo_id ldo_id = index;
+ enum mt6360_regulator_id id = index;
- return mt6360_ldo_enable(ldo_id, enable);
+ return mt6360_regulator_enable(id, enable);
}
int board_regulator_is_enabled(uint32_t index, uint8_t *enabled)
{
- enum mt6360_ldo_id ldo_id = index;
+ enum mt6360_regulator_id id = index;
- return mt6360_ldo_is_enabled(ldo_id, enabled);
+ return mt6360_regulator_is_enabled(id, enabled);
}
int board_regulator_set_voltage(uint32_t index, uint32_t min_mv,
uint32_t max_mv)
{
- enum mt6360_ldo_id ldo_id = index;
+ enum mt6360_regulator_id id = index;
- return mt6360_ldo_set_voltage(ldo_id, min_mv, max_mv);
+ return mt6360_regulator_set_voltage(id, min_mv, max_mv);
}
int board_regulator_get_voltage(uint32_t index, uint32_t *voltage_mv)
{
- enum mt6360_ldo_id ldo_id = index;
+ enum mt6360_regulator_id id = index;
- return mt6360_ldo_get_voltage(ldo_id, voltage_mv);
+ return mt6360_regulator_get_voltage(id, voltage_mv);
}
/* gpio */
diff --git a/driver/bc12/mt6360.c b/driver/bc12/mt6360.c
index a5b5ceb487..00860fd9a3 100644
--- a/driver/bc12/mt6360.c
+++ b/driver/bc12/mt6360.c
@@ -179,22 +179,21 @@ static void mt6360_usb_charger_task(const int port)
}
}
-/* LDO */
-static int mt6360_ldo_write8(int reg, int val)
+/* Regulator: LDO & BUCK */
+static int mt6360_regulator_write8(uint8_t addr, int reg, int val)
{
/*
* Note: The checksum from I2C_FLAG_PEC happens to be correct because
* length == 1 -> the high 3 bits of the offset byte is 0.
*/
return i2c_write8(mt6360_config.i2c_port,
- MT6360_LDO_SLAVE_ADDR_FLAGS | I2C_FLAG_PEC, reg, val);
+ addr | I2C_FLAG_PEC, reg, val);
}
-static int mt6360_ldo_read8(int reg, int *val)
+static int mt6360_regulator_read8(int addr, int reg, int *val)
{
int rv;
uint8_t crc = 0, real_crc;
- uint8_t addr = MT6360_LDO_SLAVE_ADDR_FLAGS;
uint8_t out[3] = {(addr << 1) | 1, reg};
rv = i2c_read16(mt6360_config.i2c_port, addr, reg, val);
@@ -212,24 +211,25 @@ static int mt6360_ldo_read8(int reg, int *val)
return EC_SUCCESS;
}
-static int mt6360_ldo_update_bits(int reg, int mask, int val)
+static int mt6360_regulator_update_bits(int addr, int reg, int mask, int val)
{
int rv;
int reg_val = 0;
- rv = mt6360_ldo_read8(reg, &reg_val);
+ rv = mt6360_regulator_read8(addr, reg, &reg_val);
if (rv)
return rv;
reg_val &= ~mask;
reg_val |= (mask & val);
- rv = mt6360_ldo_write8(reg, reg_val);
+ rv = mt6360_regulator_write8(addr, reg, reg_val);
return rv;
}
-struct mt6360_ldo_data {
+struct mt6360_regulator_data {
const char *name;
- const uint16_t *vosel_table;
- uint16_t vosel_table_len;
+ const uint16_t *ldo_vosel_table;
+ uint16_t ldo_vosel_table_len;
+ uint8_t addr;
uint8_t reg_en_ctrl2;
uint8_t reg_ctrl3;
uint8_t mask_vosel;
@@ -250,11 +250,35 @@ static const uint16_t MT6360_LDO5_VOSEL_TABLE[8] = {
[0x5] = 3300,
};
-static const struct mt6360_ldo_data ldo_data[MT6360_LDO_COUNT] = {
+static const uint16_t MT6360_LDO6_VOSEL_TABLE[16] = {
+ [0x2] = 700,
+ [0x3] = 800,
+ [0x4] = 900,
+ [0x5] = 1000,
+ [0x6] = 1100,
+ [0x7] = 1200,
+ [0x8] = 1300,
+ [0x9] = 1400,
+ [0xA] = 1500,
+ [0xB] = 1600,
+ [0xC] = 1700,
+ [0xD] = 1800,
+ [0xE] = 1900,
+ [0xF] = 2000,
+};
+
+/* LDO7 VOSEL table is the same as LDO6's. */
+static const uint16_t *const MT6360_LDO7_VOSEL_TABLE = MT6360_LDO6_VOSEL_TABLE;
+static const uint16_t MT6360_LDO7_VOSEL_TABLE_SIZE =
+ ARRAY_SIZE(MT6360_LDO6_VOSEL_TABLE);
+
+static const
+struct mt6360_regulator_data regulator_data[MT6360_REGULATOR_COUNT] = {
[MT6360_LDO3] = {
.name = "mt6360_ldo3",
- .vosel_table = MT6360_LDO3_VOSEL_TABLE,
- .vosel_table_len = ARRAY_SIZE(MT6360_LDO3_VOSEL_TABLE),
+ .ldo_vosel_table = MT6360_LDO3_VOSEL_TABLE,
+ .ldo_vosel_table_len = ARRAY_SIZE(MT6360_LDO3_VOSEL_TABLE),
+ .addr = MT6360_LDO_SLAVE_ADDR_FLAGS,
.reg_en_ctrl2 = MT6360_REG_LDO3_EN_CTRL2,
.reg_ctrl3 = MT6360_REG_LDO3_CTRL3,
.mask_vosel = MT6360_MASK_LDO3_VOSEL,
@@ -263,92 +287,118 @@ static const struct mt6360_ldo_data ldo_data[MT6360_LDO_COUNT] = {
},
[MT6360_LDO5] = {
.name = "mt6360_ldo5",
- .vosel_table = MT6360_LDO5_VOSEL_TABLE,
- .vosel_table_len = ARRAY_SIZE(MT6360_LDO5_VOSEL_TABLE),
+ .ldo_vosel_table = MT6360_LDO5_VOSEL_TABLE,
+ .ldo_vosel_table_len = ARRAY_SIZE(MT6360_LDO5_VOSEL_TABLE),
+ .addr = MT6360_LDO_SLAVE_ADDR_FLAGS,
.reg_en_ctrl2 = MT6360_REG_LDO5_EN_CTRL2,
.reg_ctrl3 = MT6360_REG_LDO5_CTRL3,
.mask_vosel = MT6360_MASK_LDO5_VOSEL,
.shift_vosel = MT6360_MASK_LDO5_VOSEL_SHIFT,
.mask_vocal = MT6360_MASK_LDO5_VOCAL,
},
+ [MT6360_LDO6] = {
+ .name = "mt6360_ldo6",
+ .ldo_vosel_table = MT6360_LDO6_VOSEL_TABLE,
+ .ldo_vosel_table_len = ARRAY_SIZE(MT6360_LDO6_VOSEL_TABLE),
+ .addr = MT6360_PMIC_SLAVE_ADDR_FLAGS,
+ .reg_en_ctrl2 = MT6360_REG_LDO6_EN_CTRL2,
+ .reg_ctrl3 = MT6360_REG_LDO6_CTRL3,
+ .mask_vosel = MT6360_MASK_LDO6_VOSEL,
+ .shift_vosel = MT6360_MASK_LDO6_VOSEL_SHIFT,
+ .mask_vocal = MT6360_MASK_LDO6_VOCAL,
+ },
+ [MT6360_LDO7] = {
+ .name = "mt6360_ldo7",
+ .ldo_vosel_table = MT6360_LDO7_VOSEL_TABLE,
+ .ldo_vosel_table_len = MT6360_LDO7_VOSEL_TABLE_SIZE,
+ .addr = MT6360_PMIC_SLAVE_ADDR_FLAGS,
+ .reg_en_ctrl2 = MT6360_REG_LDO7_EN_CTRL2,
+ .reg_ctrl3 = MT6360_REG_LDO7_CTRL3,
+ .mask_vosel = MT6360_MASK_LDO7_VOSEL,
+ .shift_vosel = MT6360_MASK_LDO7_VOSEL_SHIFT,
+ .mask_vocal = MT6360_MASK_LDO7_VOCAL,
+ },
};
-int mt6360_ldo_get_info(enum mt6360_ldo_id ldo_id, char *name,
- uint16_t *num_voltages, uint16_t *voltages_mv)
+int mt6360_regulator_get_info(enum mt6360_regulator_id id, char *name,
+ uint16_t *num_voltages, uint16_t *voltages_mv)
{
int i;
int cnt = 0;
- const struct mt6360_ldo_data *data;
+ const struct mt6360_regulator_data *data;
- if (ldo_id >= MT6360_LDO_COUNT)
+ if (id >= MT6360_REGULATOR_COUNT)
return EC_ERROR_INVAL;
- data = &ldo_data[ldo_id];
+ data = &regulator_data[id];
strzcpy(name, data->name, EC_REGULATOR_NAME_MAX_LEN);
- for (i = 0; i < data->vosel_table_len; i++) {
- int mv = data->vosel_table[i];
+ 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("LDO3 Voltage info overflow: %d", mv);
+ CPRINTS("%s voltage info overflow: %d", data->name, mv);
}
*num_voltages = cnt;
return EC_SUCCESS;
}
-int mt6360_ldo_enable(enum mt6360_ldo_id ldo_id, uint8_t enable)
+int mt6360_regulator_enable(enum mt6360_regulator_id id, uint8_t enable)
{
- const struct mt6360_ldo_data *data;
+ const struct mt6360_regulator_data *data;
- if (ldo_id >= MT6360_LDO_COUNT)
+ if (id >= MT6360_REGULATOR_COUNT)
return EC_ERROR_INVAL;
- data = &ldo_data[ldo_id];
+ data = &regulator_data[id];
if (enable)
- return mt6360_ldo_update_bits(
+ return mt6360_regulator_update_bits(
+ data->addr,
data->reg_en_ctrl2,
- MT6360_MASK_LDO_SW_OP_EN | MT6360_MASK_LDO_SW_EN,
- MT6360_MASK_LDO_SW_OP_EN | MT6360_MASK_LDO_SW_EN);
+ MT6360_MASK_RGL_SW_OP_EN | MT6360_MASK_RGL_SW_EN,
+ MT6360_MASK_RGL_SW_OP_EN | MT6360_MASK_RGL_SW_EN);
else
- return mt6360_ldo_update_bits(
+ return mt6360_regulator_update_bits(
+ data->addr,
data->reg_en_ctrl2,
- MT6360_MASK_LDO_SW_OP_EN | MT6360_MASK_LDO_SW_EN,
- MT6360_MASK_LDO_SW_OP_EN);
+ MT6360_MASK_RGL_SW_OP_EN | MT6360_MASK_RGL_SW_EN,
+ MT6360_MASK_RGL_SW_OP_EN);
}
-int mt6360_ldo_is_enabled(enum mt6360_ldo_id ldo_id, uint8_t *enabled)
+int mt6360_regulator_is_enabled(enum mt6360_regulator_id id, uint8_t *enabled)
{
int rv;
int value;
- const struct mt6360_ldo_data *data;
+ const struct mt6360_regulator_data *data;
- if (ldo_id >= MT6360_LDO_COUNT)
+ if (id >= MT6360_REGULATOR_COUNT)
return EC_ERROR_INVAL;
- data = &ldo_data[ldo_id];
+ data = &regulator_data[id];
- rv = mt6360_ldo_read8(data->reg_en_ctrl2, &value);
+ rv = mt6360_regulator_read8(data->addr, data->reg_en_ctrl2, &value);
if (rv) {
- CPRINTS("Error reading LDO3 enabled: %d", rv);
+ CPRINTS("Error reading %s enabled: %d", data->name, rv);
return rv;
}
- *enabled = !!(value & MT6360_MASK_LDO_SW_EN);
+ *enabled = !!(value & MT6360_MASK_RGL_SW_EN);
return EC_SUCCESS;
}
-int mt6360_ldo_set_voltage(enum mt6360_ldo_id ldo_id, int min_mv, int max_mv)
+int mt6360_regulator_set_voltage(enum mt6360_regulator_id id, int min_mv,
+ int max_mv)
{
int i;
- const struct mt6360_ldo_data *data;
+ const struct mt6360_regulator_data *data;
- if (ldo_id >= MT6360_LDO_COUNT)
+ if (id >= MT6360_REGULATOR_COUNT)
return EC_ERROR_INVAL;
- data = &ldo_data[ldo_id];
+ data = &regulator_data[id];
- for (i = 0; i < data->vosel_table_len; i++) {
- int mv = data->vosel_table[i];
+ for (i = 0; i < data->ldo_vosel_table_len; i++) {
+ int mv = data->ldo_vosel_table[i];
int step;
if (!mv)
@@ -360,36 +410,38 @@ int mt6360_ldo_set_voltage(enum mt6360_ldo_id ldo_id, int min_mv, int max_mv)
MT6360_LDO_VOCAL_STEP_MV;
if (mv > max_mv)
continue;
- step = (mv - data->vosel_table[i]) / MT6360_LDO_VOCAL_STEP_MV;
+ step = (mv - data->ldo_vosel_table[i]) /
+ MT6360_LDO_VOCAL_STEP_MV;
- return mt6360_ldo_update_bits(
+ return mt6360_regulator_update_bits(
+ data->addr,
data->reg_ctrl3,
data->mask_vosel | data->mask_vocal,
(i << data->shift_vosel) | step);
}
- CPRINTS("LDO3 voltage %d - %d out of range", min_mv, max_mv);
+ CPRINTS("%s voltage %d - %d out of range", data->name, min_mv, max_mv);
return EC_ERROR_INVAL;
}
-int mt6360_ldo_get_voltage(enum mt6360_ldo_id ldo_id, int *voltage_mv)
+int mt6360_regulator_get_voltage(enum mt6360_regulator_id id, int *voltage_mv)
{
int value;
int rv;
- const struct mt6360_ldo_data *data;
+ const struct mt6360_regulator_data *data;
- if (ldo_id >= MT6360_LDO_COUNT)
+ if (id >= MT6360_REGULATOR_COUNT)
return EC_ERROR_INVAL;
- data = &ldo_data[ldo_id];
+ data = &regulator_data[id];
- rv = mt6360_ldo_read8(data->reg_ctrl3, &value);
+ rv = mt6360_regulator_read8(data->addr, data->reg_ctrl3, &value);
if (rv) {
- CPRINTS("Error reading LDO3 ctrl3: %d", rv);
+ CPRINTS("Error reading %s ctrl3: %d", data->name, rv);
return rv;
}
- *voltage_mv = data->vosel_table[(value & data->mask_vosel) >>
- data->shift_vosel];
+ *voltage_mv = data->ldo_vosel_table[(value & data->mask_vosel) >>
+ data->shift_vosel];
if (*voltage_mv == 0) {
- CPRINTS("Unknown LDO3 voltage value: %d", value);
+ CPRINTS("Unknown %s voltage value: %d", data->name, value);
return EC_ERROR_INVAL;
}
*voltage_mv +=
diff --git a/driver/bc12/mt6360.h b/driver/bc12/mt6360.h
index a51baee694..6af946a006 100644
--- a/driver/bc12/mt6360.h
+++ b/driver/bc12/mt6360.h
@@ -49,30 +49,47 @@
#define MT6360_MASK_LDO5_VOSEL_SHIFT 4
#define MT6360_MASK_LDO5_VOCAL 0x0F
-/* This is same for LDO{3,5,2,1}_EN_CTRL2 */
-#define MT6360_MASK_LDO_SW_OP_EN BIT(7)
-#define MT6360_MASK_LDO_SW_EN BIT(6)
+#define MT6360_REG_LDO6_EN_CTRL2 0x37
+
+#define MT6360_REG_LDO6_CTRL3 0x3B
+#define MT6360_MASK_LDO6_VOSEL 0xF0
+#define MT6360_MASK_LDO6_VOSEL_SHIFT 4
+#define MT6360_MASK_LDO6_VOCAL 0x0F
+
+#define MT6360_REG_LDO7_EN_CTRL2 0x31
+
+#define MT6360_REG_LDO7_CTRL3 0x35
+#define MT6360_MASK_LDO7_VOSEL 0xF0
+#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_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
-enum mt6360_ldo_id {
+enum mt6360_regulator_id {
MT6360_LDO3,
MT6360_LDO5,
+ MT6360_LDO6,
+ MT6360_LDO7,
- MT6360_LDO_COUNT,
+ MT6360_REGULATOR_COUNT,
};
-int mt6360_ldo_get_info(enum mt6360_ldo_id ldo_id, char *name,
- uint16_t *voltage_count, uint16_t *voltages_mv);
+int mt6360_regulator_get_info(enum mt6360_regulator_id id, char *name,
+ uint16_t *voltage_count, uint16_t *voltages_mv);
-int mt6360_ldo_enable(enum mt6360_ldo_id ldo_id, uint8_t enable);
+int mt6360_regulator_enable(enum mt6360_regulator_id id, uint8_t enable);
-int mt6360_ldo_is_enabled(enum mt6360_ldo_id ldo_id, uint8_t *enabled);
+int mt6360_regulator_is_enabled(enum mt6360_regulator_id id, uint8_t *enabled);
-int mt6360_ldo_set_voltage(enum mt6360_ldo_id ldo_id, int min_mv, int max_mv);
+int mt6360_regulator_set_voltage(enum mt6360_regulator_id id, int min_mv,
+ int max_mv);
-int mt6360_ldo_get_voltage(enum mt6360_ldo_id ldo_id, int *voltage_mv);
+int mt6360_regulator_get_voltage(enum mt6360_regulator_id id, int *voltage_mv);
enum mt6360_led_id {
MT6360_LED_RGB1,