linux/drivers/power/supply/bq27xxx_battery.c

// SPDX-License-Identifier: GPL-2.0
/*
 * BQ27xxx battery driver
 *
 * Copyright (C) 2008 Rodolfo Giometti <[email protected]>
 * Copyright (C) 2008 Eurotech S.p.A. <[email protected]>
 * Copyright (C) 2010-2011 Lars-Peter Clausen <[email protected]>
 * Copyright (C) 2011 Pali Rohár <[email protected]>
 * Copyright (C) 2017 Liam Breck <[email protected]>
 *
 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
 *
 * Datasheets:
 * https://www.ti.com/product/bq27000
 * https://www.ti.com/product/bq27200
 * https://www.ti.com/product/bq27010
 * https://www.ti.com/product/bq27210
 * https://www.ti.com/product/bq27500
 * https://www.ti.com/product/bq27510-g1
 * https://www.ti.com/product/bq27510-g2
 * https://www.ti.com/product/bq27510-g3
 * https://www.ti.com/product/bq27520-g1
 * https://www.ti.com/product/bq27520-g2
 * https://www.ti.com/product/bq27520-g3
 * https://www.ti.com/product/bq27520-g4
 * https://www.ti.com/product/bq27530-g1
 * https://www.ti.com/product/bq27531-g1
 * https://www.ti.com/product/bq27541-g1
 * https://www.ti.com/product/bq27542-g1
 * https://www.ti.com/product/bq27546-g1
 * https://www.ti.com/product/bq27742-g1
 * https://www.ti.com/product/bq27545-g1
 * https://www.ti.com/product/bq27421-g1
 * https://www.ti.com/product/bq27425-g1
 * https://www.ti.com/product/bq27426
 * https://www.ti.com/product/bq27411-g1
 * https://www.ti.com/product/bq27441-g1
 * https://www.ti.com/product/bq27621-g1
 * https://www.ti.com/product/bq27z561
 * https://www.ti.com/product/bq28z610
 * https://www.ti.com/product/bq34z100-g1
 * https://www.ti.com/product/bq78z100
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/param.h>
#include <linux/jiffies.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/of.h>

#include <linux/power/bq27xxx_battery.h>

#define BQ27XXX_MANUFACTURER

/* BQ27XXX Flags */
#define BQ27XXX_FLAG_DSC
#define BQ27XXX_FLAG_SOCF
#define BQ27XXX_FLAG_SOC1
#define BQ27XXX_FLAG_CFGUP
#define BQ27XXX_FLAG_FC
#define BQ27XXX_FLAG_OTD
#define BQ27XXX_FLAG_OTC
#define BQ27XXX_FLAG_UT
#define BQ27XXX_FLAG_OT

/* BQ27000 has different layout for Flags register */
#define BQ27000_FLAG_EDVF
#define BQ27000_FLAG_EDV1
#define BQ27000_FLAG_CI
#define BQ27000_FLAG_FC
#define BQ27000_FLAG_CHGS

/* BQ27Z561 has different layout for Flags register */
#define BQ27Z561_FLAG_FDC
#define BQ27Z561_FLAG_FC
#define BQ27Z561_FLAG_DIS_CH

/* control register params */
#define BQ27XXX_SEALED
#define BQ27XXX_SET_CFGUPDATE
#define BQ27XXX_SOFT_RESET
#define BQ27XXX_RESET

#define BQ27XXX_RS
#define BQ27XXX_POWER_CONSTANT
#define BQ27XXX_CURRENT_CONSTANT

#define INVALID_REG_ADDR

/*
 * bq27xxx_reg_index - Register names
 *
 * These are indexes into a device's register mapping array.
 */

enum bq27xxx_reg_index {};

#define BQ27XXX_DM_REG_ROWS

/* Register mappings */
static u8
	bq27000_regs[BQ27XXX_REG_MAX] =,
	bq27010_regs[BQ27XXX_REG_MAX] =,
	bq2750x_regs[BQ27XXX_REG_MAX] =,
