mirror of
https://github.com/revyos/th1520-vendor-uboot.git
synced 2026-06-21 09:02:25 +02:00
sync: huiwei e92da50a54f00ae044eec58de8ae56cde5bb61dd
merge into 03a9fc66d7ddb7fd4ae80ad121ef1e5abd49aabd
This commit is contained in:
2
Makefile
2
Makefile
@@ -757,6 +757,8 @@ libs-y += drivers/net/phy/
|
||||
libs-y += drivers/power/ \
|
||||
drivers/power/domain/ \
|
||||
drivers/power/fuel_gauge/ \
|
||||
drivers/power/charge/ \
|
||||
drivers/mcu/ \
|
||||
drivers/power/mfd/ \
|
||||
drivers/power/pmic/ \
|
||||
drivers/power/battery/ \
|
||||
|
||||
@@ -8,6 +8,28 @@
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
charge-animation {
|
||||
compatible = "rockchip,uboot-charge";
|
||||
uboot-low-power-voltage = <7300>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
leds {
|
||||
status = "okay";
|
||||
compatible = "gpio-leds";
|
||||
red-led {
|
||||
gpios = <&gpio1_porta 14 0>; // GPIO_ACTIVE_HIGH: 0
|
||||
label = "battery_charging";
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
green-led {
|
||||
gpios = <&gpio1_porta 13 0>; // GPIO_ACTIVE_HIGH: 0
|
||||
label = "battery_full";
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0xc0000000 0x0 0x40000000>;
|
||||
@@ -120,6 +142,35 @@
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cw2015@62 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
compatible = "cellwise,cw2015";
|
||||
reg = <0x62>;
|
||||
cellwise,battery-profile = /bits/ 8
|
||||
<0x17 0x67 0x66 0x65 0x64 0x63 0x61 0x5E
|
||||
0x52 0x6D 0x4D 0x58 0x5B 0x51 0x44 0x3B
|
||||
0x33 0x2C 0x26 0x23 0x24 0x29 0x34 0x42
|
||||
0x49 0x16 0x0E 0xB8 0x3D 0x5D 0x68 0x7D
|
||||
0x78 0x75 0x7B 0x7A 0x3F 0x18 0x82 0x48
|
||||
0x09 0x4A 0x1A 0x47 0x86 0x93 0x97 0x15
|
||||
0x49 0x71 0x9A 0xC3 0x80 0x41 0x4F 0xCB
|
||||
0x2F 0x00 0x64 0xA5 0xB5 0x0D 0xB8 0x91>;
|
||||
cellwise,monitor-interval-ms = <5000>;
|
||||
cellwise,dual-cell = <1>;
|
||||
// monitored-battery = <&battery>;
|
||||
// power-supplies = <&bq25703>;
|
||||
};
|
||||
|
||||
bq25703: bq25703@6b {
|
||||
status = "okay";
|
||||
compatible = "ti,bq25703";
|
||||
reg = <0x6b>;
|
||||
ti,charge-current = <2500000>;
|
||||
ti,max-input-voltage = <5000000>;
|
||||
ti,input-current = <2000000>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c1: i2c@ffe7f24000{
|
||||
@@ -130,6 +181,12 @@
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mcu_hc32fx:mcu-hc32fx@0x4c {
|
||||
status = "okay";
|
||||
compatible = "mcu_hc32fx";
|
||||
reg = <0x4c>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c2: i2c@ffec00c000{
|
||||
|
||||
@@ -2504,6 +2504,15 @@ int board_late_init(void)
|
||||
light_usb_boot_check();
|
||||
light_mac_vaild_check();
|
||||
ap_peri_clk_disable();
|
||||
|
||||
#ifdef CONFIG_MCU_HC32fX
|
||||
mcu_poweron();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_CHARGE_DISPLAY
|
||||
charge_display();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,3 +122,12 @@ CONFIG_TPM_Z32H330TC_SPI=y
|
||||
CONFIG_CMD_TPM=y
|
||||
CONFIG_CMD_TPM_V2=y
|
||||
CONFIG_CMD_TPM_TEST=y
|
||||
CONFIG_DM_CHARGE_DISPLAY=y
|
||||
CONFIG_CHARGE_ANIMATION=y
|
||||
CONFIG_DM_FUEL_GAUGE=y
|
||||
CONFIG_POWER_FG_CW201X=y
|
||||
CONFIG_CHARGER_BQ25700=y
|
||||
CONFIG_LED=y
|
||||
CONFIG_LED_GPIO=y
|
||||
CONFIG_DM_MCU=y
|
||||
CONFIG_MCU_HC32fX=y
|
||||
|
||||
@@ -130,6 +130,8 @@ source "drivers/w1-eeprom/Kconfig"
|
||||
|
||||
source "drivers/watchdog/Kconfig"
|
||||
|
||||
source "drivers/mcu/Kconfig"
|
||||
|
||||
config PHYS_TO_BUS
|
||||
bool "Custom physical to bus address mapping"
|
||||
help
|
||||
|
||||
15
drivers/mcu/Kconfig
Executable file
15
drivers/mcu/Kconfig
Executable file
@@ -0,0 +1,15 @@
|
||||
menu "MCU Support"
|
||||
|
||||
config DM_MCU
|
||||
bool "Enable driver model for mcu device support"
|
||||
depends on DM
|
||||
help
|
||||
This adds a simple uclass for mcu device.
|
||||
|
||||
config MCU_HC32fX
|
||||
bool "Enable HC32fX MCU support"
|
||||
depends on DM_MCU
|
||||
help
|
||||
This adds a driver for the HC32fX MCU support.
|
||||
|
||||
endmenu
|
||||
9
drivers/mcu/Makefile
Executable file
9
drivers/mcu/Makefile
Executable file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# Copyright (c) 2015 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_DM_MCU) += mcu-uclass.o
|
||||
obj-$(CONFIG_MCU_HC32fX) += mcu_hc32fx.o
|
||||
65
drivers/mcu/mcu-uclass.c
Executable file
65
drivers/mcu/mcu-uclass.c
Executable file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <mcu/mcu-uclass.h>
|
||||
#include <dm/root.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
|
||||
int _mcu_shutdown(struct udevice *dev)
|
||||
{
|
||||
struct mcu_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops->shutdown)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->shutdown(dev);
|
||||
}
|
||||
|
||||
int _mcu_poweron(struct udevice *dev)
|
||||
{
|
||||
struct mcu_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops->poweron)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->poweron(dev);
|
||||
}
|
||||
|
||||
int mcu_poweron(void)
|
||||
{
|
||||
struct udevice *mcu;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device(UCLASS_MCU, 0, &mcu);
|
||||
if (ret) {
|
||||
printf("Get UCLASS_MCU failed, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return _mcu_poweron(mcu);
|
||||
}
|
||||
|
||||
int mcu_shutdown(void)
|
||||
{
|
||||
struct udevice *mcu;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device(UCLASS_MCU, 0, &mcu);
|
||||
if (ret) {
|
||||
printf("Get charge display failed, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return _mcu_shutdown(mcu);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(mcu) = {
|
||||
.id = UCLASS_MCU,
|
||||
.name = "mcu",
|
||||
};
|
||||
97
drivers/mcu/mcu_hc32fx.c
Executable file
97
drivers/mcu/mcu_hc32fx.c
Executable file
@@ -0,0 +1,97 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <mcu/mcu-uclass.h>
|
||||
#include <dm/lists.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define HC32FX_POWEROFF_20 0x20
|
||||
#define HC32FX_POWERON_30 0x30
|
||||
#define POWER_OFF 0x55
|
||||
#define POWER_ON 0x01
|
||||
|
||||
struct hc32fx_info {
|
||||
struct udevice *dev;
|
||||
};
|
||||
|
||||
static u8 hc32fx_read(struct hc32fx_info *hc32fx, u8 reg)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(hc32fx->dev, reg, &val, 1);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
hc32fx->dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int hc32fx_write(struct hc32fx_info *hc32fx, u8 reg, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(hc32fx->dev, reg, &val, 1);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
hc32fx->dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcu_hc32fx_poweron(struct udevice *dev)
|
||||
{
|
||||
struct hc32fx_info *hc32fx = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = hc32fx_write(hc32fx, HC32FX_POWERON_30, POWER_ON);
|
||||
if(ret)
|
||||
printf("set mcu POWERON fail\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcu_hc32fx_shutdown(struct udevice *dev)
|
||||
{
|
||||
struct hc32fx_info *hc32fx = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = hc32fx_write(hc32fx, HC32FX_POWEROFF_20, POWER_OFF);
|
||||
if(ret)
|
||||
printf("set mcu POWEROFF fail\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcu_gpio_probe(struct udevice *dev)
|
||||
{
|
||||
struct hc32fx_info *priv = dev_get_priv(dev);
|
||||
priv->dev = dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mcu_ops mcu_hc32fx_ops = {
|
||||
.poweron = mcu_hc32fx_poweron,
|
||||
.shutdown = mcu_hc32fx_shutdown,
|
||||
};
|
||||
|
||||
static const struct udevice_id hc32fx_ops_ids[] = {
|
||||
{ .compatible = "mcu_hc32fx" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mcu_gpio) = {
|
||||
.name = "hc32fx-mcu",
|
||||
.id = UCLASS_MCU,
|
||||
.of_match = hc32fx_ops_ids,
|
||||
.ops = &mcu_hc32fx_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct hc32fx_info),
|
||||
.probe = mcu_gpio_probe,
|
||||
};
|
||||
@@ -2,10 +2,20 @@ menu "Power"
|
||||
|
||||
source "drivers/power/domain/Kconfig"
|
||||
|
||||
source "drivers/power/fuel_gauge/Kconfig"
|
||||
|
||||
source "drivers/power/pmic/Kconfig"
|
||||
|
||||
source "drivers/power/regulator/Kconfig"
|
||||
|
||||
source "drivers/power/charge/Kconfig"
|
||||
|
||||
config DM_CHARGE_DISPLAY
|
||||
bool "Enable driver model for charge display support"
|
||||
depends on DM
|
||||
help
|
||||
This adds a simple uclass for charge display.
|
||||
|
||||
choice
|
||||
prompt "Select Sunxi PMIC Variant"
|
||||
depends on ARCH_SUNXI
|
||||
@@ -72,6 +82,13 @@ config SY8106A_POWER
|
||||
|
||||
endchoice
|
||||
|
||||
config CHARGE_ANIMATION
|
||||
bool "Enable charge animation"
|
||||
depends on DM_CHARGE_DISPLAY && DM_FUEL_GAUGE
|
||||
select ARM_CPU_SUSPEND
|
||||
help
|
||||
This adds a simple function for charge animation display.
|
||||
|
||||
config AXP_DCDC1_VOLT
|
||||
int "axp pmic dcdc1 voltage"
|
||||
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
# Copyright (c) 2009 Wind River Systems, Inc.
|
||||
# Tom Rix <Tom.Rix at windriver.com>
|
||||
|
||||
obj-$(CONFIG_DM_CHARGE_DISPLAY) += charge-display-uclass.o
|
||||
|
||||
obj-$(CONFIG_AXP152_POWER) += axp152.o
|
||||
obj-$(CONFIG_AXP209_POWER) += axp209.o
|
||||
obj-$(CONFIG_AXP221_POWER) += axp221.o
|
||||
obj-$(CONFIG_AXP809_POWER) += axp809.o
|
||||
obj-$(CONFIG_AXP818_POWER) += axp818.o
|
||||
obj-$(CONFIG_CHARGE_ANIMATION) += charge_animation.o
|
||||
obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o
|
||||
obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o
|
||||
obj-$(CONFIG_SY8106A_POWER) += sy8106a.o
|
||||
@@ -20,3 +23,4 @@ obj-$(CONFIG_DIALOG_POWER) += power_dialog.o
|
||||
obj-$(CONFIG_POWER_FSL) += power_fsl.o
|
||||
obj-$(CONFIG_POWER_I2C) += power_i2c.o
|
||||
obj-$(CONFIG_POWER_SPI) += power_spi.o
|
||||
|
||||
|
||||
40
drivers/power/charge-display-uclass.c
Executable file
40
drivers/power/charge-display-uclass.c
Executable file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <command.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <power/charge_display.h>
|
||||
|
||||
int charge_display_show(struct udevice *dev)
|
||||
{
|
||||
const struct dm_charge_display_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->show)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->show(dev);
|
||||
}
|
||||
|
||||
int charge_display(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct udevice *fg_dev;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device(UCLASS_CHARGE_DISPLAY, 0, &dev);
|
||||
if (ret) {
|
||||
debug("Get charge display failed, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return charge_display_show(dev);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(charge_display) = {
|
||||
.id = UCLASS_CHARGE_DISPLAY,
|
||||
.name = "charge_display",
|
||||
};
|
||||
5
drivers/power/charge/Kconfig
Executable file
5
drivers/power/charge/Kconfig
Executable file
@@ -0,0 +1,5 @@
|
||||
config CHARGER_BQ25700
|
||||
bool "BQ25700 charger support"
|
||||
depends on DM_FUEL_GAUGE
|
||||
help
|
||||
This adds support for BQ25700 charger support.
|
||||
7
drivers/power/charge/Makefile
Executable file
7
drivers/power/charge/Makefile
Executable file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_CHARGER_BQ25700) += bq25700_charger.o
|
||||
256
drivers/power/charge/bq25700_charger.c
Executable file
256
drivers/power/charge/bq25700_charger.c
Executable file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* (C) Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <power/fuel_gauge.h>
|
||||
#include <power/pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define BQ25700_ID 0x25700
|
||||
#define BQ25703_ID 0x25703
|
||||
|
||||
#define COMPAT_BQ25700 "ti,bq25700"
|
||||
#define COMPAT_BQ25703 "ti,bq25703"
|
||||
|
||||
#define BQ25700_I2C_SPEED 100000
|
||||
#define BQ25700_CHARGE_CURRENT_1500MA 0x5C0
|
||||
#define BQ25700_SDP_INPUT_CURRENT_500MA 0xA00
|
||||
#define BQ25700_DCP_INPUT_CURRENT_1500MA 0x1E00
|
||||
#define BQ25700_DCP_INPUT_CURRENT_2000MA 0x2800
|
||||
#define BQ25700_DCP_INPUT_CURRENT_3000MA 0x3C00
|
||||
|
||||
#define WATCHDOG_ENSABLE (0x03 << 13)
|
||||
|
||||
#define BQ25700_CHARGEOPTION0_REG 0x12
|
||||
#define BQ25700_CHARGECURREN_REG 0x14
|
||||
#define BQ25700_CHARGERSTAUS_REG 0x20
|
||||
#define BQ25700_INPUTVOLTAGE_REG 0x3D
|
||||
#define BQ25700_INPUTCURREN_REG 0x3F
|
||||
|
||||
#define BQ25703_CHARGEOPTION0_REG 0x00
|
||||
#define BQ25703_CHARGECURREN_REG 0x02
|
||||
#define BQ25703_CHARGERSTAUS_REG 0x20
|
||||
#define BQ25703_INPUTVOLTAGE_REG 0x0A
|
||||
#define BQ25703_INPUTCURREN_REG 0x0E
|
||||
|
||||
enum bq25700_table_ids {
|
||||
/* range tables */
|
||||
TBL_ICHG,
|
||||
TBL_CHGMAX,
|
||||
TBL_INPUTVOL,
|
||||
TBL_INPUTCUR,
|
||||
TBL_SYSVMIN,
|
||||
TBL_OTGVOL,
|
||||
TBL_OTGCUR,
|
||||
TBL_EXTCON,
|
||||
};
|
||||
|
||||
struct bq25700 {
|
||||
struct udevice *dev;
|
||||
u32 ichg;
|
||||
u32 chip_id;
|
||||
};
|
||||
|
||||
struct bq25700_range {
|
||||
u32 min;
|
||||
u32 max;
|
||||
u32 step;
|
||||
};
|
||||
|
||||
static int bq25700_read(struct bq25700 *charger, uint reg)
|
||||
{
|
||||
u16 val;
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(charger->dev, reg, (u8 *)&val, 2);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
charger->dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int bq25700_write(struct bq25700 *charger, uint reg, u16 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(charger->dev, reg, (u8 *)&val, 2);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
charger->dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const union {
|
||||
struct bq25700_range rt;
|
||||
} bq25700_tables[] = {
|
||||
/* range tables */
|
||||
[TBL_ICHG] = { .rt = {0, 8128000, 64000} },
|
||||
/* uV */
|
||||
[TBL_CHGMAX] = { .rt = {0, 19200000, 16000} },
|
||||
/* uV max charge voltage*/
|
||||
[TBL_INPUTVOL] = { .rt = {3200000, 19520000, 64000} },
|
||||
/* uV input charge voltage*/
|
||||
[TBL_INPUTCUR] = {.rt = {0, 6350000, 50000} },
|
||||
/*uA input current*/
|
||||
[TBL_SYSVMIN] = { .rt = {1024000, 16182000, 256000} },
|
||||
/* uV min system voltage*/
|
||||
[TBL_OTGVOL] = {.rt = {4480000, 20800000, 64000} },
|
||||
/*uV OTG volage*/
|
||||
[TBL_OTGCUR] = {.rt = {0, 6350000, 50000} },
|
||||
};
|
||||
|
||||
static u32 bq25700_find_idx(u32 value, enum bq25700_table_ids id)
|
||||
{
|
||||
const struct bq25700_range *rtbl = &bq25700_tables[id].rt;
|
||||
u32 rtbl_size;
|
||||
u32 idx;
|
||||
|
||||
rtbl_size = (rtbl->max - rtbl->min) / rtbl->step + 1;
|
||||
|
||||
for (idx = 1;
|
||||
idx < rtbl_size && (idx * rtbl->step + rtbl->min <= value);
|
||||
idx++)
|
||||
;
|
||||
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
static bool bq25700_charger_status(struct bq25700 *charger)
|
||||
{
|
||||
int state_of_charger;
|
||||
u16 value;
|
||||
|
||||
value = bq25700_read(charger, BQ25700_CHARGERSTAUS_REG);
|
||||
state_of_charger = value >> 15;
|
||||
|
||||
return state_of_charger;
|
||||
}
|
||||
|
||||
static bool bq25703_charger_status(struct bq25700 *charger)
|
||||
{
|
||||
int state_of_charger;
|
||||
u16 value;
|
||||
|
||||
value = bq25700_read(charger, BQ25703_CHARGERSTAUS_REG);
|
||||
state_of_charger = value >> 15;
|
||||
|
||||
return state_of_charger;
|
||||
}
|
||||
|
||||
static bool bq257xx_charger_status(struct udevice *dev)
|
||||
{
|
||||
struct bq25700 *charger = dev_get_priv(dev);
|
||||
|
||||
if (charger->chip_id == BQ25700_ID)
|
||||
return bq25700_charger_status(charger);
|
||||
else
|
||||
return bq25703_charger_status(charger);
|
||||
}
|
||||
|
||||
static int bq25700_charger_capability(struct udevice *dev)
|
||||
{
|
||||
return FG_CAP_CHARGER;
|
||||
}
|
||||
|
||||
static int bq25700_get_usb_type(void)
|
||||
{
|
||||
#ifdef CONFIG_PHY_ROCKCHIP_INNO_USB2
|
||||
return rockchip_chg_get_type();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void bq25703_charger_current_init(struct bq25700 *charger)
|
||||
{
|
||||
u16 vol_idx = 0, cur_idx, chr_idx;
|
||||
u16 temp;
|
||||
|
||||
temp = bq25700_read(charger, BQ25703_CHARGEOPTION0_REG);
|
||||
temp &= (~WATCHDOG_ENSABLE);
|
||||
bq25700_write(charger, BQ25703_CHARGEOPTION0_REG, temp);
|
||||
|
||||
vol_idx = bq25700_find_idx((5000000 - 1280000 - 3200000), TBL_INPUTVOL);
|
||||
vol_idx = vol_idx << 6;
|
||||
cur_idx = bq25700_find_idx(2500000, TBL_INPUTCUR);
|
||||
cur_idx = cur_idx << 8;
|
||||
chr_idx = bq25700_find_idx(2500000, TBL_ICHG);
|
||||
chr_idx = chr_idx << 6;
|
||||
|
||||
bq25700_write(charger, BQ25703_INPUTCURREN_REG, cur_idx); //0x0E
|
||||
bq25700_write(charger, BQ25703_INPUTVOLTAGE_REG, vol_idx); //0x0A
|
||||
bq25700_write(charger, BQ25703_CHARGECURREN_REG, chr_idx); //0x02
|
||||
|
||||
}
|
||||
|
||||
static int bq25700_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct bq25700 *charger = dev_get_priv(dev);
|
||||
const void *blob = gd->fdt_blob;
|
||||
int node, node1;
|
||||
|
||||
charger->dev = dev;
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, 0, COMPAT_BQ25700);
|
||||
node1 = fdt_node_offset_by_compatible(blob, 0, COMPAT_BQ25703);
|
||||
if ((node < 0) && (node1 < 0)) {
|
||||
printf("Can't find dts node for charger bq25700\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (node < 0) {
|
||||
node = node1;
|
||||
charger->chip_id = BQ25703_ID;
|
||||
} else {
|
||||
charger->chip_id = BQ25700_ID;
|
||||
}
|
||||
|
||||
charger->ichg = fdtdec_get_int(blob, node, "ti,charge-current", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq25700_probe(struct udevice *dev)
|
||||
{
|
||||
struct bq25700 *charger = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
if (charger->chip_id == BQ25703_ID)
|
||||
bq25703_charger_current_init(charger);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id charger_ids[] = {
|
||||
{ .compatible = "ti,bq25700" },
|
||||
{ .compatible = "ti,bq25703" },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct dm_fuel_gauge_ops charger_ops = {
|
||||
.get_chrg_online = bq257xx_charger_status,
|
||||
.capability = bq25700_charger_capability,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(bq25700_charger) = {
|
||||
.name = "bq25700_charger",
|
||||
.id = UCLASS_FG,
|
||||
.probe = bq25700_probe,
|
||||
.of_match = charger_ids,
|
||||
.ops = &charger_ops,
|
||||
.ofdata_to_platdata = bq25700_ofdata_to_platdata,
|
||||
.priv_auto_alloc_size = sizeof(struct bq25700),
|
||||
};
|
||||
245
drivers/power/charge_animation.c
Executable file
245
drivers/power/charge_animation.c
Executable file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <led.h>
|
||||
#include <rtc.h>
|
||||
#include <pwm.h>
|
||||
#include <power/charge_display.h>
|
||||
#include <power/charge_animation.h>
|
||||
#include <power/fuel_gauge.h>
|
||||
#include <power/pmic.h>
|
||||
#include <mcu/mcu-uclass.h>
|
||||
#ifdef CONFIG_IRQ
|
||||
#include <irq-generic.h>
|
||||
#include <rk_timer_irq.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define IMAGE_RECALC_IDX -1
|
||||
#define IMAGE_SOC_100_IDX(n) ((n) - 2)
|
||||
#define IMAGE_LOWPOWER_IDX(n) ((n) - 1)
|
||||
#define SYSTEM_SUSPEND_DELAY_MS 5000
|
||||
#define FUEL_GAUGE_POLL_MS 1000
|
||||
|
||||
#define LED_CHARGING_NAME "battery_charging"
|
||||
#define LED_CHARGING_FULL_NAME "battery_full"
|
||||
|
||||
struct charge_image {
|
||||
const char *name;
|
||||
int soc;
|
||||
int period; /* ms */
|
||||
};
|
||||
|
||||
struct charge_animation_priv {
|
||||
struct udevice *fg;
|
||||
struct udevice *charger;
|
||||
struct udevice *mcu;
|
||||
#ifdef CONFIG_LED
|
||||
struct udevice *led_charging;
|
||||
struct udevice *led_full;
|
||||
#endif
|
||||
const struct charge_image *image;
|
||||
int image_num;
|
||||
|
||||
int auto_wakeup_key_state;
|
||||
ulong auto_screen_off_timeout; /* ms */
|
||||
ulong suspend_delay_timeout; /* ms */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LED
|
||||
static int leds_update(struct udevice *dev, int soc)
|
||||
{
|
||||
struct charge_animation_priv *priv = dev_get_priv(dev);
|
||||
static int old_soc = -1;
|
||||
int ret, ledst;
|
||||
|
||||
if (old_soc == soc)
|
||||
return 0;
|
||||
|
||||
old_soc = soc;
|
||||
if (priv->led_charging) {
|
||||
ledst = (soc < 100) ? LEDST_ON : LEDST_OFF;
|
||||
ret = led_set_state(priv->led_charging, ledst);
|
||||
if (ret) {
|
||||
printf("set charging led %s failed, ret=%d\n",
|
||||
(ledst == LEDST_ON) ? "ON" : "OFF", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->led_full) {
|
||||
ledst = (soc == 100) ? LEDST_ON : LEDST_OFF;
|
||||
ret = led_set_state(priv->led_full, ledst);
|
||||
if (ret) {
|
||||
printf("set charging full led %s failed, ret=%d\n",
|
||||
ledst == LEDST_ON ? "ON" : "OFF", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int leds_update(struct udevice *dev, int soc) { return 0; }
|
||||
#endif
|
||||
|
||||
static int charge_animation_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct charge_animation_pdata *pdata = dev_get_platdata(dev);
|
||||
pdata->low_power_voltage =
|
||||
dev_read_u32_default(dev, "uboot-low-power-voltage", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fg_charger_get_chrg_online(struct udevice *dev)
|
||||
{
|
||||
struct charge_animation_priv *priv = dev_get_priv(dev);
|
||||
struct udevice *charger;
|
||||
|
||||
charger = priv->charger ? : priv->fg;
|
||||
|
||||
return fuel_gauge_get_chrg_online(charger);
|
||||
}
|
||||
|
||||
static int charge_animation_show(struct udevice *dev)
|
||||
{
|
||||
int soc, voltage, ret, charging = 0;
|
||||
struct charge_animation_priv *priv = dev_get_priv(dev);
|
||||
struct charge_animation_pdata *pdata = dev_get_platdata(dev);
|
||||
struct udevice *fg = priv->fg;
|
||||
struct udevice *mcu = priv->mcu;
|
||||
|
||||
voltage = fuel_gauge_get_voltage(fg);
|
||||
if (voltage < 0)
|
||||
return -EINVAL;
|
||||
|
||||
while (voltage < pdata->low_power_voltage + 50) {
|
||||
soc = fuel_gauge_update_get_soc(fg);
|
||||
if (soc < 0 || soc > 100) {
|
||||
printf("get soc failed: %d\n", soc);
|
||||
continue;
|
||||
} else if (soc >= 1) {
|
||||
printf("soc is: %d\n", soc);
|
||||
break;
|
||||
}
|
||||
|
||||
voltage = fuel_gauge_get_voltage(fg);
|
||||
if (voltage < 0) {
|
||||
printf("get voltage failed: %d\n", voltage);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = leds_update(dev, soc);
|
||||
if (ret)
|
||||
printf("update led failed: %d\n", ret);
|
||||
|
||||
printf("soc is: %d voltage is :%d\n", soc, voltage);
|
||||
|
||||
charging = fg_charger_get_chrg_online(dev);
|
||||
if (charging <= 0) {
|
||||
mcu_shutdown(); // shutdown system power
|
||||
}
|
||||
mdelay(100);
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fg_charger_get_device(struct udevice **fuel_gauge,
|
||||
struct udevice **charger)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct uclass *uc;
|
||||
int ret, cap;
|
||||
|
||||
*fuel_gauge = NULL,
|
||||
*charger = NULL;
|
||||
|
||||
ret = uclass_get(UCLASS_FG, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (uclass_first_device(UCLASS_FG, &dev);
|
||||
dev;
|
||||
uclass_next_device(&dev)) {
|
||||
cap = fuel_gauge_capability(dev);
|
||||
if (cap == (FG_CAP_CHARGER | FG_CAP_FUEL_GAUGE)) {
|
||||
*fuel_gauge = dev;
|
||||
*charger = NULL;
|
||||
} else if (cap == FG_CAP_FUEL_GAUGE) {
|
||||
*fuel_gauge = dev;
|
||||
} else if (cap == FG_CAP_CHARGER) {
|
||||
*charger = dev;
|
||||
}
|
||||
}
|
||||
|
||||
return (*fuel_gauge) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static const struct dm_charge_display_ops charge_animation_ops = {
|
||||
.show = charge_animation_show,
|
||||
};
|
||||
|
||||
static int charge_animation_probe(struct udevice *dev)
|
||||
{
|
||||
struct charge_animation_priv *priv = dev_get_priv(dev);
|
||||
int ret, soc;
|
||||
/* Get PMIC: used for power off system */
|
||||
ret = uclass_get_device(UCLASS_MCU, 0, &priv->mcu);
|
||||
if (ret) {
|
||||
if (ret == -ENODEV)
|
||||
printf("Can't find MCU\n");
|
||||
else
|
||||
printf("Get UCLASS MCU failed: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Get fuel gauge and charger(If need) */
|
||||
ret = fg_charger_get_device(&priv->fg, &priv->charger);
|
||||
if (ret) {
|
||||
if (ret == -ENODEV)
|
||||
debug("Can't find FG\n");
|
||||
else
|
||||
debug("Get UCLASS FG failed: %d\n", ret);
|
||||
// return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_LED
|
||||
ret = led_get_by_label(LED_CHARGING_NAME, &priv->led_charging);
|
||||
if (!ret)
|
||||
printf("Found Charging LED \n");
|
||||
|
||||
ret = led_get_by_label(LED_CHARGING_FULL_NAME, &priv->led_full);
|
||||
if (!ret)
|
||||
printf("Found Charging-Full LED\n");
|
||||
#endif
|
||||
|
||||
printf("Enable charge animation display\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id charge_animation_ids[] = {
|
||||
{ .compatible = "rockchip,uboot-charge" },
|
||||
{ },
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(charge_animation) = {
|
||||
.name = "charge-animation",
|
||||
.id = UCLASS_CHARGE_DISPLAY,
|
||||
.probe = charge_animation_probe,
|
||||
.of_match = charge_animation_ids,
|
||||
.ops = &charge_animation_ops,
|
||||
.ofdata_to_platdata = charge_animation_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct charge_animation_pdata),
|
||||
.priv_auto_alloc_size = sizeof(struct charge_animation_priv),
|
||||
};
|
||||
11
drivers/power/fuel_gauge/Kconfig
Executable file
11
drivers/power/fuel_gauge/Kconfig
Executable file
@@ -0,0 +1,11 @@
|
||||
config DM_FUEL_GAUGE
|
||||
bool "Enable driver model fuel gauge support"
|
||||
depends on DM
|
||||
help
|
||||
This adds a simple uclass for fuel gauge.
|
||||
|
||||
config POWER_FG_CW201X
|
||||
bool "CW201X Fuel gauge support"
|
||||
depends on DM_FUEL_GAUGE
|
||||
help
|
||||
This adds support for CW201X fuel gauge support.
|
||||
@@ -3,4 +3,7 @@
|
||||
# Copyright (C) 2012 Samsung Electronics
|
||||
# Lukasz Majewski <l.majewski@samsung.com>
|
||||
|
||||
obj-$(CONFIG_$(SPL_)DM_FUEL_GAUGE) += fuel_gauge_uclass.o
|
||||
|
||||
obj-$(CONFIG_POWER_FG_MAX17042) += fg_max17042.o
|
||||
obj-$(CONFIG_POWER_FG_CW201X) += fg_cw201x.o
|
||||
|
||||
415
drivers/power/fuel_gauge/fg_cw201x.c
Executable file
415
drivers/power/fuel_gauge/fg_cw201x.c
Executable file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
* (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
// #include <linux/usb/phy-rockchip-usb2.h>
|
||||
#include <malloc.h>
|
||||
#include <power/battery.h>
|
||||
#include <power/fuel_gauge.h>
|
||||
// #include <power/pmic.h>
|
||||
#include "fg_regs.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define COMPAT_ROCKCHIP_CW201X "cw201x"
|
||||
|
||||
#define REG_VERSION 0x0
|
||||
#define REG_VCELL 0x2
|
||||
#define REG_SOC 0x4
|
||||
#define REG_RRT_ALERT 0x6
|
||||
#define REG_CONFIG 0x8
|
||||
#define REG_MODE 0xA
|
||||
#define REG_BATINFO 0x10
|
||||
|
||||
#define MODE_SLEEP_MASK (0x3 << 6)
|
||||
#define MODE_SLEEP (0x3 << 6)
|
||||
#define MODE_NORMAL (0x0 << 6)
|
||||
#define MODE_QUICK_START (0x3 << 4)
|
||||
#define MODE_RESTART (0xf << 0)
|
||||
|
||||
#define CONFIG_UPDATE_FLG (0x1 << 1)
|
||||
#define ATHD (0x0 << 3)
|
||||
|
||||
enum charger_type {
|
||||
CHARGER_TYPE_NO = 0,
|
||||
CHARGER_TYPE_USB,
|
||||
CHARGER_TYPE_AC,
|
||||
CHARGER_TYPE_DC,
|
||||
CHARGER_TYPE_UNDEF,
|
||||
};
|
||||
|
||||
struct cw201x_info {
|
||||
struct udevice *dev;
|
||||
int capacity;
|
||||
u32 *cw_bat_config_info;
|
||||
int divider_res1;
|
||||
int divider_res2;
|
||||
int hw_id_check;
|
||||
struct gpio_desc hw_id0;
|
||||
struct gpio_desc hw_id1;
|
||||
int support_dc_adp;
|
||||
struct gpio_desc dc_det_gpio;
|
||||
int dc_det_flag;
|
||||
bool dual_cell;
|
||||
};
|
||||
|
||||
static u8 cw201x_read(struct cw201x_info *cw201x, u8 reg)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(cw201x->dev, reg, &val, 1);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
cw201x->dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int cw201x_write(struct cw201x_info *cw201x, u8 reg, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(cw201x->dev, reg, &val, 1);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
cw201x->dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 cw201x_read_half_word(struct cw201x_info *cw201x, int reg)
|
||||
{
|
||||
u8 vall, valh;
|
||||
u16 val;
|
||||
|
||||
valh = cw201x_read(cw201x, reg);
|
||||
vall = cw201x_read(cw201x, reg + 1);
|
||||
val = ((u16)valh << 8) | vall;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int cw201x_parse_config_info(struct cw201x_info *cw201x)
|
||||
{
|
||||
int ret;
|
||||
int i, len, size;
|
||||
const u8 *info;
|
||||
struct udevice *dev = cw201x->dev;
|
||||
|
||||
if (dev_read_prop(dev, "bat_config_info", &len)) {
|
||||
len /= sizeof(u32);
|
||||
size = sizeof(*cw201x->cw_bat_config_info) * len;
|
||||
cw201x->cw_bat_config_info = calloc(size, 1);
|
||||
if (!cw201x->cw_bat_config_info) {
|
||||
printf("calloc cw_bat_config_info fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = dev_read_u32_array(dev, "bat_config_info",
|
||||
cw201x->cw_bat_config_info, len);
|
||||
if (ret) {
|
||||
printf("fdtdec_get cw_bat_config_info fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dev_read_prop(dev, "cellwise,battery-profile", &len))
|
||||
return -EINVAL;
|
||||
|
||||
size = sizeof(*cw201x->cw_bat_config_info) * len;
|
||||
cw201x->cw_bat_config_info = calloc(size, 1);
|
||||
if (!cw201x->cw_bat_config_info) {
|
||||
printf("calloc cw_bat_config_info fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info = dev_read_u8_array_ptr(dev, "cellwise,battery-profile", len);
|
||||
if (!info) {
|
||||
printf("fdtdec_get battery profile fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
cw201x->cw_bat_config_info[i] = info[i];
|
||||
printf("%#x ", cw201x->cw_bat_config_info[i]);
|
||||
if ((i+1) % 8 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw201x_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct cw201x_info *cw201x = dev_get_priv(dev);
|
||||
int ret;
|
||||
int hw_id0_val, hw_id1_val;
|
||||
|
||||
cw201x->dev = dev;
|
||||
ret = cw201x_parse_config_info(cw201x);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cw201x->dual_cell = dev_read_bool(dev, "cellwise,dual-cell");
|
||||
ret = gpio_request_by_name_nodev(dev_ofnode(dev), "dc_det_gpio",
|
||||
0, &cw201x->dc_det_gpio, GPIOD_IS_IN);
|
||||
if (!ret) {
|
||||
cw201x->support_dc_adp = 1;
|
||||
printf("DC is valid\n");
|
||||
} else {
|
||||
printf("DC is invalid, ret=%d\n", ret);
|
||||
}
|
||||
|
||||
cw201x->hw_id_check = dev_read_u32_default(dev, "hw_id_check", 0);
|
||||
if (cw201x->hw_id_check) {
|
||||
ret = gpio_request_by_name_nodev(dev_ofnode(dev),
|
||||
"hw_id0_gpio", 0,
|
||||
&cw201x->hw_id0, GPIOD_IS_IN);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
hw_id0_val = dm_gpio_get_value(&cw201x->hw_id0);
|
||||
|
||||
ret = gpio_request_by_name_nodev(dev_ofnode(dev),
|
||||
"hw_id1_gpio", 0,
|
||||
&cw201x->hw_id1, GPIOD_IS_IN);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
hw_id1_val = dm_gpio_get_value(&cw201x->hw_id1);
|
||||
|
||||
/* ID1 = 0, ID0 = 1 : Battery */
|
||||
if (!hw_id0_val || hw_id1_val)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cw201x->divider_res1 = dev_read_u32_default(dev, "divider_res1", 0);
|
||||
cw201x->divider_res2 = dev_read_u32_default(dev, "divider_res2", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw201x_get_vol(struct cw201x_info *cw201x)
|
||||
{
|
||||
u16 value16, value16_1, value16_2, value16_3;
|
||||
int voltage;
|
||||
int res1, res2;
|
||||
int retry = 0;
|
||||
|
||||
__retry:
|
||||
value16 = cw201x_read_half_word(cw201x, REG_VCELL);
|
||||
if (value16 < 0)
|
||||
return -1;
|
||||
|
||||
value16_1 = cw201x_read_half_word(cw201x, REG_VCELL);
|
||||
if (value16_1 < 0)
|
||||
return -1;
|
||||
|
||||
value16_2 = cw201x_read_half_word(cw201x, REG_VCELL);
|
||||
if (value16_2 < 0)
|
||||
return -1;
|
||||
|
||||
if (value16 > value16_1) {
|
||||
value16_3 = value16;
|
||||
value16 = value16_1;
|
||||
value16_1 = value16_3;
|
||||
}
|
||||
|
||||
if (value16_1 > value16_2) {
|
||||
value16_3 = value16_1;
|
||||
value16_1 = value16_2;
|
||||
value16_2 = value16_3;
|
||||
}
|
||||
|
||||
if (value16 > value16_1) {
|
||||
value16_3 = value16;
|
||||
value16 = value16_1;
|
||||
value16_1 = value16_3;
|
||||
}
|
||||
|
||||
voltage = value16_1 * 312 / 1024;
|
||||
if (voltage <= 0 && retry < 10) {
|
||||
retry++;
|
||||
mdelay(20);
|
||||
goto __retry;
|
||||
}
|
||||
|
||||
if (cw201x->divider_res1 &&
|
||||
cw201x->divider_res2) {
|
||||
res1 = cw201x->divider_res1;
|
||||
res2 = cw201x->divider_res2;
|
||||
voltage = voltage * (res1 + res2) / res2;
|
||||
}
|
||||
|
||||
if (cw201x->dual_cell)
|
||||
voltage *= 2;
|
||||
|
||||
// printf("the cw201x voltage=%d\n", voltage);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
static int cw201x_dwc_otg_check_dpdm(void)
|
||||
{
|
||||
#if defined(CONFIG_PHY_ROCKCHIP_INNO_USB2) && !defined(CONFIG_SPL_BUILD)
|
||||
return rockchip_chg_get_type();
|
||||
#else
|
||||
printf("rockchip_chg_get_type() is not implement\n");
|
||||
return CHARGER_TYPE_NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int cw201x_get_usb_state(struct cw201x_info *cw201x)
|
||||
{
|
||||
int charger_type;
|
||||
|
||||
switch (cw201x_dwc_otg_check_dpdm()) {
|
||||
case 0:
|
||||
charger_type = CHARGER_TYPE_NO;
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
charger_type = CHARGER_TYPE_USB;
|
||||
break;
|
||||
case 2:
|
||||
charger_type = CHARGER_TYPE_AC;
|
||||
break;
|
||||
default:
|
||||
charger_type = CHARGER_TYPE_NO;
|
||||
break;
|
||||
}
|
||||
|
||||
return charger_type;
|
||||
}
|
||||
|
||||
static bool cw201x_get_dc_state(struct cw201x_info *cw201x)
|
||||
{
|
||||
if (dm_gpio_get_value(&cw201x->dc_det_gpio))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool cw201x_check_charge(struct cw201x_info *cw201x)
|
||||
{
|
||||
if (cw201x_get_usb_state(cw201x) != CHARGER_TYPE_NO)
|
||||
return true;
|
||||
if (cw201x_get_dc_state(cw201x))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cw201x_get_soc(struct cw201x_info *cw201x)
|
||||
{
|
||||
int cap, i = 0;
|
||||
|
||||
while (i < 10) {
|
||||
mdelay(30);
|
||||
cap = cw201x_read(cw201x, REG_SOC);
|
||||
if ((cap < 0) || (cap > 100))
|
||||
cap = cw201x->capacity;
|
||||
i++;
|
||||
if (cap)
|
||||
break;
|
||||
}
|
||||
cw201x->capacity = cap;
|
||||
|
||||
return cw201x->capacity;
|
||||
}
|
||||
|
||||
static int cw201x_update_get_soc(struct udevice *dev)
|
||||
{
|
||||
struct cw201x_info *cw201x = dev_get_priv(dev);
|
||||
|
||||
return cw201x_get_soc(cw201x);
|
||||
}
|
||||
|
||||
static int cw201x_update_get_voltage(struct udevice *dev)
|
||||
{
|
||||
struct cw201x_info *cw201x = dev_get_priv(dev);
|
||||
|
||||
return cw201x_get_vol(cw201x);
|
||||
}
|
||||
|
||||
static int cw201x_update_get_current(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cw201x_update_get_chrg_online(struct udevice *dev)
|
||||
{
|
||||
struct cw201x_info *cw201x = dev_get_priv(dev);
|
||||
|
||||
return cw201x_check_charge(cw201x);
|
||||
}
|
||||
|
||||
static int cw201x_capability(struct udevice *dev)
|
||||
{
|
||||
return FG_CAP_FUEL_GAUGE;
|
||||
}
|
||||
|
||||
static struct dm_fuel_gauge_ops cw201x_fg_ops = {
|
||||
.capability = cw201x_capability,
|
||||
.get_soc = cw201x_update_get_soc,
|
||||
.get_voltage = cw201x_update_get_voltage,
|
||||
.get_current = cw201x_update_get_current,
|
||||
.get_chrg_online = cw201x_update_get_chrg_online,
|
||||
};
|
||||
|
||||
static int cw201x_fg_cfg(struct cw201x_info *cw201x)
|
||||
{
|
||||
u8 val = MODE_SLEEP;
|
||||
int i;
|
||||
|
||||
if ((val & MODE_SLEEP_MASK) == MODE_SLEEP) {
|
||||
val = MODE_NORMAL;
|
||||
cw201x_write(cw201x, REG_MODE, val);
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
cw201x_write(cw201x, REG_BATINFO + i,
|
||||
(u8)cw201x->cw_bat_config_info[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw201x_fg_probe(struct udevice *dev)
|
||||
{
|
||||
struct cw201x_info *cw201x = dev_get_priv(dev);
|
||||
|
||||
cw201x->dev = dev;
|
||||
cw201x_fg_cfg(cw201x);
|
||||
|
||||
printf("vol: %d, soc: %d\n",
|
||||
cw201x_get_vol(cw201x), cw201x_get_soc(cw201x));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id cw201x_ids[] = {
|
||||
{ .compatible = "cw201x" },
|
||||
{ .compatible = "cellwise,cw2015" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(cw201x_fg) = {
|
||||
.name = "cw201x_fg",
|
||||
.id = UCLASS_FG,
|
||||
.of_match = cw201x_ids,
|
||||
.probe = cw201x_fg_probe,
|
||||
.ofdata_to_platdata = cw201x_ofdata_to_platdata,
|
||||
.ops = &cw201x_fg_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct cw201x_info),
|
||||
};
|
||||
95
drivers/power/fuel_gauge/fg_regs.h
Executable file
95
drivers/power/fuel_gauge/fg_regs.h
Executable file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _FG_RK8XX_H_
|
||||
#define _FG_RK8XX_H_
|
||||
|
||||
/* register definition */
|
||||
#define SECONDS_REG 0X00
|
||||
#define VB_MON_REG 0x21
|
||||
#define THERMAL_REG 0x22
|
||||
#define SUP_STS_REG 0xA0
|
||||
#define USB_CTRL_REG 0xA1
|
||||
#define CHRG_CTRL_REG1 0xA3
|
||||
#define CHRG_CTRL_REG2 0xA4
|
||||
#define CHRG_CTRL_REG3 0xA5
|
||||
#define BAT_CTRL_REG 0xA6
|
||||
#define BAT_HTS_TS_REG 0xA8
|
||||
#define BAT_LTS_TS_REG 0xA9
|
||||
#define TS_CTRL_REG 0xAC
|
||||
#define ADC_CTRL_REG 0xAD
|
||||
#define GGCON_REG 0xB0
|
||||
#define GGSTS_REG 0xB1
|
||||
#define ZERO_CUR_ADC_REGH 0xB2
|
||||
#define ZERO_CUR_ADC_REGL 0xB3
|
||||
#define GASCNT_CAL_REG3 0xB4
|
||||
#define GASCNT_CAL_REG2 0xB5
|
||||
#define GASCNT_CAL_REG1 0xB6
|
||||
#define GASCNT_CAL_REG0 0xB7
|
||||
#define GASCNT_REG3 0xB8
|
||||
#define GASCNT_REG2 0xB9
|
||||
#define GASCNT_REG1 0xBA
|
||||
#define GASCNT_REG0 0xBB
|
||||
#define BAT_CUR_AVG_REGH 0xBC
|
||||
#define BAT_CUR_AVG_REGL 0xBD
|
||||
#define TS_ADC_REGH 0xBE
|
||||
#define TS_ADC_REGL 0xBF
|
||||
#define RK818_TS2_ADC_REGH 0xC0
|
||||
#define RK818_TS2_ADC_REGL 0xC1
|
||||
#define RK816_USB_ADC_REGH 0xC0
|
||||
#define RK816_USB_ADC_REGL 0xC1
|
||||
#define BAT_OCV_REGH 0xC2
|
||||
#define BAT_OCV_REGL 0xC3
|
||||
#define BAT_VOL_REGH 0xC4
|
||||
#define BAT_VOL_REGL 0xC5
|
||||
#define RELAX_ENTRY_THRES_REGH 0xC6
|
||||
#define RELAX_ENTRY_THRES_REGL 0xC7
|
||||
#define RELAX_EXIT_THRES_REGH 0xC8
|
||||
#define RELAX_EXIT_THRES_REGL 0xC9
|
||||
#define RELAX_VOL1_REGH 0xCA
|
||||
#define RELAX_VOL1_REGL 0xCB
|
||||
#define RELAX_VOL2_REGH 0xCC
|
||||
#define RELAX_VOL2_REGL 0xCD
|
||||
#define RELAX_CUR1_REGH 0xCE
|
||||
#define RELAX_CUR1_REGL 0xCF
|
||||
#define RELAX_CUR2_REGH 0xD0
|
||||
#define RELAX_CUR2_REGL 0xD1
|
||||
#define CAL_OFFSET_REGH 0xD2
|
||||
#define CAL_OFFSET_REGL 0xD3
|
||||
#define NON_ACT_TIMER_CNT_REG 0xD4
|
||||
#define VCALIB0_REGH 0xD5
|
||||
#define VCALIB0_REGL 0xD6
|
||||
#define VCALIB1_REGH 0xD7
|
||||
#define VCALIB1_REGL 0xD8
|
||||
#define FCC_GASCNT_REG3 0xD9
|
||||
#define FCC_GASCNT_REG2 0xDA
|
||||
#define FCC_GASCNT_REG1 0xDB
|
||||
#define FCC_GASCNT_REG0 0xDC
|
||||
#define IOFFSET_REGH 0xDD
|
||||
#define IOFFSET_REGL 0xDE
|
||||
#define SLEEP_CON_SAMP_CUR_REG 0xDF
|
||||
#define SOC_REG 0xE0
|
||||
#define REMAIN_CAP_REG3 0xE1
|
||||
#define REMAIN_CAP_REG2 0xE2
|
||||
#define REMAIN_CAP_REG1 0xE3
|
||||
#define REMAIN_CAP_REG0 0xE4
|
||||
#define UPDAT_LEVE_REG 0xE5
|
||||
#define NEW_FCC_REG3 0xE6
|
||||
#define NEW_FCC_REG2 0xE7
|
||||
#define NEW_FCC_REG1 0xE8
|
||||
#define NEW_FCC_REG0 0xE9
|
||||
#define NON_ACT_TIMER_CNT_SAVE_REG 0xEA
|
||||
#define OCV_VOL_VALID_REG 0xEB
|
||||
#define REBOOT_CNT_REG 0xEC
|
||||
#define POFFSET_REG 0xED
|
||||
#define MISC_MARK_REG 0xEE
|
||||
#define HALT_CNT_REG 0xEF
|
||||
#define DATA15_REG 0xEF
|
||||
#define DATA16_REG 0xF0
|
||||
#define DATA17_REG 0xF1
|
||||
#define DATA18_REG 0xF2
|
||||
|
||||
#endif
|
||||
136
drivers/power/fuel_gauge/fuel_gauge_uclass.c
Executable file
136
drivers/power/fuel_gauge/fuel_gauge_uclass.c
Executable file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <power/fuel_gauge.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int fuel_gauge_capability(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->capability)
|
||||
return (FG_CAP_CHARGER | FG_CAP_FUEL_GAUGE);
|
||||
|
||||
return ops->capability(dev);
|
||||
}
|
||||
|
||||
int fuel_gauge_bat_is_exist(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->bat_is_exist)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->bat_is_exist(dev);
|
||||
}
|
||||
|
||||
int fuel_gauge_get_current(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_current)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_current(dev);
|
||||
}
|
||||
|
||||
int fuel_gauge_get_voltage(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_voltage)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_voltage(dev);
|
||||
}
|
||||
|
||||
int fuel_gauge_update_get_soc(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_soc)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_soc(dev);
|
||||
}
|
||||
|
||||
bool fuel_gauge_get_chrg_online(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_chrg_online)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_chrg_online(dev);
|
||||
}
|
||||
|
||||
int fuel_gauge_get_temperature(struct udevice *dev, int *temp)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_temperature)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_temperature(dev, temp);
|
||||
}
|
||||
|
||||
int charger_set_charger_voltage(struct udevice *dev, int uV)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->set_charger_voltage)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_charger_voltage(dev, uV);
|
||||
}
|
||||
|
||||
int charger_set_current(struct udevice *dev, int ichrg_uA)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->set_charger_current)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_charger_current(dev, ichrg_uA);
|
||||
}
|
||||
|
||||
int charger_set_iprechg_current(struct udevice *dev, int iprechrg_uA)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->set_iprechg_current)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_iprechg_current(dev, iprechrg_uA);
|
||||
}
|
||||
|
||||
int charger_set_enable(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->set_charger_enable)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_charger_enable(dev);
|
||||
}
|
||||
|
||||
int charger_set_disable(struct udevice *dev)
|
||||
{
|
||||
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->set_charger_disable)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_charger_disable(dev);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(fuel_guage) = {
|
||||
.id = UCLASS_FG,
|
||||
.name = "fuel_gauge",
|
||||
};
|
||||
@@ -115,7 +115,9 @@ enum uclass_id {
|
||||
UCLASS_W1, /* Dallas 1-Wire bus */
|
||||
UCLASS_W1_EEPROM, /* one-wire EEPROMs */
|
||||
UCLASS_WDT, /* Watchdog Timer driver */
|
||||
|
||||
UCLASS_FG, /* Fuel gauge */
|
||||
UCLASS_CHARGE_DISPLAY, /* Charge display */
|
||||
UCLASS_MCU, /* MCU device */
|
||||
UCLASS_COUNT,
|
||||
UCLASS_INVALID = -1,
|
||||
};
|
||||
|
||||
23
include/mcu/mcu-uclass.h
Executable file
23
include/mcu/mcu-uclass.h
Executable file
@@ -0,0 +1,23 @@
|
||||
#ifndef __MCU_H
|
||||
#define __MCU_H
|
||||
|
||||
struct mcu_ops {
|
||||
int (*shutdown)(struct udevice *dev);
|
||||
int (*poweron)(struct udevice *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
* mcu_shutdown() - power off supplies
|
||||
*
|
||||
* @return 0 on success or negative value of errno.
|
||||
*/
|
||||
int mcu_shutdown(void);
|
||||
|
||||
/**
|
||||
* mcu_poweron() - power on supplies
|
||||
*
|
||||
* @return 0 on success or negative value of errno.
|
||||
*/
|
||||
int mcu_poweron(void);
|
||||
|
||||
#endif
|
||||
33
include/power/charge_animation.h
Executable file
33
include/power/charge_animation.h
Executable file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _CHARGE_ANIMATION_H_
|
||||
#define _CHARGE_ANIMATION_H_
|
||||
|
||||
struct regulator_mem {
|
||||
struct udevice *dev;
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct charge_animation_pdata {
|
||||
int android_charge; /* android charge, 1: enable, 0: disable */
|
||||
int uboot_charge; /* u-boot charge, 1: enable, 0: disable */
|
||||
|
||||
int auto_exit_charge; /* energy enough auto exit uboot charging*/
|
||||
int exit_charge_voltage;/* lowest voltage allowed to exit charging */
|
||||
int exit_charge_level; /* lowest soc level allowed to exit charging */
|
||||
int low_power_voltage; /* below this voltage, force system into charge mode anyway */
|
||||
int screen_on_voltage; /* lowest voltage allowed to turn on screen */
|
||||
|
||||
int system_suspend; /* enter ATF system suspend, 1: enable, 0: disable */
|
||||
int auto_wakeup_interval;/* timeout seconds to auto wakeup system */
|
||||
int auto_wakeup_screen_invert;/* auto wakeup system, 1: enable, 0: disable */
|
||||
int auto_off_screen_interval;/* timeout seconds to auto turn off screen */
|
||||
|
||||
struct regulator_mem *regulators_mem; /* assigned regulator suspend state */
|
||||
};
|
||||
|
||||
#endif
|
||||
17
include/power/charge_display.h
Executable file
17
include/power/charge_display.h
Executable file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _CHARGE_DISPLAY_H_
|
||||
#define _CHARGE_DISPLAY_H_
|
||||
|
||||
struct dm_charge_display_ops {
|
||||
int (*show)(struct udevice *dev);
|
||||
};
|
||||
|
||||
int charge_display(void);
|
||||
int charge_display_show(struct udevice *dev);
|
||||
|
||||
#endif
|
||||
46
include/power/fuel_gauge.h
Executable file
46
include/power/fuel_gauge.h
Executable file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _FUEL_GAUGE_H_
|
||||
#define _FUEL_GAUGE_H_
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT(nr) (1 << (nr))
|
||||
#endif
|
||||
|
||||
/* Capability */
|
||||
#define FG_CAP_FUEL_GAUGE BIT(0)
|
||||
#define FG_CAP_CHARGER BIT(1)
|
||||
|
||||
struct dm_fuel_gauge_ops {
|
||||
int (*capability)(struct udevice *dev);
|
||||
int (*bat_is_exist)(struct udevice *dev);
|
||||
int (*get_soc)(struct udevice *dev);
|
||||
int (*get_voltage)(struct udevice *dev);
|
||||
int (*get_current)(struct udevice *dev);
|
||||
int (*get_temperature)(struct udevice *dev, int *temp);
|
||||
bool (*get_chrg_online)(struct udevice *dev);
|
||||
int (*set_charger_voltage)(struct udevice *dev, int uV);
|
||||
int (*set_charger_enable)(struct udevice *dev);
|
||||
int (*set_charger_disable)(struct udevice *dev);
|
||||
int (*set_iprechg_current)(struct udevice *dev, int iprechrg_uA);
|
||||
int (*set_charger_current)(struct udevice *dev, int ichrg_uA);
|
||||
};
|
||||
|
||||
int fuel_gauge_capability(struct udevice *dev);
|
||||
int fuel_gauge_bat_is_exist(struct udevice *dev);
|
||||
int fuel_gauge_update_get_soc(struct udevice *dev);
|
||||
int fuel_gauge_get_voltage(struct udevice *dev);
|
||||
int fuel_gauge_get_current(struct udevice *dev);
|
||||
bool fuel_gauge_get_chrg_online(struct udevice *dev);
|
||||
int fuel_gauge_get_temperature(struct udevice *dev, int *temp);
|
||||
int charger_set_charger_voltage(struct udevice *dev, int uV);
|
||||
int charger_set_iprechg_current(struct udevice *dev, int iprechrg_uA);
|
||||
int charger_set_current(struct udevice *dev, int ichrg_uA);
|
||||
int charger_set_enable(struct udevice *dev);
|
||||
int charger_set_disable(struct udevice *dev);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user