614 lines
18 KiB
Diff
614 lines
18 KiB
Diff
From b6cbd44b2582bbc76d1f8eb4fe4b77d45c5dcebe Mon Sep 17 00:00:00 2001
|
|
From: Alan <Alan>
|
|
Date: Fri, 19 May 2023 16:38:40 +0800
|
|
Subject: [PATCH 05/11] Add: add support for AXP313a PMIC
|
|
|
|
---
|
|
arch/arm/mach-sunxi/pmic_bus.c | 4 +
|
|
board/sunxi/board.c | 30 ++-
|
|
drivers/power/Kconfig | 14 +-
|
|
drivers/power/Makefile | 1 +
|
|
drivers/power/axp313a.c | 362 +++++++++++++++++++++++++++++++++
|
|
include/axp313a.h | 53 +++++
|
|
include/axp_pmic.h | 3 +
|
|
7 files changed, 459 insertions(+), 8 deletions(-)
|
|
create mode 100644 drivers/power/axp313a.c
|
|
create mode 100644 include/axp313a.h
|
|
|
|
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
|
|
index c090840637..19c31b195f 100644
|
|
--- a/arch/arm/mach-sunxi/pmic_bus.c
|
|
+++ b/arch/arm/mach-sunxi/pmic_bus.c
|
|
@@ -23,6 +23,8 @@
|
|
|
|
#define AXP305_I2C_ADDR 0x36
|
|
|
|
+#define AXP313A_I2C_ADDR 0x36
|
|
+
|
|
#define AXP221_CHIP_ADDR 0x68
|
|
|
|
#if CONFIG_IS_ENABLED(PMIC_AXP)
|
|
@@ -34,6 +36,8 @@ static int pmic_i2c_address(void)
|
|
return AXP152_I2C_ADDR;
|
|
if (IS_ENABLED(CONFIG_AXP305_POWER))
|
|
return AXP305_I2C_ADDR;
|
|
+ if (IS_ENABLED(CONFIG_AXP313A_POWER))
|
|
+ return AXP313A_I2C_ADDR;
|
|
|
|
/* Other AXP2xx and AXP8xx variants */
|
|
return AXP209_I2C_ADDR;
|
|
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
|
|
index c7488d7c79..c264790075 100644
|
|
--- a/board/sunxi/board.c
|
|
+++ b/board/sunxi/board.c
|
|
@@ -581,6 +581,7 @@ static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
|
|
void sunxi_board_init(void)
|
|
{
|
|
int power_failed = 0;
|
|
+ int power_volume = 0;
|
|
|
|
#ifdef CONFIG_LED_STATUS
|
|
if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC))
|
|
@@ -593,7 +594,8 @@ void sunxi_board_init(void)
|
|
|
|
#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
|
|
defined CONFIG_AXP221_POWER || defined CONFIG_AXP305_POWER || \
|
|
- defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
|
|
+ defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER || \
|
|
+ defined CONFIG_AXP313A_POWER
|
|
power_failed = axp_init();
|
|
|
|
if (IS_ENABLED(CONFIG_AXP_DISABLE_BOOT_ON_POWERON) && !power_failed) {
|
|
@@ -610,11 +612,12 @@ void sunxi_board_init(void)
|
|
defined CONFIG_AXP818_POWER
|
|
power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT);
|
|
#endif
|
|
-#if !defined(CONFIG_AXP305_POWER)
|
|
+#if !defined(CONFIG_AXP305_POWER) && !defined(CONFIG_AXP313A_POWER)
|
|
power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT);
|
|
power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT);
|
|
#endif
|
|
-#if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER)
|
|
+#if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) && \
|
|
+ !defined(CONFIG_AXP313A_POWER)
|
|
power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT);
|
|
#endif
|
|
#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
|
|
@@ -626,12 +629,29 @@ void sunxi_board_init(void)
|
|
defined CONFIG_AXP818_POWER
|
|
power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT);
|
|
#endif
|
|
-#if !defined(CONFIG_AXP305_POWER)
|
|
+#if !defined(CONFIG_AXP305_POWER) && !defined(CONFIG_AXP313A_POWER)
|
|
power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT);
|
|
#endif
|
|
-#if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP305_POWER)
|
|
+#if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP305_POWER) && \
|
|
+ !defined(CONFIG_AXP313A_POWER)
|
|
power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT);
|
|
#endif
|
|
+#if defined(CONFIG_AXP313A_POWER)
|
|
+ power_failed |= pmu_axp313a_set_voltage("dcdc1", 960, 1);
|
|
+ power_volume = pmu_axp313a_get_voltage("dcdc1");
|
|
+
|
|
+ power_failed |= pmu_axp313a_set_voltage("dcdc2", 1000, 1);
|
|
+ power_volume = pmu_axp313a_get_voltage("dcdc2");
|
|
+
|
|
+ power_failed |= pmu_axp313a_set_voltage("dcdc3", 1500, 1);
|
|
+ power_volume = pmu_axp313a_get_voltage("dcdc3");
|
|
+
|
|
+ power_failed |= pmu_axp313a_set_voltage("aldo1", 1800, 1);
|
|
+ power_volume = pmu_axp313a_get_voltage("aldo1");
|
|
+
|
|
+ power_failed |= pmu_axp313a_set_voltage("dldo1", 3300, 1);
|
|
+ power_volume = pmu_axp313a_get_voltage("dldo1");
|
|
+#endif
|
|
#ifdef CONFIG_AXP209_POWER
|
|
power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT);
|
|
#endif
|
|
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
|
index 7f3b990d23..93905039e6 100644
|
|
--- a/drivers/power/Kconfig
|
|
+++ b/drivers/power/Kconfig
|
|
@@ -56,7 +56,7 @@ choice
|
|
depends on ARCH_SUNXI
|
|
default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
|
|
default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40
|
|
- default AXP305_POWER if MACH_SUN50I_H616
|
|
+ default AXP313A_POWER if MACH_SUN50I_H616
|
|
default AXP818_POWER if MACH_SUN8I_A83T
|
|
default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_V3S
|
|
|
|
@@ -101,6 +101,14 @@ config AXP305_POWER
|
|
Select this to enable support for the axp305 pmic found on most
|
|
H616 boards.
|
|
|
|
+config AXP313A_POWER
|
|
+ bool "axp313a pmic support"
|
|
+ depends on MACH_SUN50I_H616
|
|
+ select AXP_PMIC_BUS
|
|
+ select CMD_POWEROFF
|
|
+ ---help---
|
|
+ Select this to enable support for the axp313a pmic found on BigTreeTech CB1 boards.
|
|
+
|
|
config AXP809_POWER
|
|
bool "axp809 pmic support"
|
|
depends on MACH_SUN9I
|
|
@@ -180,12 +188,12 @@ config AXP_DCDC3_VOLT
|
|
|
|
config AXP_DCDC4_VOLT
|
|
int "axp pmic dcdc4 voltage"
|
|
- depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP305_POWER
|
|
+ depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP305_POWER || AXP313A_POWER
|
|
default 1250 if AXP152_POWER
|
|
default 1200 if MACH_SUN6I
|
|
default 0 if MACH_SUN8I
|
|
default 900 if MACH_SUN9I
|
|
- default 1500 if AXP305_POWER
|
|
+ default 1500 if AXP305_POWER || AXP313A_POWER
|
|
---help---
|
|
Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to
|
|
disable dcdc4.
|
|
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
|
|
index ba64b2c593..f851f4a94e 100644
|
|
--- a/drivers/power/Makefile
|
|
+++ b/drivers/power/Makefile
|
|
@@ -12,6 +12,7 @@ obj-$(CONFIG_AXP152_POWER) += axp152.o
|
|
obj-$(CONFIG_AXP209_POWER) += axp209.o
|
|
obj-$(CONFIG_AXP221_POWER) += axp221.o
|
|
obj-$(CONFIG_AXP305_POWER) += axp305.o
|
|
+obj-$(CONFIG_AXP313A_POWER) += axp313a.o
|
|
obj-$(CONFIG_AXP809_POWER) += axp809.o
|
|
obj-$(CONFIG_AXP818_POWER) += axp818.o
|
|
obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o
|
|
diff --git a/drivers/power/axp313a.c b/drivers/power/axp313a.c
|
|
new file mode 100644
|
|
index 0000000000..c2463458c4
|
|
--- /dev/null
|
|
+++ b/drivers/power/axp313a.c
|
|
@@ -0,0 +1,362 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Allwinner.
|
|
+ * weidonghui <weidonghui@allwinnertech.com>
|
|
+ *
|
|
+ * SUNXI AXP21 Driver
|
|
+ *
|
|
+ * SPDX-License-Identifier: GPL-2.0+
|
|
+ */
|
|
+
|
|
+#include <common.h>
|
|
+
|
|
+#include <errno.h>
|
|
+#include <asm/arch/pmic_bus.h>
|
|
+#include <axp_pmic.h>
|
|
+#include <axp313a.h>
|
|
+
|
|
+#ifdef PMU_DEBUG
|
|
+#define axp_info(fmt...) printf("[axp][info]: " fmt)
|
|
+#define axp_err(fmt...) printf("[axp][err]: " fmt)
|
|
+#else
|
|
+#define axp_info(fmt...)
|
|
+#define axp_err(fmt...) printf("[axp][err]: " fmt)
|
|
+#endif
|
|
+
|
|
+typedef struct _axp_contrl_info
|
|
+{
|
|
+ char name[16];
|
|
+
|
|
+ u32 min_vol;
|
|
+ u32 max_vol;
|
|
+ u32 cfg_reg_addr;
|
|
+ u32 cfg_reg_mask;
|
|
+
|
|
+ u32 step0_val;
|
|
+ u32 split1_val;
|
|
+ u32 step1_val;
|
|
+ u32 ctrl_reg_addr;
|
|
+
|
|
+ u32 ctrl_bit_ofs;
|
|
+ u32 step2_val;
|
|
+ u32 split2_val;
|
|
+} axp_contrl_info;
|
|
+
|
|
+__attribute__((section(".data"))) axp_contrl_info pmu_axp313a_ctrl_tbl[] = {
|
|
+ /*name, min, max, reg, mask, step0,split1_val, step1,ctrl_reg,ctrl_bit */
|
|
+ {"dcdc1", 500, 3400, AXP313A_DC1OUT_VOL, 0x7f, 10, 1200, 20,
|
|
+ AXP313A_OUTPUT_POWER_ON_OFF_CTL, 0, 100, 1540},
|
|
+ {"dcdc2", 500, 1540, AXP313A_DC2OUT_VOL, 0x7f, 10, 1200, 20,
|
|
+ AXP313A_OUTPUT_POWER_ON_OFF_CTL, 1},
|
|
+ {"dcdc3", 500, 1840, AXP313A_DC3OUT_VOL, 0x7f, 10, 1200, 20,
|
|
+ AXP313A_OUTPUT_POWER_ON_OFF_CTL, 2},
|
|
+ {"aldo1", 500, 3500, AXP313A_ALDO1OUT_VOL, 0x1f, 100, 0, 0,
|
|
+ AXP313A_OUTPUT_POWER_ON_OFF_CTL, 3},
|
|
+ {"dldo1", 500, 3500, AXP313A_DLDO1OUT_VOL, 0x1f, 100, 0, 0,
|
|
+ AXP313A_OUTPUT_POWER_ON_OFF_CTL, 4},
|
|
+};
|
|
+
|
|
+static axp_contrl_info *get_ctrl_info_from_tbl(char *name)
|
|
+{
|
|
+ int i = 0;
|
|
+ int size = ARRAY_SIZE(pmu_axp313a_ctrl_tbl);
|
|
+ axp_contrl_info *p;
|
|
+
|
|
+ for (i = 0; i < size; i++)
|
|
+ {
|
|
+ if (!strncmp(name, pmu_axp313a_ctrl_tbl[i].name,
|
|
+ strlen(pmu_axp313a_ctrl_tbl[i].name)))
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (i >= size)
|
|
+ {
|
|
+ axp_err("can't find %s from table\n", name);
|
|
+ return NULL;
|
|
+ }
|
|
+ p = pmu_axp313a_ctrl_tbl + i;
|
|
+ return p;
|
|
+}
|
|
+
|
|
+int pmu_axp313a_necessary_reg_enable(void)
|
|
+{
|
|
+ __attribute__((unused)) u8 reg_value;
|
|
+#ifdef CONFIG_AXP313A_NECESSARY_REG_ENABLE
|
|
+ if (pmic_bus_read(AXP313A_RUNTIME_ADDR, AXP313A_WRITE_LOCK, ®_value))
|
|
+ return -1;
|
|
+ reg_value |= 0x5;
|
|
+ if (pmic_bus_write(AXP313A_RUNTIME_ADDR, AXP313A_WRITE_LOCK, reg_value))
|
|
+ return -1;
|
|
+
|
|
+ if (pmic_bus_read(AXP313A_RUNTIME_ADDR, AXP313A_ERROR_MANAGEMENT, ®_value))
|
|
+ return -1;
|
|
+ reg_value |= 0x8;
|
|
+ if (pmic_bus_write(AXP313A_RUNTIME_ADDR, AXP313A_ERROR_MANAGEMENT, reg_value))
|
|
+ return -1;
|
|
+
|
|
+ if (pmic_bus_read(AXP313A_RUNTIME_ADDR, AXP313A_DCDC_DVM_PWM_CTL, ®_value))
|
|
+ return -1;
|
|
+ reg_value |= (0x1 << 5);
|
|
+ if (pmic_bus_write(AXP313A_RUNTIME_ADDR, AXP313A_DCDC_DVM_PWM_CTL, reg_value))
|
|
+ return -1;
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int axp_init(void)
|
|
+{
|
|
+ u8 pmu_chip_id;
|
|
+ if (pmic_bus_init())
|
|
+ {
|
|
+ printf("%s pmic_bus_init fail\n", __func__);
|
|
+ return -1;
|
|
+ }
|
|
+ if (pmic_bus_read(AXP313A_VERSION, &pmu_chip_id))
|
|
+ {
|
|
+ printf("%s pmic_bus_read fail\n", __func__);
|
|
+ return -1;
|
|
+ }
|
|
+ pmu_chip_id &= 0XCF;
|
|
+ if (pmu_chip_id == AXP1530_CHIP_ID || pmu_chip_id == AXP313A_CHIP_ID || pmu_chip_id == AXP313B_CHIP_ID)
|
|
+ {
|
|
+ /*pmu type AXP313A*/
|
|
+ // pmu_axp313a_necessary_reg_enable();
|
|
+ return 0;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+int pmu_axp313a_get_info(char *name, unsigned char *chipid)
|
|
+{
|
|
+ strncpy(name, "axp313a", sizeof("axp313a"));
|
|
+ *chipid = AXP313A_CHIP_ID;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int pmu_axp313a_set_voltage(char *name, uint set_vol, uint onoff)
|
|
+{
|
|
+ u8 reg_value;
|
|
+ axp_contrl_info *p_item = NULL;
|
|
+ u8 base_step = 0;
|
|
+
|
|
+ p_item = get_ctrl_info_from_tbl(name);
|
|
+ if (!p_item)
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ axp_info(
|
|
+ "name %s, min_vol %dmv, max_vol %d, cfg_reg 0x%x, cfg_mask 0x%x \
|
|
+ step0_val %d, split1_val %d, step1_val %d, ctrl_reg_addr 0x%x, ctrl_bit_ofs %d\n",
|
|
+ p_item->name, p_item->min_vol, p_item->max_vol,
|
|
+ p_item->cfg_reg_addr, p_item->cfg_reg_mask, p_item->step0_val,
|
|
+ p_item->split1_val, p_item->step1_val, p_item->ctrl_reg_addr,
|
|
+ p_item->ctrl_bit_ofs);
|
|
+
|
|
+ if ((set_vol > 0) && (p_item->min_vol))
|
|
+ {
|
|
+ if (set_vol < p_item->min_vol)
|
|
+ {
|
|
+ set_vol = p_item->min_vol;
|
|
+ }
|
|
+ else if (set_vol > p_item->max_vol)
|
|
+ {
|
|
+ set_vol = p_item->max_vol;
|
|
+ }
|
|
+ if (pmic_bus_read(p_item->cfg_reg_addr,
|
|
+ ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ reg_value &= ~p_item->cfg_reg_mask;
|
|
+ if (p_item->split2_val && (set_vol > p_item->split2_val))
|
|
+ {
|
|
+ base_step = (p_item->split2_val - p_item->split1_val) /
|
|
+ p_item->step1_val;
|
|
+
|
|
+ base_step += (p_item->split1_val - p_item->min_vol) /
|
|
+ p_item->step0_val;
|
|
+ reg_value |= (base_step +
|
|
+ (set_vol - p_item->split2_val / p_item->step2_val * p_item->step2_val) /
|
|
+ p_item->step2_val);
|
|
+ }
|
|
+ else if (p_item->split1_val &&
|
|
+ (set_vol > p_item->split1_val))
|
|
+ {
|
|
+ if (p_item->split1_val < p_item->min_vol)
|
|
+ {
|
|
+ axp_err("bad split val(%d) for %s\n",
|
|
+ p_item->split1_val, name);
|
|
+ }
|
|
+
|
|
+ base_step = (p_item->split1_val - p_item->min_vol) /
|
|
+ p_item->step0_val;
|
|
+ reg_value |= (base_step +
|
|
+ (set_vol - p_item->split1_val) /
|
|
+ p_item->step1_val);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ reg_value |=
|
|
+ (set_vol - p_item->min_vol) / p_item->step0_val;
|
|
+ }
|
|
+ if (pmic_bus_write(p_item->cfg_reg_addr, reg_value))
|
|
+ {
|
|
+ axp_err("unable to set %s\n", name);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (onoff < 0)
|
|
+ {
|
|
+ return 0;
|
|
+ }
|
|
+ if (pmic_bus_read(p_item->ctrl_reg_addr, ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ if (onoff == 0)
|
|
+ {
|
|
+ reg_value &= ~(1 << p_item->ctrl_bit_ofs);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ reg_value |= (1 << p_item->ctrl_bit_ofs);
|
|
+ }
|
|
+ if (pmic_bus_write(p_item->ctrl_reg_addr, reg_value))
|
|
+ {
|
|
+ axp_err("unable to onoff %s\n", name);
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int pmu_axp313a_get_voltage(char *name)
|
|
+{
|
|
+ u8 reg_value;
|
|
+ axp_contrl_info *p_item = NULL;
|
|
+ u8 base_step;
|
|
+ int vol;
|
|
+
|
|
+ p_item = get_ctrl_info_from_tbl(name);
|
|
+ if (!p_item)
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (pmic_bus_read(p_item->ctrl_reg_addr, ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ if (!(reg_value & (0x01 << p_item->ctrl_bit_ofs)))
|
|
+ {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (pmic_bus_read(p_item->cfg_reg_addr, ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ reg_value &= p_item->cfg_reg_mask;
|
|
+ if (p_item->split2_val)
|
|
+ {
|
|
+ u32 base_step2;
|
|
+ base_step = (p_item->split1_val - p_item->min_vol) /
|
|
+ p_item->step0_val;
|
|
+
|
|
+ base_step2 = base_step + (p_item->split2_val - p_item->split1_val) /
|
|
+ p_item->step1_val;
|
|
+
|
|
+ if (reg_value >= base_step2)
|
|
+ {
|
|
+ vol = ALIGN(p_item->split2_val, p_item->step2_val) +
|
|
+ p_item->step2_val * (reg_value - base_step2);
|
|
+ }
|
|
+ else if (reg_value >= base_step)
|
|
+ {
|
|
+ vol = p_item->split1_val +
|
|
+ p_item->step1_val * (reg_value - base_step);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vol = p_item->min_vol + p_item->step0_val * reg_value;
|
|
+ }
|
|
+ }
|
|
+ else if (p_item->split1_val)
|
|
+ {
|
|
+ base_step = (p_item->split1_val - p_item->min_vol) /
|
|
+ p_item->step0_val;
|
|
+ if (reg_value > base_step)
|
|
+ {
|
|
+ vol = p_item->split1_val +
|
|
+ p_item->step1_val * (reg_value - base_step);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vol = p_item->min_vol + p_item->step0_val * reg_value;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vol = p_item->min_vol + p_item->step0_val * reg_value;
|
|
+ }
|
|
+ return vol;
|
|
+}
|
|
+
|
|
+int pmu_axp313a_set_power_off(void)
|
|
+{
|
|
+ u8 reg_value;
|
|
+ if (pmic_bus_read(AXP313A_POWER_DOMN_SEQUENCE, ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ reg_value |= (1 << 7);
|
|
+ if (pmic_bus_write(AXP313A_POWER_DOMN_SEQUENCE, reg_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int pmu_axp313a_get_key_irq(void)
|
|
+{
|
|
+ u8 reg_value;
|
|
+ if (pmic_bus_read(AXP313A_IRQ_STATUS, ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ reg_value &= (0x03 << 4);
|
|
+ if (reg_value)
|
|
+ {
|
|
+ if (pmic_bus_write(AXP313A_IRQ_STATUS, reg_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ return (reg_value >> 4) & 3;
|
|
+}
|
|
+
|
|
+unsigned char pmu_axp313a_get_reg_value(unsigned char reg_addr)
|
|
+{
|
|
+ u8 reg_value;
|
|
+ if (pmic_bus_read(reg_addr, ®_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ return reg_value;
|
|
+}
|
|
+
|
|
+unsigned char pmu_axp313a_set_reg_value(unsigned char reg_addr, unsigned char reg_value)
|
|
+{
|
|
+ unsigned char reg;
|
|
+ if (pmic_bus_write(reg_addr, reg_value))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ if (pmic_bus_read(reg_addr, ®))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ return reg;
|
|
+}
|
|
diff --git a/include/axp313a.h b/include/axp313a.h
|
|
new file mode 100644
|
|
index 0000000000..d50d300c0f
|
|
--- /dev/null
|
|
+++ b/include/axp313a.h
|
|
@@ -0,0 +1,53 @@
|
|
+/*
|
|
+ * Copyright (C) 2016 Allwinner.
|
|
+ * weidonghui <weidonghui@allwinnertech.com>
|
|
+ *
|
|
+ * SUNXI AXP313A Driver
|
|
+ *
|
|
+ * SPDX-License-Identifier: GPL-2.0+
|
|
+ */
|
|
+
|
|
+#ifndef __AXP313A_H__
|
|
+#define __AXP313A_H__
|
|
+
|
|
+//PMIC chip id reg03:bit7-6 bit3-
|
|
+#define AXP1530_CHIP_ID (0x48)
|
|
+#define AXP313A_CHIP_ID (0x4B)
|
|
+#define AXP313B_CHIP_ID (0x4C)
|
|
+
|
|
+#define AXP313A_DEVICE_ADDR (0x3A3)
|
|
+#ifndef CONFIG_SYS_SUNXI_R_I2C0_SLAVE
|
|
+#define AXP313A_RUNTIME_ADDR (0x2d)
|
|
+#else
|
|
+#ifndef CONFIG_AXP313A_SUNXI_I2C_SLAVE
|
|
+#define AXP313A_RUNTIME_ADDR CONFIG_SYS_SUNXI_R_I2C0_SLAVE
|
|
+#else
|
|
+#define AXP313A_RUNTIME_ADDR CONFIG_AXP313A_SUNXI_I2C_SLAVE
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+/* define AXP313A REGISTER */
|
|
+#define AXP313A_POWER_ON_SOURCE_INDIVATION (0x00)
|
|
+#define AXP313A_POWER_OFF_SOURCE_INDIVATION (0x01)
|
|
+#define AXP313A_VERSION (0x03)
|
|
+#define AXP313A_OUTPUT_POWER_ON_OFF_CTL (0x10)
|
|
+#define AXP313A_DCDC_DVM_PWM_CTL (0x12)
|
|
+#define AXP313A_DC1OUT_VOL (0x13)
|
|
+#define AXP313A_DC2OUT_VOL (0x14)
|
|
+#define AXP313A_DC3OUT_VOL (0x15)
|
|
+#define AXP313A_ALDO1OUT_VOL (0x16)
|
|
+#define AXP313A_DLDO1OUT_VOL (0x17)
|
|
+#define AXP313A_POWER_DOMN_SEQUENCE (0x1A)
|
|
+#define AXP313A_PWROK_VOFF_SERT (0x1B)
|
|
+#define AXP313A_POWER_WAKEUP_CTL (0x1C)
|
|
+#define AXP313A_OUTPUT_MONITOR_CONTROL (0x1D)
|
|
+#define AXP313A_POK_SET (0x1E)
|
|
+#define AXP313A_IRQ_ENABLE (0x20)
|
|
+#define AXP313A_IRQ_STATUS (0x21)
|
|
+#define AXP313A_WRITE_LOCK (0x70)
|
|
+#define AXP313A_ERROR_MANAGEMENT (0x71)
|
|
+#define AXP313A_DCDC1_2_POWER_ON_DEFAULT_SET (0x80)
|
|
+#define AXP313A_DCDC3_ALDO1_POWER_ON_DEFAULT_SET (0x81)
|
|
+
|
|
+
|
|
+#endif /* __AXP313A_REGS_H__ */
|
|
diff --git a/include/axp_pmic.h b/include/axp_pmic.h
|
|
index 4ac6486583..6ca85ef61b 100644
|
|
--- a/include/axp_pmic.h
|
|
+++ b/include/axp_pmic.h
|
|
@@ -13,6 +13,7 @@
|
|
#include <axp209.h>
|
|
#include <axp221.h>
|
|
#include <axp305.h>
|
|
+#include <axp313a.h>
|
|
#include <axp809.h>
|
|
#include <axp818.h>
|
|
|
|
@@ -53,5 +54,7 @@ int axp_set_fldo(int fldo_num, unsigned int mvolt);
|
|
int axp_set_sw(bool on);
|
|
int axp_init(void);
|
|
int axp_get_sid(unsigned int *sid);
|
|
+int pmu_axp313a_set_voltage(char *name, unsigned int set_vol, unsigned int onoff);
|
|
+int pmu_axp313a_get_voltage(char *name);
|
|
|
|
#endif
|
|
--
|
|
2.34.1
|
|
|