#define bq2751x_regs bq27510g3_regs
#define bq2752x_regs bq27510g3_regs
	bq27500_regs[BQ27XXX_REG_MAX] =,
#define bq27510g1_regs bq27500_regs
#define bq27510g2_regs bq27500_regs
	bq27510g3_regs[BQ27XXX_REG_MAX] =,
	bq27520g1_regs[BQ27XXX_REG_MAX] =,
	bq27520g2_regs[BQ27XXX_REG_MAX] =,
	bq27520g3_regs[BQ27XXX_REG_MAX] =,
	bq27520g4_regs[BQ27XXX_REG_MAX] =,
	bq27521_regs[BQ27XXX_REG_MAX] =,
	bq27530_regs[BQ27XXX_REG_MAX] =,
#define bq27531_regs bq27530_regs
	bq27541_regs[BQ27XXX_REG_MAX] =,
#define bq27542_regs bq27541_regs
#define bq27546_regs bq27541_regs
#define bq27742_regs bq27541_regs
	bq27545_regs[BQ27XXX_REG_MAX] =,
	bq27421_regs[BQ27XXX_REG_MAX] =,
#define bq27411_regs bq27421_regs
#define bq27425_regs bq27421_regs
#define bq27426_regs bq27421_regs
#define bq27441_regs bq27421_regs
#define bq27621_regs bq27421_regs
	bq27z561_regs[BQ27XXX_REG_MAX] =,
	bq28z610_regs[BQ27XXX_REG_MAX] =,
	bq34z100_regs[BQ27XXX_REG_MAX] =,
	bq78z100_regs[BQ27XXX_REG_MAX] =;

static enum power_supply_property bq27000_props[] =;

static enum power_supply_property bq27010_props[] =;

#define bq2750x_props
#define bq2751x_props
#define bq2752x_props

static enum power_supply_property bq27500_props[] =;
#define bq27510g1_props
#define bq27510g2_props

static enum power_supply_property bq27510g3_props[] =;

static enum power_supply_property bq27520g1_props[] =;

#define bq27520g2_props

static enum power_supply_property bq27520g3_props[] =;

static enum power_supply_property bq27520g4_props[] =;

static enum power_supply_property bq27521_props[] =;

static enum power_supply_property bq27530_props[] =;
#define bq27531_props

static enum power_supply_property bq27541_props[] =;
#define bq27542_props
#define bq27546_props
#define bq27742_props

static enum power_supply_property bq27545_props[] =;

static enum power_supply_property bq27421_props[] =;
#define bq27411_props
#define bq27425_props
#define bq27426_props
#define bq27441_props
#define bq27621_props

static enum power_supply_property bq27z561_props[] =;

static enum power_supply_property bq28z610_props[] =;

static enum power_supply_property bq34z100_props[] =;

static enum power_supply_property bq78z100_props[] =;

struct bq27xxx_dm_reg {};

enum bq27xxx_dm_reg_id {};

#define bq27000_dm_regs
#define bq27010_dm_regs
#define bq2750x_dm_regs
#define bq2751x_dm_regs
#define bq2752x_dm_regs

#if 0 /* not yet tested */
static struct bq27xxx_dm_reg bq27500_dm_regs[] = {
	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 48, 10, 2,    0, 65535 },
	[BQ27XXX_DM_DESIGN_ENERGY]     = { }, /* missing on chip */
	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 80, 48, 2, 1000, 32767 },
};
#else
#define bq27500_dm_regs
#endif

/* todo create data memory definitions from datasheets and test on chips */
#define bq27510g1_dm_regs
#define bq27510g2_dm_regs
#define bq27510g3_dm_regs
#define bq27520g1_dm_regs
#define bq27520g2_dm_regs
#define bq27520g3_dm_regs
#define bq27520g4_dm_regs
#define bq27521_dm_regs
#define bq27530_dm_regs
#define bq27531_dm_regs
#define bq27541_dm_regs
#define bq27542_dm_regs
#define bq27546_dm_regs
#define bq27742_dm_regs

