Permalink
Browse files

charger: add max77693 charger support

The charger basically wraps around the existing regulator driver,
and also supplies information about the charging state.
  • Loading branch information...
fourkbomb committed May 22, 2018
1 parent 7a8e0ad commit 4e9a64304ac951b40f26c44c9144d76e9ac7a51a
@@ -3,3 +3,10 @@ config DM_CHARGER
depends on DM
---help---
This config enables driver model charger support.

config DM_CHARGER_MAX77693
bool "Enable DM charger support for max77693"
depends on DM_CHARGER
depends on DM_REGULATOR_MAX77693
---help---
This config enables support for using the max77693 as a charger.
@@ -5,4 +5,4 @@
#

obj-$(CONFIG_DM_CHARGER) += charger-uclass.o

obj-$(CONFIG_DM_CHARGER_MAX77693) += max77693.o
@@ -0,0 +1,127 @@
/*
* Copyright (C) 2018 Simon Shields <simon@lineageos.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/

#include <common.h>
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <i2c.h>
#include <power/charger.h>
#include <power/max77693_pmic.h>
#include <power/pmic.h>
#include <power/regulator.h>

DECLARE_GLOBAL_DATA_PTR;

enum max77693_charger_charging_state {
MAX77693_CHARGING_PREQUALIFICATION = 0x0,
MAX77693_CHARGING_FAST_CONST_CURRENT,
MAX77693_CHARGING_FAST_CONST_VOLTAGE,
MAX77693_CHARGING_TOP_OFF,
MAX77693_CHARGING_DONE,
MAX77693_CHARGING_HIGH_TEMP,
MAX77693_CHARGING_TIMER_EXPIRED,
MAX77693_CHARGING_THERMISTOR_SUSPEND,
MAX77693_CHARGING_OFF,
MAX77693_CHARGING_RESERVED,
MAX77693_CHARGING_OVER_TEMP,
MAX77693_CHARGING_WATCHDOG_EXPIRED,
};

static int max77693_get_current(struct udevice *dev)
{
return regulator_get_current(dev->priv);
}

static int max77693_set_current(struct udevice *dev, unsigned int microamps)
{
struct udevice *reg = dev->priv;
int ret;

if (!microamps) {
ret = regulator_set_current(reg, 0);
if (ret) {
printf("regulator_set_current(0) failed: %d\n", ret);
return ret;
}

ret = regulator_set_enable(reg, 0);
if (ret) {
printf("failed to disable charger regulator: %d\n", ret);
return ret;
}
} else {
ret = regulator_set_current(reg, microamps);
if (ret) {
printf("regulator_set_current(%u) failed: %d\n", microamps, ret);
return ret;
}

ret = regulator_set_enable(reg, 1);
if (ret) {
printf("failed to enable charger regulator: %d\n", ret);
return ret;
}
}

return 0;
}

static int max77693_get_status(struct udevice *dev)
{
u8 reg;
int ret = pmic_read(dev->parent, MAX77693_CHG_DETAILS_01, &reg, 1);
if (ret) {
printf("Failed to read CHG_DETAILS_01: %d\n", ret);
return ret;
}

reg &= 0xf;

switch (reg) {
case MAX77693_CHARGING_PREQUALIFICATION:
case MAX77693_CHARGING_FAST_CONST_CURRENT:
case MAX77693_CHARGING_FAST_CONST_VOLTAGE:
case MAX77693_CHARGING_TOP_OFF:
case MAX77693_CHARGING_HIGH_TEMP:
return CHARGE_STATE_CHARGING;
case MAX77693_CHARGING_DONE:
return CHARGE_STATE_FULL;
case MAX77693_CHARGING_TIMER_EXPIRED:
case MAX77693_CHARGING_THERMISTOR_SUSPEND:
return CHARGE_STATE_NOT_CHARGING;
case MAX77693_CHARGING_OFF:
case MAX77693_CHARGING_OVER_TEMP:
case MAX77693_CHARGING_WATCHDOG_EXPIRED:
return CHARGE_STATE_DISCHARGING;
}

return CHARGE_STATE_UNKNOWN;
}

static int max77693_probe(struct udevice *dev)
{
int ret = device_get_supply_regulator(dev, "charger-supply", &dev->priv);
if (ret) {
printf("Failed to get charger regulator: %d\n", ret);
return ret;
}

return 0;
}

static struct dm_charger_ops max77693_chg_ops = {
.get_current = max77693_get_current,
.set_current = max77693_set_current,
.get_status = max77693_get_status,
};

U_BOOT_DRIVER(charger_max77693) = {
.name = MAX77693_CHARGER_DRIVER,
.id = UCLASS_CHARGER,
.ops = &max77693_chg_ops,
.probe = max77693_probe,
};
@@ -20,9 +20,10 @@ DECLARE_GLOBAL_DATA_PTR;
#define PMIC_TYPE_HAPTIC 2

static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "ESAFEOUT", .driver = MAX77693_SAFEOUT_DRIVER },
{ .prefix = "CHARGER", .driver = MAX77693_CHARGER_DRIVER },
{ .prefix = "ESAFEOUT", .driver = MAX77693_REGULATOR_SAFEOUT_DRIVER },
{ .prefix = "CHARGER", .driver = MAX77693_REGULATOR_CHARGER_DRIVER },
{ .prefix = "muic", .driver = MAX77693_MUIC_DRIVER },
{ .prefix = "charger", .driver = MAX77693_CHARGER_DRIVER },
};

static int max77693_reg_count(struct udevice *dev)
@@ -66,25 +67,28 @@ static int max77693_read(struct udevice *dev, uint reg, uint8_t *buff, int len)

static int max77693_bind(struct udevice *dev)
{
ofnode children_node;
ofnode children_node = dev_ofnode(dev);
int children;
ulong type = dev_get_driver_data(dev);

if (type == PMIC_TYPE_MUIC) {
children_node = dev_ofnode(dev);
} else {
children = pmic_bind_children(dev, children_node, pmic_children_info);
if (!children)
debug("%s: %s: found no children!", dev->name,
__func__);

if (type == PMIC_TYPE_CHARGER) {
children_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(children_node)) {
debug("%s: %s: found no regulators!", dev->name,
__func__);
return -ENXIO;
}
}

children = pmic_bind_children(dev, children_node, pmic_children_info);
if (!children)
debug("%s: %s: found no children!", dev->name,
__func__);
children = pmic_bind_children(dev, children_node, pmic_children_info);
if (!children)
debug("%s: %s: found no regulator children!", dev->name,
__func__);
}

return 0;
}
@@ -230,7 +230,7 @@ static const struct dm_regulator_ops max77693_charger_ops = {
};

U_BOOT_DRIVER(max77693_reg_charger) = {
.name = MAX77693_CHARGER_DRIVER,
.name = MAX77693_REGULATOR_CHARGER_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &max77693_charger_ops,
};
@@ -243,7 +243,7 @@ static const struct dm_regulator_ops max77693_safeout_ops = {
};

U_BOOT_DRIVER(max77693_reg_safeout) = {
.name = MAX77693_SAFEOUT_DRIVER,
.name = MAX77693_REGULATOR_SAFEOUT_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &max77693_safeout_ops,
};
@@ -19,6 +19,7 @@

#define MAX77693_CHG_BASE 0xB0
#define MAX77693_CHG_INT_OK 0xB2
#define MAX77693_CHG_DETAILS_01 0xB4
#define MAX77693_CHG_CNFG_00 0xB7
#define MAX77693_CHG_CNFG_02 0xB9
#define MAX77693_CHG_CNFG_06 0xBD
@@ -38,8 +39,9 @@

#define MAX77693_PMIC_I2C_ADDR (0xCC >> 1)

#define MAX77693_SAFEOUT_DRIVER "max77693_reg_safeout"
#define MAX77693_CHARGER_DRIVER "max77693_reg_charger"
#define MAX77693_REGULATOR_SAFEOUT_DRIVER "max77693_reg_safeout"
#define MAX77693_REGULATOR_CHARGER_DRIVER "max77693_reg_charger"
#define MAX77693_CHARGER_DRIVER "max77693_charger"

#ifndef CONFIG_PMIC_DM_MAX77693
int pmic_init_max77693(unsigned char bus);

0 comments on commit 4e9a643

Please sign in to comment.