[coreboot-gerrit] New patch to review for coreboot: mediatek/mt8173: Add APIs for PMIC GPIO control

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Dec 1 19:57:59 CET 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/12609

-gerrit

commit 96114b9b6ac66b0fa77bbafd312ca2cda9f79513
Author: Biao Huang <biao.huang at mediatek.com>
Date:   Thu Sep 3 17:39:12 2015 +0800

    mediatek/mt8173: Add APIs for PMIC GPIO control
    
    BRANCH=chromeos-2015.07
    BUG=none
    TEST=verified on Oak rev3
    
    Change-Id: Ied991f13b73e70b91cc267222f351b588df8df66
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 4bc08ce28611d8b940642483c09614d2b8205c1f
    Original-Change-Id: If78e154ff7f553f65aa44d370820cc8c7f829c96
    Original-Signed-off-by: Biao Huang <biao.huang at mediatek.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/297224
    Original-Commit-Ready: Yidi Lin <yidi.lin at mediatek.com>
    Original-Tested-by: Yidi Lin <yidi.lin at mediatek.com>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/soc/mediatek/mt8173/include/soc/mt6391.h |  35 ++++++
 src/soc/mediatek/mt8173/mt6391.c             | 159 +++++++++++++++++++++++++++
 2 files changed, 194 insertions(+)

diff --git a/src/soc/mediatek/mt8173/include/soc/mt6391.h b/src/soc/mediatek/mt8173/include/soc/mt6391.h
index 304ef22..5a07355 100644
--- a/src/soc/mediatek/mt8173/include/soc/mt6391.h
+++ b/src/soc/mediatek/mt8173/include/soc/mt6391.h
@@ -308,4 +308,39 @@ void mt6391_write(u16 reg, u16 val, u32 mask, u32 shift);
 void mt6391_enable_reset_when_ap_resets(void);
 void mt6391_init(void);
 
+/*
+ * PMIC GPIO REGISTER DEFINITION
+ */
+enum {
+	MT6391_GPIO_DIR_BASE = 0xC000,
+	MT6391_GPIO_PULLEN_BASE = 0xC020,
+	MT6391_GPIO_PULLSEL_BASE = 0xC040,
+	MT6391_GPIO_DOUT_BASE = 0xC080,
+	MT6391_GPIO_DIN_BASE = 0xC0A0,
+	MT6391_GPIO_MODE_BASE = 0xC0C0,
+};
+
+enum mt6391_pull_enable {
+	MT6391_GPIO_PULL_DISABLE = 0,
+	MT6391_GPIO_PULL_ENABLE = 1,
+};
+
+enum mt6391_pull_select {
+	MT6391_GPIO_PULL_DOWN = 0,
+	MT6391_GPIO_PULL_UP = 1,
+};
+
+/*
+ * PMIC GPIO Exported Function
+ */
+int mt6391_gpio_get(u32 gpio);
+void mt6391_gpio_set(u32 gpio, int value);
+void mt6391_gpio_input_pulldown(u32 gpio);
+void mt6391_gpio_input_pullup(u32 gpio);
+void mt6391_gpio_input(u32 gpio);
+void mt6391_gpio_output(u32 gpio, int value);
+void mt6391_gpio_set_pull(u32 gpio, enum mt6391_pull_enable enable,
+			  enum mt6391_pull_select select);
+void mt6391_gpio_set_mode(u32 gpio, int mode);
+
 #endif /* __SOC_MEDIATEK_MT8173_MT6391_H__ */
diff --git a/src/soc/mediatek/mt8173/mt6391.c b/src/soc/mediatek/mt8173/mt6391.c
index 49fc0b0..91de817 100644
--- a/src/soc/mediatek/mt8173/mt6391.c
+++ b/src/soc/mediatek/mt8173/mt6391.c
@@ -16,11 +16,14 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
+#include <arch/io.h>
 #include <assert.h>
 #include <console/console.h>
 #include <delay.h>
+#include <soc/addressmap.h>
 #include <soc/mt6391.h>
 #include <soc/pmic_wrap.h>
+#include <types.h>
 
 #if CONFIG_DEBUG_PMIC
 #define DEBUG_PMIC(level, x...)		printk(level, x)
@@ -432,3 +435,159 @@ void mt6391_init(void)
 	/* Adjust default BUCK voltage from eFuse */
 	mt6391_default_buck_voltage();
 }
