From 37af1d4c76fa9a15a1fdb24213b6b287e0f625ab Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Mon, 31 Dec 2018 12:56:56 -0600 Subject: [PATCH] drivers/power/mcp73871.c: Add support to Microchip MPC73871 Battery Charger. --- drivers/power/Kconfig | 7 + drivers/power/Make.defs | 6 + drivers/power/mcp73871.c | 423 +++++++++++++++++++++++++++++++++ include/nuttx/power/mcp73871.h | 92 +++++++ 4 files changed, 528 insertions(+) create mode 100644 drivers/power/mcp73871.c create mode 100644 include/nuttx/power/mcp73871.h diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 94d29122d7..7d589fd0d4 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -357,6 +357,13 @@ config BQ2429X ---help--- The BQ24296/BQ24297/BQ24296M are battery charger for lithium-ion batteries. +config MCP73871 + bool "Microchip MCP73871 Battery charger support" + default n + depends on BATTERY_CHARGER + ---help--- + A simple driver to report MCP73871 status. + if BQ2429X config DEBUG_BQ2429X diff --git a/drivers/power/Make.defs b/drivers/power/Make.defs index f4fe4c1a6a..9d047fe86e 100644 --- a/drivers/power/Make.defs +++ b/drivers/power/Make.defs @@ -94,6 +94,12 @@ ifeq ($(CONFIG_BATTERY_CHARGER),y) CSRCS += battery_charger.c +# Add the MCP73871 battery charger driver + +ifeq ($(CONFIG_MCP73871),y) +CSRCS += mcp73871.c +endif + # Add I2C-based battery charger drivers ifeq ($(CONFIG_I2C),y) diff --git a/drivers/power/mcp73871.c b/drivers/power/mcp73871.c new file mode 100644 index 0000000000..74a5c2f483 --- /dev/null +++ b/drivers/power/mcp73871.c @@ -0,0 +1,423 @@ +/**************************************************************************** + * drivers/power/mcp73871.c + * Lower half driver for Microchip MCP73871 battery charger + * + * Copyright (C) 2018 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The MCP73871 is a standalone battery charger, so this driver is not + * supposed to do much things, it will only report faults and battery status. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery driver support + */ + +#if defined(CONFIG_BATTERY_CHARGER) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Debug ********************************************************************/ + +#ifdef CONFIG_DEBUG_MCP73871 +# define baterr _err +# define batreg _err +#else +# ifdef CONFIG_CPP_HAVE_VARARGS +# define baterr(x...) +# define batreg(x...) +# else +# define baterr (void) +# define batreg (void) +# endif +#endif + +/**************************************************************************** + * Private + ****************************************************************************/ + +struct mcp73871_dev_s +{ + /* MCP73871 configuration helpers */ + + FAR struct mcp73871_config_s *config; + + /* The common part of the battery driver visible to the upper-half driver */ + + FAR const struct battery_charger_operations_s *ops; /* Battery operations */ + sem_t batsem; /* Enforce mutually exclusive access */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Battery driver lower half methods */ + +static int mcp73871_state(FAR struct battery_charger_dev_s *dev, + FAR int *status); +static int mcp73871_health(FAR struct battery_charger_dev_s *dev, + FAR int *health); +static int mcp73871_online(FAR struct battery_charger_dev_s *dev, + FAR bool *status); +static int mcp73871_voltage(FAR struct battery_charger_dev_s *dev, + int value); +static int mcp73871_current(FAR struct battery_charger_dev_s *dev, + int value); +static int mcp73871_input_current(FAR struct battery_charger_dev_s *dev, + int value); +static int mcp73871_operate(FAR struct battery_charger_dev_s *dev, + intptr_t param); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct battery_charger_operations_s g_mcp73871ops = +{ + mcp73871_state, + mcp73871_health, + mcp73871_online, + mcp73871_voltage, + mcp73871_current, + mcp73871_input_current, + mcp73871_operate +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mcp73871_state + * + * Description: + * Return the current battery state + * + ****************************************************************************/ + +static int mcp73871_state(FAR struct battery_charger_dev_s *dev, + FAR int *status) +{ + FAR struct mcp73871_dev_s *priv = (FAR struct mcp73871_dev_s *)dev; + uint8_t value = 0; + + /* Create a value with bits 2 1 0 = STAT1 | STAT2 | PG */ + + value = (priv->config->read_stat1() << 2) | + (priv->config->read_stat2() << 1) | + (priv->config->read_pg() << 0); + + switch (value) + { + case MCP73871_FAULT: + *status = BATTERY_FAULT; + break; + + case MCP73871_CHARGING: + *status = BATTERY_CHARGING; + break; + + case MCP73871_BAT_LOW: + *status = BATTERY_DISCHARGING; + break; + + case MCP73871_CHG_COMPLETE: + *status = BATTERY_FULL; + break; + + case MCP73871_NO_BATTERY: + *status = BATTERY_FAULT; + break; + + case MCP73871_NO_INPUT_PWR: + *status = BATTERY_FAULT; + break; + + default: + *status = BATTERY_HEALTH_UNKNOWN; + break; + } + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_health + * + * Description: + * Return the current battery health state + * + * Note: if more than one fault happened the user needs to call this ioctl + * again to read a new fault, repeat until receive a BATTERY_HEALTH_GOOD. + * + ****************************************************************************/ + +static int mcp73871_health(FAR struct battery_charger_dev_s *dev, + FAR int *health) +{ + FAR struct mcp73871_dev_s *priv = (FAR struct mcp73871_dev_s *)dev; + uint8_t value = 0; + + /* Create a value with bits 2 1 0 = STAT1 | STAT2 | PG */ + + value = (priv->config->read_stat1() << 2) | + (priv->config->read_stat2() << 1) | + (priv->config->read_pg() << 0); + + switch (value) + { + case MCP73871_FAULT: + *health = BATTERY_HEALTH_SAFE_TMR_EXP; + break; + + case MCP73871_CHARGING: + case MCP73871_CHG_COMPLETE: + *health = BATTERY_HEALTH_GOOD; + break; + + case MCP73871_NO_BATTERY: + *health = BATTERY_HEALTH_DISCONNECTED; + break; + + case MCP73871_BAT_LOW: + case MCP73871_NO_INPUT_PWR: + default: + *health = BATTERY_HEALTH_UNKNOWN; + break; + } + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_online + * + * Description: + * Return true if the battery is online + * + ****************************************************************************/ + +static int mcp73871_online(FAR struct battery_charger_dev_s *dev, + FAR bool *status) +{ + /* There is no concept of online/offline in this driver */ + + *status = true; + return OK; +} + +/**************************************************************************** + * Name: mcp73871_powersupply + * + * Description: + * Set the Power Supply Current Limit. + * + ****************************************************************************/ + +static inline int mcp73871_powersupply(FAR struct mcp73871_dev_s *priv, + int current) +{ + /* This chip doesn't support setting current limit by software */ + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_setvolt + * + * Description: + * Set the voltage level to charge the battery. Voltage value in mV. + * + ****************************************************************************/ + +static inline int mcp73871_setvolt(FAR struct mcp73871_dev_s *priv, + int volts) +{ + /* This chip doesn't support setting voltage by software */ + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_setcurr + * + * Description: + * Set the current to charge the battery. Current value in mA. + * + ****************************************************************************/ + +static inline int mcp73871_setcurr(FAR struct mcp73871_dev_s *priv, + int current) +{ + /* This chip doesn't support setting current by software */ + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_voltage + * + * Description: + * Set battery charger voltage + * + ****************************************************************************/ + +static int mcp73871_voltage(FAR struct battery_charger_dev_s *dev, int value) +{ + /* This chip doesn't support setting voltage by software */ + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_current + * + * Description: + * Set the battery charger current rate for charging + * + ****************************************************************************/ + +static int mcp73871_current(FAR struct battery_charger_dev_s *dev, int value) +{ + /* This chip doesn't support setting current rate by software */ + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_input_current + * + * Description: + * Set the power-supply input current limit + * + ****************************************************************************/ + +static int mcp73871_input_current(FAR struct battery_charger_dev_s *dev, + int value) +{ + /* This chip doesn't support setting input current limit by software */ + + return OK; +} + +/**************************************************************************** + * Name: mcp73871_operate + * + * Description: + * Do miscellaneous battery ioctl() + * + ****************************************************************************/ + +static int mcp73871_operate(FAR struct battery_charger_dev_s *dev, + uintptr_t param) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mcp73871_initialize + * + * Description: + * Initialize the BQ2425x battery driver and return an instance of the + * lower_half interface that may be used with battery_charger_register(); + * + * This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery driver support + * + * Input Parameters: + * config - The config structure with function pointers to read/write. + * + * Returned Value: + * A pointer to the initialized lower-half driver instance. A NULL + * pointer is returned on a failure to initialize the BQ2425x lower half. + * + ****************************************************************************/ + +FAR struct battery_charger_dev_s * + mcp73871_initialize(FAR struct mcp73871_config_s *config) +{ + FAR struct mcp73871_dev_s *priv; + + /* Initialize the BQ2425x device structure */ + + priv = (FAR struct mcp73871_dev_s *) + kmm_zalloc(sizeof(struct mcp73871_dev_s)); + + if (priv) + { + /* Initialize the BQ2425x device structure */ + + nxsem_init(&priv->batsem, 0, 1); + priv->ops = &g_mcp73871ops; + priv->config = config; + + /* Enable the battery charge */ + + priv->config->set_chg_ce(true); + } + + return (FAR struct battery_charger_dev_s *)priv; +} + +#endif /* CONFIG_BATTERY_CHARGER */ diff --git a/include/nuttx/power/mcp73871.h b/include/nuttx/power/mcp73871.h new file mode 100644 index 0000000000..863ef4c22f --- /dev/null +++ b/include/nuttx/power/mcp73871.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * drivers/power/mcp73871.h + * Lower half driver for MCP73871 battery charger + * + * Copyright (C) 2018 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __DRIVERS_POWER_MCP73871_H +#define __DRIVERS_POWER_MCP73871_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is the TABLE 5-1 STATUS OUTPUTS from MCP73871 datasheet + * (20002090C.pdf) + */ + +#define MCP73871_FAULT 0 +#define MCP73871_CHARGING 2 +#define MCP73871_BAT_LOW 3 +#define MCP73871_CHG_COMPLETE 4 +#define MCP73871_NO_BATTERY 6 /* Also could be Shutdown mode */ +#define MCP73871_NO_INPUT_PWR 7 /* Also could be Shutdown mode */ + +/* MCP73871 configuration data structure */ + +struct mcp73871_config_s +{ + CODE int (*read_stat1)(void); + CODE int (*read_stat2)(void); + CODE int (*read_pg)(void); + CODE void (*set_chg_ce)(bool on); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: mcp73871_initialize + * + * Description: + * Initialize the BQ2425x battery driver and return an instance of the + * lower_half interface that may be used with battery_charger_register(); + * + * This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery driver support + * + * Input Parameters: + * config - The config structure with function pointers to read/write. + * + * Returned Value: + * A pointer to the initialized lower-half driver instance. A NULL + * pointer is returned on a failure to initialize the BQ2425x lower half. + * + ****************************************************************************/ + +FAR struct battery_charger_dev_s * + mcp73871_initialize(FAR struct mcp73871_config_s *config); + +#endif /* __DRIVERS_POWER_MCP73871_H */