#if 0 /* not yet tested */
static struct bq27xxx_dm_reg bq27545_dm_regs[] = {
	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 48, 23, 2,    0, 32767 },
	[BQ27XXX_DM_DESIGN_ENERGY]     = { 48, 25, 2,    0, 32767 },
	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 80, 67, 2, 2800,  3700 },
};
#else
#define bq27545_dm_regs
#endif

static struct bq27xxx_dm_reg bq27411_dm_regs[] =;

static struct bq27xxx_dm_reg bq27421_dm_regs[] =;

static struct bq27xxx_dm_reg bq27425_dm_regs[] =;

static struct bq27xxx_dm_reg bq27426_dm_regs[] =;

#if 0 /* not yet tested */
#define bq27441_dm_regs
#else
#define bq27441_dm_regs
#endif

#if 0 /* not yet tested */
static struct bq27xxx_dm_reg bq27621_dm_regs[] = {
	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 82, 3, 2,    0,  8000 },
	[BQ27XXX_DM_DESIGN_ENERGY]     = { 82, 5, 2,    0, 32767 },
	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 9, 2, 2500,  3700 },
};
#else
#define bq27621_dm_regs
#endif

#define bq27z561_dm_regs
#define bq28z610_dm_regs
#define bq34z100_dm_regs
#define bq78z100_dm_regs

#define BQ27XXX_O_ZERO
#define BQ27XXX_O_OTDC
#define BQ27XXX_O_UTOT
#define BQ27XXX_O_CFGUP
#define BQ27XXX_O_RAM
#define BQ27Z561_O_BITS
#define BQ27XXX_O_SOC_SI
#define BQ27XXX_O_HAS_CI
#define BQ27XXX_O_MUL_CHEM

#define BQ27XXX_DATA(ref, key, opt)

static struct {} bq27xxx_chip_data[] =;

static DEFINE_MUTEX(bq27xxx_list_lock);
static LIST_HEAD(bq27xxx_battery_devices);

#define BQ27XXX_MSLEEP(i)

#define BQ27XXX_DM_SZ

/**
 * struct bq27xxx_dm_buf - chip data memory buffer
 * @class: data memory subclass_id
 * @block: data memory block number
 * @data: data from/for the block
 * @has_data: true if data has been filled by read
 * @dirty: true if data has changed since last read/write
 *
 * Encapsulates info required to manage chip data memory blocks.
 */
struct bq27xxx_dm_buf {};

#define BQ27XXX_DM_BUF(di, i)

static inline __be16 *bq27xxx_dm_reg_ptr(struct bq27xxx_dm_buf *buf,
				      struct bq27xxx_dm_reg *reg)
{}

static const char * const bq27xxx_dm_reg_name[] =;


static bool bq27xxx_dt_to_nvm =;
module_param_named(dt_monitored_battery_updates_nvm, bq27xxx_dt_to_nvm, bool, 0444);
MODULE_PARM_DESC();

static int poll_interval_param_set(const char *val, const struct kernel_param *kp)
{}

static const struct kernel_param_ops param_ops_poll_interval =;

static unsigned int poll_interval =;
module_param_cb();
MODULE_PARM_DESC();

/*
 * Common code for BQ27xxx devices
 */

static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
			       bool single)
{}

static inline int bq27xxx_write(struct bq27xxx_device_info *di, int reg_index,
				u16 value, bool single)
{}

static inline int bq27xxx_read_block(struct bq27xxx_device_info *di, int reg_index,
				     u8 *data, int len)
{}

static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_index,
				      u8 *data, int len)
{}

static int bq27xxx_battery_seal(struct bq27xxx_device_info *di)
{}

static int bq27xxx_battery_unseal(struct bq27xxx_device_info *di)
{}

static u8 bq27xxx_battery_checksum_dm_block(struct bq27xxx_dm_buf *buf)
{}

static int bq27xxx_battery_read_dm_block(struct bq27xxx_device_info *di,
					 struct bq27xxx_dm_buf *buf)
{}

static void bq27xxx_battery_update_dm_block(struct bq27xxx_device_info *di,
					    struct bq27xxx_dm_buf *buf,
					    enum bq27xxx_dm_reg_id reg_id,
					    unsigned int val)
{}

static int bq27xxx_battery_cfgupdate_priv(struct bq27xxx_device_info *di, bool active)
{}

static inline int bq27xxx_battery_set_cfgupdate(struct bq27xxx_device_info *di)
{}

static inline int bq27xxx_battery_soft_reset(struct bq27xxx_device_info *di)
{}

static int bq27xxx_battery_write_dm_block(struct bq27xxx_device_info *di,
					  struct bq27xxx_dm_buf *buf)
{}

static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
				       struct power_supply_battery_info *info)
{}

static void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
{}

/*
 * Return the battery State-of-Charge
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
{}

/*
 * Return a battery charge value in µAh
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg,
				       union power_supply_propval *val)
{}

/*
 * Return the battery Nominal available capacity in µAh
 * Or < 0 if something fails.
 */
static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di,
					   union power_supply_propval *val)
{}

/*
 * Return the battery Remaining Capacity in µAh
 * Or < 0 if something fails.
 */
static inline int bq27xxx_battery_read_rc(struct bq27xxx_device_info *di,
					  union power_supply_propval *val)
{}

/*
 * Return the battery Full Charge Capacity in µAh
 * Or < 0 if something fails.
 */
static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di,
					   union power_supply_propval *val)
{}

/*
 * Return the Design Capacity in µAh
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di,
				     union power_supply_propval *val)
{}

/*
 * Return the battery Available energy in µWh
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di,
				       union power_supply_propval *val)
{}

/*
 * Return the battery temperature in tenths of degree Celsius
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di,
					    union power_supply_propval *val)
{}

/*
 * Return the battery Cycle count total
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di,
				     union power_supply_propval *val)
{}

/*
 * Read a time register.
 * Return < 0 if something fails.
 */
static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg,
				     union power_supply_propval *val)
{}

/*
 * Returns true if a battery over temperature condition is detected
 */
static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
{}

/*
 * Returns true if a battery under temperature condition is detected
 */
static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
{}

/*
 * Returns true if a low state of charge condition is detected
 */
static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
{}

/*
 * Returns true if reported battery capacity is inaccurate
 */
static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,
						 u16 flags)
{}

static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di,
				       union power_supply_propval *val)
{}

static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
{}

/*
 * Return the battery average current in µA and the status
 * Note that current can be negative signed as well
 * Or 0 if something fails.
 */
static int bq27xxx_battery_current_and_status(
	struct bq27xxx_device_info *di,
	union power_supply_propval *val_curr,
	union power_supply_propval *val_status,
	struct bq27xxx_reg_cache *cache)
{}

static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
{}

void bq27xxx_battery_update(struct bq27xxx_device_info *di)
{}
EXPORT_SYMBOL_GPL();

static void bq27xxx_battery_poll(struct work_struct *work)
{}

/*
 * Get the average power in µW
 * Return < 0 if something fails.
 */
static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di,
				   union power_supply_propval *val)
{}

static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
					  union power_supply_propval *val)
{}

/*
 * Return the battery Voltage in millivolts
 * Or < 0 if something fails.
 */
static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
				   union power_supply_propval *val)
{}

static int bq27xxx_simple_value(int value,
				union power_supply_propval *val)
{}

static int bq27xxx_battery_get_property(struct power_supply *psy,
					enum power_supply_property psp,
					union power_supply_propval *val)
{}

static void bq27xxx_external_power_changed(struct power_supply *psy)
{}

static void bq27xxx_battery_mutex_destroy(void *data)
{}

int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
{}
EXPORT_SYMBOL_GPL();

void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_PM_SLEEP
static int bq27xxx_battery_suspend(struct device *dev)
{}

static int bq27xxx_battery_resume(struct device *dev)
{}
#endif /* CONFIG_PM_SLEEP */

SIMPLE_DEV_PM_OPS(bq27xxx_battery_battery_pm_ops,
		  bq27xxx_battery_suspend, bq27xxx_battery_resume);
EXPORT_SYMBOL_GPL();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();