+
+/* API of GPIO in PMIC MT6391 */
+enum {
+	MAX_GPIO_REG_BITS = 16,
+	MAX_GPIO_MODE_PER_REG = 5,
+	GPIO_MODE_BITS = 3,
+	GPIO_PORT_OFFSET = 3,
+	GPIO_SET_OFFSET = 2,
+	GPIO_RST_OFFSET = 4,
+	MAX_MT6391_GPIO = 40
+};
+
+enum {
+	MT6391_GPIO_DIRECTION_IN = 0,
+	MT6391_GPIO_DIRECTION_OUT = 1,
+};
+
+enum {
+	MT6391_GPIO_MODE = 0,
+};
+
+static void pos_bit_calc(u32 pin, u16 *pos, u16 *bit)
+{
+	*pos = (pin / MAX_GPIO_REG_BITS) << GPIO_PORT_OFFSET;
+	*bit = pin % MAX_GPIO_REG_BITS;
+}
+
+static void pos_bit_calc_mode(u32 pin, u16 *pos, u16 *bit)
+{
+	*pos = (pin / MAX_GPIO_MODE_PER_REG) << GPIO_PORT_OFFSET;
+	*bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
+}
+
+static s32 mt6391_gpio_set_dir(u32 pin, u32 dir)
+{
+	u16 pos;
+	u16 bit;
+	u16 reg;
+
+	assert(pin <= MAX_MT6391_GPIO);
+
+	pos_bit_calc(pin, &pos, &bit);
+
+	if (dir == MT6391_GPIO_DIRECTION_IN)
+		reg = MT6391_GPIO_DIR_BASE + pos + GPIO_RST_OFFSET;
+	else
+		reg = MT6391_GPIO_DIR_BASE + pos + GPIO_SET_OFFSET;
+
+	if (pwrap_write(reg, 1L << bit) != 0)
+		return -1;
+
+	return 0;
+}
+
+void mt6391_gpio_set_pull(u32 pin, enum mt6391_pull_enable enable,
+			  enum mt6391_pull_select select)
+{
+	u16 pos;
+	u16 bit;
+	u16 en_reg, sel_reg;
+
+	assert(pin <= MAX_MT6391_GPIO);
+
+	pos_bit_calc(pin, &pos, &bit);
+
+	if (enable == MT6391_GPIO_PULL_DISABLE) {
+		en_reg = MT6391_GPIO_PULLEN_BASE + pos + GPIO_RST_OFFSET;
+	} else {
+		en_reg = MT6391_GPIO_PULLEN_BASE + pos + GPIO_SET_OFFSET;
+		sel_reg = (select == MT6391_GPIO_PULL_DOWN) ?
+			  (MT6391_GPIO_PULLSEL_BASE + pos + GPIO_RST_OFFSET) :
+			  (MT6391_GPIO_PULLSEL_BASE + pos + GPIO_SET_OFFSET);
+		pwrap_write(sel_reg, 1L << bit);
+	}
+	pwrap_write(en_reg, 1L << bit);
+}
+
+int mt6391_gpio_get(u32 pin)
+{
+	u16 pos;
+	u16 bit;
+	u16 reg;
+	u16 data;
+
+	assert(pin <= MAX_MT6391_GPIO);
+
+	pos_bit_calc(pin, &pos, &bit);
+
+	reg = MT6391_GPIO_DIN_BASE + pos;
+	pwrap_read(reg, &data);
+
+	return (data & (1L << bit)) ? 1 : 0;
+}
+
+void mt6391_gpio_set(u32 pin, int output)
+{
+	u16 pos;
+	u16 bit;
+	u16 reg;
+
+	assert(pin <= MAX_MT6391_GPIO);
+
+	pos_bit_calc(pin, &pos, &bit);
+
+	if (output == 0)
+		reg = MT6391_GPIO_DOUT_BASE + pos + GPIO_RST_OFFSET;
+	else
+		reg = MT6391_GPIO_DOUT_BASE + pos + GPIO_SET_OFFSET;
+
+	pwrap_write(reg, 1L << bit);
+}
+
+void mt6391_gpio_set_mode(u32 pin, int mode)
+{
+	u16 pos;
+	u16 bit;
+	u16 mask = (1L << GPIO_MODE_BITS) - 1;
+
+	assert(pin <= MAX_MT6391_GPIO);
+
+	pos_bit_calc_mode(pin, &pos, &bit);
+	mt6391_write(MT6391_GPIO_MODE_BASE + pos, mode, mask, bit);
+}
+
+void mt6391_gpio_input_pulldown(u32 gpio)
+{
+	mt6391_gpio_set_pull(gpio, MT6391_GPIO_PULL_ENABLE,
+			     MT6391_GPIO_PULL_DOWN);
+	mt6391_gpio_set_dir(gpio, MT6391_GPIO_DIRECTION_IN);
+	mt6391_gpio_set_mode(gpio, MT6391_GPIO_MODE);
+}
+
+void mt6391_gpio_input_pullup(u32 gpio)
+{
+	mt6391_gpio_set_pull(gpio, MT6391_GPIO_PULL_ENABLE,
+			     MT6391_GPIO_PULL_UP);
+	mt6391_gpio_set_dir(gpio, MT6391_GPIO_DIRECTION_IN);
+	mt6391_gpio_set_mode(gpio, MT6391_GPIO_MODE);
+}
+
+void mt6391_gpio_input(u32 gpio)
+{
+	mt6391_gpio_set_pull(gpio, MT6391_GPIO_PULL_DISABLE,
+			     MT6391_GPIO_PULL_DOWN);
+	mt6391_gpio_set_dir(gpio, MT6391_GPIO_DIRECTION_IN);
+	mt6391_gpio_set_mode(gpio, MT6391_GPIO_MODE);
+}
+
+void mt6391_gpio_output(u32 gpio, int value)
+{
+	mt6391_gpio_set_pull(gpio, MT6391_GPIO_PULL_DISABLE,
+			     MT6391_GPIO_PULL_DOWN);
+	mt6391_gpio_set(gpio, value);
+	mt6391_gpio_set_dir(gpio, MT6391_GPIO_DIRECTION_OUT);
+	mt6391_gpio_set_mode(gpio, MT6391_GPIO_MODE);
+}



More information about the coreboot-gerrit mailing list