/**************************************************************************** * drivers/power/mcp73871.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /* Lower half driver for Microchip MCP73871 battery charger * * 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 # define baterr _none # define batreg _none #endif /**************************************************************************** * Private ****************************************************************************/ struct mcp73871_dev_s { /* 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 */ /* MCP73871 configuration helpers */ FAR struct mcp73871_config_s *config; }; /**************************************************************************** * 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; /* Allocate the MCP73871 device structure */ priv = (FAR struct mcp73871_dev_s *) kmm_zalloc(sizeof(struct mcp73871_dev_s)); if (priv) { /* Initialize the MCP73871 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 */