BigW Consortium Gitlab

Commit 42389f75 by Ashish Syal

added working bq27426 driver

parent bd8986ad
#ifndef BQ27426_PLATFORM_DATA_H
#define BQ27426_PLATFORM_DATA_H
struct bq27426_platform_data
{
int energy_full_design_uwh;
int charge_full_design_uah;
int voltage_min_design_uv;
};
#endif /* BQ27426_PLATFORM_DATA_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_BQ27X00_BATTERY_H__
#define __LINUX_BQ27X00_BATTERY_H__
#include <linux/power_supply.h>
#include "bq27426-platform-data.h"
enum bq27xxx_chip {
BQ27000 = 1, /* bq27000, bq27200 */
BQ27010, /* bq27010, bq27210 */
......@@ -32,6 +33,18 @@ enum bq27xxx_chip {
};
struct bq27xxx_device_info;
//struct power_supply_battery_info;
struct power_supply_battery_info {
int energy_full_design_uwh; /* microWatt-hours */
int charge_full_design_uah; /* microAmp-hours */
int voltage_min_design_uv; /* microVolts */
int precharge_current_ua; /* microAmps */
int charge_term_current_ua; /* microAmps */
int constant_charge_current_max_ua; /* microAmps */
int constant_charge_voltage_max_uv; /* microVolts */
};
struct bq27xxx_access_methods {
int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
int (*write)(struct bq27xxx_device_info *di, u8 reg, int value, bool single);
......@@ -66,14 +79,14 @@ struct bq27xxx_device_info {
int charge_design_full;
unsigned long last_update;
struct delayed_work work;
struct power_supply *bat;
struct power_supply bat;
struct list_head list;
struct mutex lock;
u8 *regs;
};
void bq27xxx_battery_update(struct bq27xxx_device_info *di);
int bq27xxx_battery_setup(struct bq27xxx_device_info *di);
int bq27xxx_battery_setup(struct bq27xxx_device_info *di, struct bq27426_platform_data *platform_data);
void bq27xxx_battery_teardown(struct bq27xxx_device_info *di);
#endif
sources:
{
bq27xxx_battery.c
bq27xxx_battery_i2c.c
devres_backport.c
bq27xxx_battery_source.c
power_supply_backport.c
}
\ No newline at end of file
}
......@@ -18,8 +18,8 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/unaligned.h>
#include "bq27xxx_battery.h"
#include "bq27426-platform-data.h"
static DEFINE_IDR(battery_id);
static DEFINE_MUTEX(battery_mutex);
......@@ -147,17 +147,21 @@ static int bq27xxx_battery_i2c_bulk_write(struct bq27xxx_device_info *di,
static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
dev_info(client->dev, " BQ27xx probe");
struct bq27xxx_device_info *di;
int ret;
char *name;
int num;
dev_info(client->dev, " BQ27xx probe");
struct bq27426_platform_data *platform_data;
platform_data = client->dev.platform_data;
dev_info(&client->dev, " BQ27xx probe");
/* Get new ID for the new battery device */
mutex_lock(&battery_mutex);
num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
mutex_unlock(&battery_mutex);
dev_info(&client->dev, " BQ27xx probe battery id");
if (num < 0)
return num;
......@@ -173,13 +177,13 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
di->dev = &client->dev;
di->chip = id->driver_data;
di->name = name;
di->bus.read = bq27xxx_battery_i2c_read;
di->bus.write = bq27xxx_battery_i2c_write;
di->bus.read_bulk = bq27xxx_battery_i2c_bulk_read;
di->bus.write_bulk = bq27xxx_battery_i2c_bulk_write;
dev_info(&client->dev, " BQ27xx probe battery setup");
ret = bq27xxx_battery_setup(di);
ret = bq27xxx_battery_setup(di, platform_data);
if (ret)
goto err_failed;
......@@ -258,7 +262,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
#ifdef CONFIG_OF
//#ifdef CONFIG_OF
static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
{ .compatible = "ti,bq27200" },
{ .compatible = "ti,bq27210" },
......@@ -289,7 +293,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
{},
};
MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table);
#endif
//#endif
static struct i2c_driver bq27xxx_battery_i2c_driver = {
.driver = {
......
sources:
{
bq27xxx_battery_i2c.c
devres_backport.c
}
requires:
{
kernelModules:
{
$CURDIR/bq27xxx_battery
}
}
......@@ -55,9 +55,9 @@
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/of.h>
//#include "power_supply_backport.h"
#include "bq27xxx_battery.h"
#include "bq27426-platform-data.h"
#define BQ27XXX_MANUFACTURER "Texas Instruments"
/* BQ27XXX Flags */
......@@ -84,7 +84,7 @@
#define BQ27XXX_SOFT_RESET 0x42
#define BQ27XXX_RESET 0x41
#define BQ27XXX_RS (20) /* Resistor sense mOhm */
#define BQ27XXX_RS (10) /* Resistor sense mOhm */
#define BQ27XXX_POWER_CONSTANT (29200) /* 29.2 µV^2 * 1000 */
#define BQ27XXX_CURRENT_CONSTANT (3570) /* 3.57 µV * 1000 */
......@@ -661,7 +661,7 @@ static enum power_supply_property bq27421_props[] = {
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
//POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_MANUFACTURER,
};
#define bq27425_props bq27421_props
......@@ -742,6 +742,7 @@ static struct bq27xxx_dm_reg bq27426_dm_regs[] = {
[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 10, 2, 2500, 3700 },
};
#if 0 /* not yet tested */
#define bq27441_dm_regs bq27421_dm_regs
#else
......@@ -1265,18 +1266,34 @@ static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
/* assume bq27xxx_battery_update() is called hereafter */
}
static void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
static void bq27xxx_battery_settings(struct bq27xxx_device_info *di, struct bq27426_platform_data *platform_data )
{
struct power_supply_battery_info info = {};
/* struct power_supply_battery_info info = {
.energy_full_design_uwh = 16280000,
.charge_full_design_uah = 4400000,
.voltage_min_design_uv = 3300000,
.precharge_current_ua = -EINVAL,
.charge_term_current_ua = -EINVAL,
.constant_charge_current_max_ua = -EINVAL,
.constant_charge_voltage_max_uv = -EINVAL,
};*/
unsigned int min, max;
if (power_supply_get_battery_info(di->bat, &info) < 0)
return;
struct power_supply_battery_info info;
info.energy_full_design_uwh = platform_data->energy_full_design_uwh;
info.charge_full_design_uah = platform_data->charge_full_design_uah;
info.voltage_min_design_uv = platform_data->voltage_min_design_uv;
// struct bq27xxx_platform_data *platform_data;
dev_info(di->dev, " in the setting first break");
//if (power_supply_get_battery_info(&di->bat, &info) < 0)
// return;
if (!di->dm_regs) {
dev_warn(di->dev, "data memory update not supported for chip\n");
return;
}
dev_info(di->dev, " in the setting third break");
if (info.energy_full_design_uwh != info.charge_full_design_uah) {
if (info.energy_full_design_uwh == -EINVAL)
......@@ -1407,8 +1424,13 @@ static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
dcap = (dcap << 8) * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
else
dcap *= 1000;
return dcap;
dev_info(di->dev, " value of dcap is %d", dcap);
dev_info(di->dev, " value of dcap is %d", dcap);
dev_info(di->dev, " value of dcap is %d", dcap);
dev_info(di->dev, " value of dcap is %d", dcap);
dev_info(di->dev, " value of dcap is %d", dcap);
dev_info(di->dev, " value of dcap is %d", dcap);
return dcap;
}
/*
......@@ -1583,7 +1605,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
if (cache.flags >= 0) {
cache.temperature = bq27xxx_battery_read_temperature(di);
if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n");
dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
cache.capacity = -ENODATA;
cache.energy = -ENODATA;
cache.time_to_empty = -ENODATA;
......@@ -1615,7 +1637,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
}
if (di->cache.capacity != cache.capacity)
power_supply_changed(di->bat);
power_supply_changed(&di->bat);
if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
di->cache = cache;
......@@ -1679,7 +1701,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
status = POWER_SUPPLY_STATUS_FULL;
else if (di->cache.flags & BQ27000_FLAG_CHGS)
status = POWER_SUPPLY_STATUS_CHARGING;
else if (power_supply_am_i_supplied(di->bat) > 0)
else if (power_supply_am_i_supplied(&di->bat) > 0)
status = POWER_SUPPLY_STATUS_NOT_CHARGING;
else
status = POWER_SUPPLY_STATUS_DISCHARGING;
......@@ -1763,8 +1785,9 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
union power_supply_propval *val)
{
int ret = 0;
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
//struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
struct bq27xxx_device_info *di = container_of(psy, struct bq27xxx_device_info, bat);
mutex_lock(&di->lock);
if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
cancel_delayed_work_sync(&di->work);
......@@ -1851,20 +1874,18 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
static void bq27xxx_external_power_changed(struct power_supply *psy)
{
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
// struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
struct bq27xxx_device_info *di = container_of(psy, struct bq27xxx_device_info, bat);
cancel_delayed_work_sync(&di->work);
schedule_delayed_work(&di->work, 0);
}
int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
int bq27xxx_battery_setup(struct bq27xxx_device_info *di, struct bq27426_platform_data *platform_data)
{
struct power_supply_desc *psy_desc;
struct power_supply_config psy_cfg = {
.of_node = di->dev->of_node,
.drv_data = di,
};
// struct power_supply *psy_desc;
int ret = 0;
dev_info(di->dev, " in the setup");
INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
mutex_init(&di->lock);
......@@ -1872,32 +1893,47 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
di->unseal_key = bq27xxx_chip_data[di->chip].unseal_key;
di->dm_regs = bq27xxx_chip_data[di->chip].dm_regs;
di->opts = bq27xxx_chip_data[di->chip].opts;
dev_info(di->dev, " in the setup second break");
psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
if (!psy_desc)
return -ENOMEM;
/*&di->bat = devm_kzalloc(di->dev, sizeof(struct power_supply), GFP_KERNEL);
if (!di->bat)
return -ENOMEM;*/
/*
psy_desc->name = di->name;
psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
psy_desc->properties = bq27xxx_chip_data[di->chip].props;
psy_desc->num_properties = bq27xxx_chip_data[di->chip].props_size;
psy_desc->get_property = bq27xxx_battery_get_property;
psy_desc->external_power_changed = bq27xxx_external_power_changed;
di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
if (IS_ERR(di->bat)) {
*/
dev_info(di->dev, " in the setup third break");
di->bat.name = "BQ27246";
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
di->bat.properties = bq27xxx_chip_data[di->chip].props;
di->bat.num_properties = bq27xxx_chip_data[di->chip].props_size;
di->bat.get_property = bq27xxx_battery_get_property;
di->bat.external_power_changed = bq27xxx_external_power_changed;
dev_info(di->dev, " in the setup fourth break");
ret = power_supply_register_no_ws(di->dev, &di->bat);
if (ret != 0) {
dev_err(di->dev, "failed to register battery\n");
return PTR_ERR(di->bat);
return ret;
}
dev_info(di->dev, " in the setup fifth break");
bq27xxx_battery_settings(di, platform_data);
dev_info(di->dev, " in the setup sixth break");
bq27xxx_battery_settings(di);
bq27xxx_battery_update(di);
dev_info(di->dev, " in the setup seventh break");
mutex_lock(&bq27xxx_list_lock);
list_add(&di->list, &bq27xxx_battery_devices);
mutex_unlock(&bq27xxx_list_lock);
dev_info(di->dev, " in the setup eigth break");
return 0;
return ret;
}
EXPORT_SYMBOL_GPL(bq27xxx_battery_setup);
......@@ -1913,7 +1949,7 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
cancel_delayed_work_sync(&di->work);
power_supply_unregister(di->bat);
power_supply_unregister(&di->bat);
mutex_lock(&bq27xxx_list_lock);
list_del(&di->list);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment