drivers: st: pmic: update stpmic1 driver
authorYann Gautier <yann.gautier@st.com>
Thu, 17 Jan 2019 13:27:50 +0000 (14:27 +0100)
committerYann Gautier <yann.gautier@st.com>
Fri, 18 Jan 2019 14:45:08 +0000 (15:45 +0100)
Change-Id: I4a1b281925e0a3a1e2a34b3e363537e4a7f13823
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Signed-off-by: Nicolas Le Bayon <nicolas.le.bayon@st.com>
drivers/st/pmic/stpmic1.c
include/drivers/st/stpmic1.h

index 8a9eae16a2ebb8ac52c2fd7863dff5c2b50384fd..465996da93eae02ab45e47f912b961e840ace401 100644 (file)
@@ -16,6 +16,10 @@ struct regul_struct {
        uint8_t voltage_table_size;
        uint8_t control_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;
@@ -23,11 +27,11 @@ static uint16_t pmic_i2c_addr;
 
 /* Voltage tables in mV */
 static const uint16_t buck1_voltage_table[] = {
-       600,
-       625,
-       650,
-       675,
-       700,
+       725,
+       725,
+       725,
+       725,
+       725,
        725,
        750,
        775,
@@ -54,7 +58,39 @@ static const uint16_t buck1_voltage_table[] = {
        1300,
        1325,
        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[] = {
@@ -308,6 +344,7 @@ static const uint16_t ldo3_voltage_table[] = {
        3300,
        3300,
        3300,
+       500,
        0xFFFF, /* VREFDDR */
 };
 
@@ -389,6 +426,10 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
                .control_reg    = BUCK1_CONTROL_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",
@@ -396,6 +437,10 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
                .control_reg    = BUCK2_CONTROL_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",
@@ -403,6 +448,10 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
                .control_reg    = BUCK3_CONTROL_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",
@@ -410,6 +459,10 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
                .control_reg    = BUCK4_CONTROL_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",
@@ -417,6 +470,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
                .control_reg    = LDO1_CONTROL_REG,
                .low_power_reg  = LDO1_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO1_MASK_RESET,
        },
        {
                .dt_node_name   = "ldo2",
@@ -424,6 +479,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
                .control_reg    = LDO2_CONTROL_REG,
                .low_power_reg  = LDO2_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO2_MASK_RESET,
        },
        {
                .dt_node_name   = "ldo3",
@@ -431,6 +488,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
                .control_reg    = LDO3_CONTROL_REG,
                .low_power_reg  = LDO3_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO3_MASK_RESET,
        },
        {
                .dt_node_name   = "ldo4",
@@ -438,6 +497,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
                .control_reg    = LDO4_CONTROL_REG,
                .low_power_reg  = LDO4_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO4_MASK_RESET,
        },
        {
                .dt_node_name   = "ldo5",
@@ -445,6 +506,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
                .control_reg    = LDO5_CONTROL_REG,
                .low_power_reg  = LDO5_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO5_MASK_RESET,
        },
        {
                .dt_node_name   = "ldo6",
@@ -452,6 +515,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
                .control_reg    = LDO6_CONTROL_REG,
                .low_power_reg  = LDO6_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO6_MASK_RESET,
        },
        {
                .dt_node_name   = "vref_ddr",
@@ -459,6 +524,8 @@ static const struct regul_struct regulators_table[] = {
                .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
                .control_reg    = VREF_DDR_CONTROL_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)
        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)
 {
        return stpmic1_register_update(MAIN_CONTROL_REG, 1,
@@ -533,9 +606,72 @@ int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
 {
        uint8_t voltage_index = voltage_to_index(name, millivolts);
        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 << 2,
-                                      0xFC);
+       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 (int)regul->voltage_table[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)
                                     (uint16_t)register_id,
                                     I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
 
+#if ENABLE_ASSERTIONS
        if (status != 0) {
                return status;
        }
@@ -569,8 +706,9 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value)
                        return -1;
                }
        }
+#endif
 
-       return 0;
+       return status;
 }
 
 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;
        }
 
-       /* Clear bits to update */
-       val &= ~mask;
+       val = (val & ~mask) | (value & mask);
 
-       /* Update appropriate bits*/
-       val |= (value & mask);
-
-       /* Send new value on I2C Bus */
        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)
        pmic_i2c_handle = i2c_handle;
        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;
+}
index 7149cb5a7fef42ef2f57129691830802d899325c..f7e293b18996f706c3cf9f27befcbdd73bf9a331 100644 (file)
 #define ITSOURCE2_REG                  0xB1U
 #define ITSOURCE3_REG                  0xB2U
 #define ITSOURCE4_REG                  0xB3U
+
+/* Registers masks */
 #define LDO_VOLTAGE_MASK               0x7CU
 #define BUCK_VOLTAGE_MASK              0xFCU
 #define LDO_BUCK_VOLTAGE_SHIFT         2
-#define LDO_ENABLE_MASK                        0x01U
-#define BUCK_ENABLE_MASK               0x01U
-#define BUCK_HPLP_ENABLE_MASK          0x02U
-#define LDO_HPLP_ENABLE_MASK           0x02U
+#define LDO_BUCK_ENABLE_MASK           0x01U
+#define LDO_BUCK_HPLP_ENABLE_MASK      0x02U
 #define LDO_BUCK_HPLP_SHIFT            1
 #define LDO_BUCK_RANK_MASK             0x01U
 #define LDO_BUCK_RESET_MASK            0x01U
 #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) */
 #define ICC_EVENT_ENABLED              BIT(4)
 #define PWRCTRL_POLARITY_HIGH          BIT(3)
 #define SWIN_SWOUT_ENABLED             BIT(2)
 #define USBSW_OTG_SWITCH_ENABLED       BIT(1)
 
+int stpmic1_powerctrl_on(void);
 int stpmic1_switch_off(void);
 int stpmic1_register_read(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);
 int stpmic1_regulator_disable(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_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);
 
+int stpmic1_get_version(unsigned long *version);
+void stpmic1_dump_regulators(void);
+
 #endif /* STPMIC1_H */