summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/mediatek/common/include/soc/tps65132s.h36
-rw-r--r--src/soc/mediatek/common/tps65132s.c66
-rw-r--r--src/soc/mediatek/mt8186/Makefile.inc1
3 files changed, 103 insertions, 0 deletions
diff --git a/src/soc/mediatek/common/include/soc/tps65132s.h b/src/soc/mediatek/common/include/soc/tps65132s.h
new file mode 100644
index 0000000000..d9e609ac56
--- /dev/null
+++ b/src/soc/mediatek/common/include/soc/tps65132s.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_TPS65132S_H__
+#define __SOC_MEDIATEK_TPS65132S_H__
+
+#include <commonlib/bsd/cb_err.h>
+#include <gpio.h>
+
+/* TPS65132S I2C slave address */
+#define PMIC_TPS65132_SLAVE 0x3E
+
+/* TPS65132 register address */
+#define PMIC_TPS65132_VPOS 0x00
+#define PMIC_TPS65132_VNEG 0x01
+#define PMIC_TPS65132_DLYX 0x02
+/* Sequencing at startup and shutdown Field */
+#define PMIC_TPS65132_ASSDD 0x03
+#define PMIC_TPS65132_CONTROL 0xFF
+
+struct tps65132s_reg_setting {
+ u8 addr;
+ u8 val;
+ u8 mask;
+};
+
+struct tps65132s_cfg {
+ uint32_t i2c_bus;
+ gpio_t en;
+ gpio_t sync;
+ const struct tps65132s_reg_setting *settings;
+ uint32_t setting_counts;
+};
+
+enum cb_err tps65132s_setup(const struct tps65132s_cfg *cfg);
+
+#endif /* __SOC_MEDIATEK_TPS65132S_H__ */
diff --git a/src/soc/mediatek/common/tps65132s.c b/src/soc/mediatek/common/tps65132s.c
new file mode 100644
index 0000000000..4683a43072
--- /dev/null
+++ b/src/soc/mediatek/common/tps65132s.c
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <delay.h>
+#include <device/i2c_simple.h>
+#include <soc/gpio.h>
+#include <soc/i2c.h>
+#include <soc/tps65132s.h>
+
+static int tps65132s_reg_mask(unsigned int bus, uint8_t chip, uint8_t addr,
+ uint8_t val, uint8_t mask)
+{
+ uint8_t msg = 0;
+
+ if (i2c_read_field(bus, chip, addr, &msg, 0xFF, 0) < 0) {
+ printk(BIOS_ERR, "%s: Failed to read i2c(%u): addr(%u)\n",
+ __func__, bus, addr);
+ return -1;
+ }
+
+ msg &= ~mask;
+ msg |= val;
+
+ return i2c_write_field(bus, chip, addr, msg, 0xFF, 0);
+}
+
+enum cb_err tps65132s_setup(const struct tps65132s_cfg *cfg)
+{
+ bool write_to_eeprom = false;
+ u8 val;
+ int i;
+
+ /* Initialize I2C bus for PMIC TPS65132 */
+ mtk_i2c_bus_init(cfg->i2c_bus, I2C_SPEED_FAST);
+ mdelay(10);
+
+ gpio_output(cfg->en, 1);
+ gpio_output(cfg->sync, 1);
+ mdelay(10);
+
+ for (i = 0; i < cfg->setting_counts; i++) {
+ i2c_read_field(cfg->i2c_bus, PMIC_TPS65132_SLAVE,
+ cfg->settings[i].addr, &val, 0xFF, 0);
+ if (val != cfg->settings[i].val) {
+ if (tps65132s_reg_mask(cfg->i2c_bus, PMIC_TPS65132_SLAVE,
+ cfg->settings[i].addr,
+ cfg->settings[i].val,
+ cfg->settings[i].mask) < 0) {
+ printk(BIOS_ERR, "Failed to program TPS65132S at %x\n",
+ cfg->settings[i].addr);
+ return CB_ERR;
+ }
+ write_to_eeprom = true;
+ }
+ }
+
+ if (write_to_eeprom) {
+ if (tps65132s_reg_mask(cfg->i2c_bus, PMIC_TPS65132_SLAVE,
+ PMIC_TPS65132_CONTROL, 0x80, 0xFC) < 0)
+ return CB_ERR;
+ printk(BIOS_INFO, "Program TPS65132S EEPROM at first boot\n");
+ mdelay(50);
+ }
+
+ return CB_SUCCESS;
+}
diff --git a/src/soc/mediatek/mt8186/Makefile.inc b/src/soc/mediatek/mt8186/Makefile.inc
index 04d047acf1..8fe923f294 100644
--- a/src/soc/mediatek/mt8186/Makefile.inc
+++ b/src/soc/mediatek/mt8186/Makefile.inc
@@ -49,6 +49,7 @@ ramstage-y += ../common/rtc.c ../common/rtc_osc_init.c rtc.c
ramstage-y += soc.c
ramstage-y += ../common/spm.c spm.c
ramstage-y += ../common/sspm.c
+ramstage-y += ../common/tps65132s.c
ramstage-y += ../common/usb.c usb.c
CPPFLAGS_common += -Isrc/soc/mediatek/mt8186/include