Commit 077f6828 authored by Yann Gautier's avatar Yann Gautier
Browse files

drivers: st: pmic: update stpmic1 driver



Change-Id: I4a1b281925e0a3a1e2a34b3e363537e4a7f13823
Signed-off-by: default avatarYann Gautier <yann.gautier@st.com>
Signed-off-by: default avatarLionel Debieve <lionel.debieve@st.com>
Signed-off-by: default avatarNicolas Le Bayon <nicolas.le.bayon@st.com>
parent c948f771
...@@ -16,6 +16,10 @@ struct regul_struct { ...@@ -16,6 +16,10 @@ struct regul_struct {
uint8_t voltage_table_size; uint8_t voltage_table_size;
uint8_t control_reg; uint8_t control_reg;
uint8_t low_power_reg; uint8_t low_power_reg;
uint8_t pull_down_reg;
uint8_t pull_down;
uint8_t mask_reset_reg;
uint8_t mask_reset;
}; };
static struct i2c_handle_s *pmic_i2c_handle; static struct i2c_handle_s *pmic_i2c_handle;
...@@ -23,11 +27,11 @@ static uint16_t pmic_i2c_addr; ...@@ -23,11 +27,11 @@ static uint16_t pmic_i2c_addr;
/* Voltage tables in mV */ /* Voltage tables in mV */
static const uint16_t buck1_voltage_table[] = { static const uint16_t buck1_voltage_table[] = {
600, 725,
625, 725,
650, 725,
675, 725,
700, 725,
725, 725,
750, 750,
775, 775,
...@@ -54,7 +58,39 @@ static const uint16_t buck1_voltage_table[] = { ...@@ -54,7 +58,39 @@ static const uint16_t buck1_voltage_table[] = {
1300, 1300,
1325, 1325,
1350, 1350,
1350, 1375,
1400,
1425,
1450,
1475,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
}; };
static const uint16_t buck2_voltage_table[] = { static const uint16_t buck2_voltage_table[] = {
...@@ -308,6 +344,7 @@ static const uint16_t ldo3_voltage_table[] = { ...@@ -308,6 +344,7 @@ static const uint16_t ldo3_voltage_table[] = {
3300, 3300,
3300, 3300,
3300, 3300,
500,
0xFFFF, /* VREFDDR */ 0xFFFF, /* VREFDDR */
}; };
...@@ -389,6 +426,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -389,6 +426,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck1_voltage_table), .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
.control_reg = BUCK1_CONTROL_REG, .control_reg = BUCK1_CONTROL_REG,
.low_power_reg = BUCK1_PWRCTRL_REG, .low_power_reg = BUCK1_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK1_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK1_MASK_RESET,
}, },
{ {
.dt_node_name = "buck2", .dt_node_name = "buck2",
...@@ -396,6 +437,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -396,6 +437,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck2_voltage_table), .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
.control_reg = BUCK2_CONTROL_REG, .control_reg = BUCK2_CONTROL_REG,
.low_power_reg = BUCK2_PWRCTRL_REG, .low_power_reg = BUCK2_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK2_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK2_MASK_RESET,
}, },
{ {
.dt_node_name = "buck3", .dt_node_name = "buck3",
...@@ -403,6 +448,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -403,6 +448,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck3_voltage_table), .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
.control_reg = BUCK3_CONTROL_REG, .control_reg = BUCK3_CONTROL_REG,
.low_power_reg = BUCK3_PWRCTRL_REG, .low_power_reg = BUCK3_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK3_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK3_MASK_RESET,
}, },
{ {
.dt_node_name = "buck4", .dt_node_name = "buck4",
...@@ -410,6 +459,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -410,6 +459,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck4_voltage_table), .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
.control_reg = BUCK4_CONTROL_REG, .control_reg = BUCK4_CONTROL_REG,
.low_power_reg = BUCK4_PWRCTRL_REG, .low_power_reg = BUCK4_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK4_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK4_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo1", .dt_node_name = "ldo1",
...@@ -417,6 +470,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -417,6 +470,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
.control_reg = LDO1_CONTROL_REG, .control_reg = LDO1_CONTROL_REG,
.low_power_reg = LDO1_PWRCTRL_REG, .low_power_reg = LDO1_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO1_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo2", .dt_node_name = "ldo2",
...@@ -424,6 +479,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -424,6 +479,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
.control_reg = LDO2_CONTROL_REG, .control_reg = LDO2_CONTROL_REG,
.low_power_reg = LDO2_PWRCTRL_REG, .low_power_reg = LDO2_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO2_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo3", .dt_node_name = "ldo3",
...@@ -431,6 +488,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -431,6 +488,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
.control_reg = LDO3_CONTROL_REG, .control_reg = LDO3_CONTROL_REG,
.low_power_reg = LDO3_PWRCTRL_REG, .low_power_reg = LDO3_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO3_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo4", .dt_node_name = "ldo4",
...@@ -438,6 +497,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -438,6 +497,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
.control_reg = LDO4_CONTROL_REG, .control_reg = LDO4_CONTROL_REG,
.low_power_reg = LDO4_PWRCTRL_REG, .low_power_reg = LDO4_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO4_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo5", .dt_node_name = "ldo5",
...@@ -445,6 +506,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -445,6 +506,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
.control_reg = LDO5_CONTROL_REG, .control_reg = LDO5_CONTROL_REG,
.low_power_reg = LDO5_PWRCTRL_REG, .low_power_reg = LDO5_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO5_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo6", .dt_node_name = "ldo6",
...@@ -452,6 +515,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -452,6 +515,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
.control_reg = LDO6_CONTROL_REG, .control_reg = LDO6_CONTROL_REG,
.low_power_reg = LDO6_PWRCTRL_REG, .low_power_reg = LDO6_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO6_MASK_RESET,
}, },
{ {
.dt_node_name = "vref_ddr", .dt_node_name = "vref_ddr",
...@@ -459,6 +524,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -459,6 +524,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
.control_reg = VREF_DDR_CONTROL_REG, .control_reg = VREF_DDR_CONTROL_REG,
.low_power_reg = VREF_DDR_PWRCTRL_REG, .low_power_reg = VREF_DDR_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = VREF_DDR_MASK_RESET,
}, },
}; };
...@@ -497,6 +564,12 @@ static uint8_t voltage_to_index(const char *name, uint16_t millivolts) ...@@ -497,6 +564,12 @@ static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
return 0; return 0;
} }
int stpmic1_powerctrl_on(void)
{
return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
PWRCTRL_PIN_VALID);
}
int stpmic1_switch_off(void) int stpmic1_switch_off(void)
{ {
return stpmic1_register_update(MAIN_CONTROL_REG, 1, return stpmic1_register_update(MAIN_CONTROL_REG, 1,
...@@ -533,9 +606,72 @@ int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts) ...@@ -533,9 +606,72 @@ int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
{ {
uint8_t voltage_index = voltage_to_index(name, millivolts); uint8_t voltage_index = voltage_to_index(name, millivolts);
const struct regul_struct *regul = get_regulator_data(name); const struct regul_struct *regul = get_regulator_data(name);
uint8_t mask;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if (strncmp(name, "buck", 4) == 0) {
mask = BUCK_VOLTAGE_MASK;
} else if ((strncmp(name, "ldo", 3) == 0) &&
(strncmp(name, "ldo4", 4) != 0)) {
mask = LDO_VOLTAGE_MASK;
} else {
return 0;
}
return stpmic1_register_update(regul->control_reg,
voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
mask);
}
int stpmic1_regulator_pull_down_set(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
if (regul->pull_down_reg != 0) {
return stpmic1_register_update(regul->pull_down_reg,
BIT(regul->pull_down),
LDO_BUCK_PULL_DOWN_MASK <<
regul->pull_down);
}
return 0;
}
int stpmic1_regulator_mask_reset_set(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
return stpmic1_register_update(regul->mask_reset_reg,
BIT(regul->mask_reset),
LDO_BUCK_RESET_MASK <<
regul->mask_reset);
}
int stpmic1_regulator_voltage_get(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
uint8_t value;
uint8_t mask;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if (strncmp(name, "buck", 4) == 0) {
mask = BUCK_VOLTAGE_MASK;
} else if ((strncmp(name, "ldo", 3) == 0) &&
(strncmp(name, "ldo4", 4) != 0)) {
mask = LDO_VOLTAGE_MASK;
} else {
return 0;
}
if (stpmic1_register_read(regul->control_reg, &value))
return -1;
value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
if (value > regul->voltage_table_size)
return -1;
return stpmic1_register_update(regul->control_reg, voltage_index << 2, return (int)regul->voltage_table[value];
0xFC);
} }
int stpmic1_register_read(uint8_t register_id, uint8_t *value) int stpmic1_register_read(uint8_t register_id, uint8_t *value)
...@@ -553,6 +689,7 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value) ...@@ -553,6 +689,7 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value)
(uint16_t)register_id, (uint16_t)register_id,
I2C_MEMADD_SIZE_8BIT, &value, 1, 100000); I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
#if ENABLE_ASSERTIONS
if (status != 0) { if (status != 0) {
return status; return status;
} }
...@@ -569,8 +706,9 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value) ...@@ -569,8 +706,9 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value)
return -1; return -1;
} }
} }
#endif
return 0; return status;
} }
int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
...@@ -583,13 +721,8 @@ int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) ...@@ -583,13 +721,8 @@ int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
return status; return status;
} }
/* Clear bits to update */ val = (val & ~mask) | (value & mask);
val &= ~mask;
/* Update appropriate bits*/
val |= (value & mask);
/* Send new value on I2C Bus */
return stpmic1_register_write(register_id, val); return stpmic1_register_write(register_id, val);
} }
...@@ -598,3 +731,32 @@ void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr) ...@@ -598,3 +731,32 @@ void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
pmic_i2c_handle = i2c_handle; pmic_i2c_handle = i2c_handle;
pmic_i2c_addr = i2c_addr; pmic_i2c_addr = i2c_addr;
} }
void stpmic1_dump_regulators(void)
{
uint32_t i;
for (i = 0U; i < MAX_REGUL; i++) {
const char *name __unused = regulators_table[i].dt_node_name;
VERBOSE("PMIC regul %s: %sable, %dmV",
name,
stpmic1_is_regulator_enabled(name) ? "en" : "dis",
stpmic1_regulator_voltage_get(name));
}
}
int stpmic1_get_version(unsigned long *version)
{
int rc;
uint8_t read_val;
rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
if (rc) {
return -1;
}
*version = (unsigned long)read_val;
return 0;
}
...@@ -84,18 +84,40 @@ ...@@ -84,18 +84,40 @@
#define ITSOURCE2_REG 0xB1U #define ITSOURCE2_REG 0xB1U
#define ITSOURCE3_REG 0xB2U #define ITSOURCE3_REG 0xB2U
#define ITSOURCE4_REG 0xB3U #define ITSOURCE4_REG 0xB3U
/* Registers masks */
#define LDO_VOLTAGE_MASK 0x7CU #define LDO_VOLTAGE_MASK 0x7CU
#define BUCK_VOLTAGE_MASK 0xFCU #define BUCK_VOLTAGE_MASK 0xFCU
#define LDO_BUCK_VOLTAGE_SHIFT 2 #define LDO_BUCK_VOLTAGE_SHIFT 2
#define LDO_ENABLE_MASK 0x01U #define LDO_BUCK_ENABLE_MASK 0x01U
#define BUCK_ENABLE_MASK 0x01U #define LDO_BUCK_HPLP_ENABLE_MASK 0x02U
#define BUCK_HPLP_ENABLE_MASK 0x02U
#define LDO_HPLP_ENABLE_MASK 0x02U
#define LDO_BUCK_HPLP_SHIFT 1 #define LDO_BUCK_HPLP_SHIFT 1
#define LDO_BUCK_RANK_MASK 0x01U #define LDO_BUCK_RANK_MASK 0x01U
#define LDO_BUCK_RESET_MASK 0x01U #define LDO_BUCK_RESET_MASK 0x01U
#define LDO_BUCK_PULL_DOWN_MASK 0x03U #define LDO_BUCK_PULL_DOWN_MASK 0x03U
/* Pull down register */
#define BUCK1_PULL_DOWN_SHIFT 0
#define BUCK2_PULL_DOWN_SHIFT 2
#define BUCK3_PULL_DOWN_SHIFT 4
#define BUCK4_PULL_DOWN_SHIFT 6
#define VREF_DDR_PULL_DOWN_SHIFT 4
/* Buck Mask reset register */
#define BUCK1_MASK_RESET 0
#define BUCK2_MASK_RESET 1
#define BUCK3_MASK_RESET 2
#define BUCK4_MASK_RESET 3
/* LDO Mask reset register */
#define LDO1_MASK_RESET 0
#define LDO2_MASK_RESET 1
#define LDO3_MASK_RESET 2
#define LDO4_MASK_RESET 3
#define LDO5_MASK_RESET 4
#define LDO6_MASK_RESET 5
#define VREF_DDR_MASK_RESET 6
/* Main PMIC Control Register (MAIN_CONTROL_REG) */ /* Main PMIC Control Register (MAIN_CONTROL_REG) */
#define ICC_EVENT_ENABLED BIT(4) #define ICC_EVENT_ENABLED BIT(4)
#define PWRCTRL_POLARITY_HIGH BIT(3) #define PWRCTRL_POLARITY_HIGH BIT(3)
...@@ -127,6 +149,7 @@ ...@@ -127,6 +149,7 @@
#define SWIN_SWOUT_ENABLED BIT(2) #define SWIN_SWOUT_ENABLED BIT(2)
#define USBSW_OTG_SWITCH_ENABLED BIT(1) #define USBSW_OTG_SWITCH_ENABLED BIT(1)
int stpmic1_powerctrl_on(void);
int stpmic1_switch_off(void); int stpmic1_switch_off(void);
int stpmic1_register_read(uint8_t register_id, uint8_t *value); int stpmic1_register_read(uint8_t register_id, uint8_t *value);
int stpmic1_register_write(uint8_t register_id, uint8_t value); int stpmic1_register_write(uint8_t register_id, uint8_t value);
...@@ -135,6 +158,12 @@ int stpmic1_regulator_enable(const char *name); ...@@ -135,6 +158,12 @@ int stpmic1_regulator_enable(const char *name);
int stpmic1_regulator_disable(const char *name); int stpmic1_regulator_disable(const char *name);
uint8_t stpmic1_is_regulator_enabled(const char *name); uint8_t stpmic1_is_regulator_enabled(const char *name);
int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts); int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts);
int stpmic1_regulator_voltage_get(const char *name);
int stpmic1_regulator_pull_down_set(const char *name);
int stpmic1_regulator_mask_reset_set(const char *name);
void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr); void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
int stpmic1_get_version(unsigned long *version);
void stpmic1_dump_regulators(void);
#endif /* STPMIC1_H */ #endif /* STPMIC1_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment