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@chromium.org> Original-Commit-Id: 4bc08ce28611d8b940642483c09614d2b8205c1f Original-Change-Id: If78e154ff7f553f65aa44d370820cc8c7f829c96 Original-Signed-off-by: Biao Huang <biao.huang@mediatek.com> Original-Reviewed-on: https://chromium-review.googlesource.com/297224 Original-Commit-Ready: Yidi Lin <yidi.lin@mediatek.com> Original-Tested-by: Yidi Lin <yidi.lin@mediatek.com> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/12609 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
31ae314f0f
commit
0dd8315bcc
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue