1
0
Fork 0

power: supply: remove max77818_battery driver

The driver is buggy and not functional at all.  Let's remove it and
start over again.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
pull/10/head
Shawn Guo 2019-08-06 19:08:59 +02:00 committed by Steinar Bakkemo
parent 9cd386c0a9
commit 4b7d7344ce
1 changed files with 0 additions and 538 deletions

View File

@ -1,538 +0,0 @@
/*
* max77818_battery.c
* fuel-gauge systems for lithium-ion (Li+) batteries
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This driver is based on max17048_battery.c
*/
#include <asm/unaligned.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/mfd/max77818/max77818.h>
#include <linux/mfd/max77818/max77818_battery.h>
/* for Regmap */
#include <linux/regmap.h>
/* for Device Tree */
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#define REG_STATUS 0x00
#define BIT_SMX BIT (14)
#define BIT_TMX BIT (13)
#define BIT_VMX BIT (12)
#define BIT_SMN BIT (10)
#define BIT_TMN BIT (9)
#define BIT_VMN BIT (8)
#define BIT_dSOCi BIT (7)
#define REG_VALRT_TH 0x01
#define REG_TALRT_TH 0x02
#define REG_SALRT_TH 0x03
#define REG_TEMP 0x08
#define REG_VCELL 0x09
#define REG_AVGVCELL 0x19
#define REG_CONFIG 0x1D
#define BIT_Aen BIT (2)
#define REG_VERSION 0x21
#define REG_LEARNCFG 0x28
#define REG_FILTERCFG 0x29
#define REG_MISCCFG 0x2B
#define REG_CGAIN 0x2E
#define REG_RCOMP0 0x38
#define REG_CONFIG2 0xBB
#define BIT_dSOCen BIT (7)
#define REG_VFOCV 0xFB
#define REG_VFSOC 0xFF
#define MAX77818_FG_DELAY 1000
#define MAX77818_BATTERY_FULL 100
#define MAX77818_BATTERY_LOW 15
#define MAX77818_VERSION_NO 0x20B0
/* Local flag indicating if probe has finished
Checked in property_is_writable(..) callback which is expected to be called during power supply registration */
static volatile bool probeDone = false;
struct mutex probeDoneLock;
struct max77818_chip {
struct device *dev;
struct max77818_dev *max77818;
struct regmap *regmap;
int fg_irq;
struct delayed_work work;
struct power_supply *battery;
/* alert */
int alert_threshold;
/* State Of Connect */
int ac_online;
int usb_online;
/* battery voltage */
int vcell;
/* battery capacity */
int soc;
/* State Of Charge */
int status;
/* battery health */
int health;
/* battery capacity */
int capacity_level;
int lasttime_vcell;
int lasttime_soc;
int lasttime_status;
struct max77818_fg_platform_data *pdata;
};
static int max77818_fg_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct max77818_chip *chip = (struct max77818_chip*) psy->drv_data;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = chip->status;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = chip->vcell;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = chip->soc;
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = chip->health;
break;
case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
val->intval = chip->capacity_level;
break;
default:
return -EINVAL;
}
return 0;
}
static void max77818_fg_get_vcell(struct max77818_chip *max77818_fg)
{
uint16_t vcell;
int rc;
rc = max77818_fg_read(max77818_fg->regmap, REG_VCELL, &vcell);
if (rc < 0)
dev_err(max77818_fg->dev, "%s: err %d\n", __func__, rc);
else {
pr_info("%s: vcell raw value(0x%4x)\n", __func__, vcell);
max77818_fg->vcell = (vcell>>3)*625;
}
}
static void max77818_fg_get_soc(struct max77818_chip *max77818_fg)
{
uint16_t soc;
int rc;
rc = max77818_fg_read(max77818_fg->regmap, REG_VFSOC, &soc);
if (rc < 0)
dev_err(max77818_fg->dev, "%s: err %d\n", __func__, rc);
else
max77818_fg->soc = (uint16_t)soc >> 8;
if (max77818_fg->soc > MAX77818_BATTERY_FULL) {
max77818_fg->soc = MAX77818_BATTERY_FULL;
max77818_fg->status = POWER_SUPPLY_STATUS_FULL;
max77818_fg->capacity_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
max77818_fg->health = POWER_SUPPLY_HEALTH_GOOD;
} else if (max77818_fg->soc < MAX77818_BATTERY_LOW) {
max77818_fg->health = POWER_SUPPLY_HEALTH_DEAD;
max77818_fg->capacity_level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
} else {
max77818_fg->health = POWER_SUPPLY_HEALTH_GOOD;
max77818_fg->capacity_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
}
}
static uint16_t max77818_fg_get_version(struct max77818_chip *max77818_fg)
{
uint16_t version;
int rc;
rc = max77818_fg_read(max77818_fg->regmap, REG_VERSION, &version);
if (rc < 0)
dev_err(max77818_fg->dev, "%s: err %d\n", __func__, rc);
return version;
}
static bool max77818_fg_check_status(struct max77818_chip *max77818_fg)
{
uint16_t data;
bool ret = false;
/* check if Smn was generated */
if (max77818_fg_read(max77818_fg->regmap, REG_STATUS, &data) < 0)
return ret;
pr_info("%s: status_reg(0x%4x)\n", __func__, data);
/* minimum SOC threshold exceeded. */
if (data & BIT_SMN)
ret = true;
/* check 1% SOC change happened */
if (data & BIT_dSOCi) {
max77818_fg_get_vcell(max77818_fg);
max77818_fg_get_soc(max77818_fg);
power_supply_changed(max77818_fg->battery);
pr_info("%s: 1% soc changed, SOC=%d, VCELL=%d\n",
__func__, max77818_fg->soc, max77818_fg->vcell);
}
/* clear status reg */
if (!ret) {
data = data & 0x007F;
if (max77818_fg_write(max77818_fg->regmap, REG_STATUS, data) < 0)
return ret;
}
return ret;
}
/* callback to be called during power supply registration to check if the probe routine has finished */
static int max77818_fg_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
printk("[---- SBA ----] max77818-battery.property_is_writable called !\n");
int probeIsDone = __sync_get(probeDone, probeDoneLock);
printk("[---- SBA ----] probeDone: %s", (probeIsDone ? "TRUE" : "FALSE"));
}
/* callback to be called when external power has changed */
static void max77818_fg_external_power_changed(struct power_supply *psy)
{
printk("[---- SBA ----] max77818-battery.external_power_changed called !\n");
}
/* callbask to be called to set charged state */
static void max77818_fg_set_charged(struct power_supply *psy)
{
printk("[---- SBA ----] max77818-battery.set_charged called !\n");
}
//static void max77818_fg_work(struct work_struct *work)
//{
// struct max77818_chip *chip;
// chip = container_of(work, struct max77818_chip, work.work);
// max77818_fg_get_vcell(chip);
// max77818_fg_get_soc(chip);
// if (chip->vcell != chip->lasttime_vcell ||
// chip->soc != chip->lasttime_soc ||
// chip->status != chip->lasttime_status) {
// chip->lasttime_vcell = chip->vcell;
// chip->lasttime_soc = chip->soc;
// power_supply_changed(chip->battery);
// }
// schedule_delayed_work(&chip->work, MAX77818_FG_DELAY);
//}
static irqreturn_t max77818_fg_irq_thread(int irq, void *irq_data)
{
struct max77818_chip *fuelgauge = irq_data;
bool fuel_alerted;
if (fuelgauge->pdata->soc_alert_threshold >= 0) {
fuel_alerted = max77818_fg_check_status(fuelgauge);
pr_info("%s: Fuel-alert %salerted!\n",
__func__, fuel_alerted ? "" : "NOT ");
// schedule_delayed_work(&fuelgauge->work, 0);
}
return IRQ_HANDLED;
}
static enum power_supply_property max77818_fg_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
};
static int max77818_fg_initialize(struct max77818_chip *chip)
{
uint16_t config, val;
uint8_t data[2];
int ret;
pr_info("%s\n", __func__);
#if 1
max77818_fg_get_vcell(chip);
pr_info("<%s> vcell %d\n", __func__, chip->vcell);
max77818_fg_get_soc(chip);
pr_info("<%s> soc %d\n", __func__, chip->soc);
#endif
/* 1. set fuel gauge alert configuration */
/* SALRT Threshold setting */
data[0] = chip->pdata->soc_alert_threshold;
data[1] = 0xff;
val = (data[1]<<8) | data[0];
max77818_fg_write(chip->regmap, REG_SALRT_TH, val);
/* VALRT Threshold setting */
data[0] = 0x00;
data[1] = 0xff;
val = (data[1]<<8) | data[0];
max77818_fg_write(chip->regmap, REG_VALRT_TH, val);
/* TALRT Threshold setting */
data[0] = 0x80;
data[1] = 0x7f;
val = (data[1]<<8) | data[0];
max77818_fg_write(chip->regmap, REG_TALRT_TH, val);
ret = max77818_fg_read(chip->regmap, REG_CONFIG, &val);
if (ret < 0)
return ret;
/*Enable Alert (Aen = 1) */
config = val | (0x01<<2);
ret = max77818_fg_write(chip->regmap, REG_CONFIG, config);
if (ret < 0)
return ret;
/* 2. set SOC 1% change alert */
ret = max77818_fg_read(chip->regmap, REG_CONFIG2, &val);
if (ret < 0)
return ret;
config = val | BIT_dSOCen;
ret = max77818_fg_write(chip->regmap, REG_CONFIG2, config);
if (ret < 0)
return ret;
return 0;
}
#ifdef CONFIG_OF
static int max77818_fg_parse_dt(struct max77818_chip *fuelgauge, struct device_node **of_node)
{
struct device_node *np = of_find_node_by_name(NULL, "fuelgauge");
struct max77818_fg_platform_data *pdata = fuelgauge->pdata;
*of_node = np;
int ret;
/* reset, irq gpio info */
if (np == NULL) {
pr_err("%s np NULL\n", __func__);
return -1;
} else {
ret = of_property_read_u32(np, "fuelgauge,fuel_alert_soc",
&pdata->soc_alert_threshold);
if (ret < 0)
pr_err("%s error reading pdata->fuel_alert_soc %d\n",
__func__, ret);
}
return 0;
}
#endif
static int max77818_fg_probe(struct platform_device *pdev)
{
struct max77818_dev *max77818 = dev_get_drvdata(pdev->dev.parent);
struct max77818_fg_platform_data *pdata = dev_get_platdata(max77818->dev);
struct max77818_chip *chip;
struct power_supply_desc psy_chg_desc;
struct power_supply_config psy_chg_config;
uint16_t version;
int ret = 0;
u8 val;
printk("[---- SBA ----] %s Enter:\n", __func__);
pr_info("%s: MAX77818 Fuelgauge Driver Loading\n", __func__);
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
chip->dev = &pdev->dev;
chip->pdata = pdata;
chip->regmap = max77818->regmap_fuel;
#if defined(CONFIG_OF)
ret = max77818_fg_parse_dt(chip, &psy_chg_config.of_node);
if (ret < 0) {
pr_err("%s not found charger dt! ret[%d]\n",
__func__, ret);
}
#endif
version = max77818_fg_get_version(chip);
dev_info(&pdev->dev, "MAX77818 Fuel-Gauge Ver 0x%x\n", version);
if (version != MAX77818_VERSION_NO) {
ret = -ENODEV;
goto error;
}
platform_set_drvdata(pdev, chip);
psy_chg_config.drv_data = chip;
/* psy_chg_config.supplied_to ?? */
/* psy_chg_config.num_supplicants */
psy_chg_desc.name = "max77818-battery";
psy_chg_desc.type = POWER_SUPPLY_TYPE_BATTERY;
psy_chg_desc.properties = max77818_fg_battery_props;
psy_chg_desc.num_properties = ARRAY_SIZE(max77818_fg_battery_props);
psy_chg_desc.get_property = max77818_fg_get_property;
/* psy_chg_desc.set_property = ?;*/
psy_chg_desc.property_is_writeable = max77818_fg_property_is_writeable;
psy_chg_desc.external_power_changed = max77818_fg_external_power_changed;
psy_chg_desc.set_charged = max77818_fg_set_charged;
psy_chg_desc.no_thermal = true;
psy_chg_desc.use_for_apm = false;
chip->battery = power_supply_register(&pdev->dev, &psy_chg_desc, &psy_chg_config);
if (ret) {
dev_err(&pdev->dev, "failed: power supply register\n");
goto error;
}
chip->fg_irq = regmap_irq_get_virq(max77818->irqc_intsrc, MAX77818_FG_INT);
dev_info(&pdev->dev, "MAX77818 Fuel-Gauge irq %d\n", chip->fg_irq);
if (chip->fg_irq > 0) {
// INIT_DELAYED_WORK(&chip->work, max77818_fg_work);
ret = request_threaded_irq(chip->fg_irq, NULL, max77818_fg_irq_thread,
IRQF_TRIGGER_FALLING, "fuelgauge-irq", chip);
if (ret) {
pr_err("%s: Failed to Reqeust IRQ\n", __func__);
goto error1;
}
}
ret = max77818_fg_initialize(chip);
if (ret < 0) {
dev_err(&pdev->dev, "Error: Initializing fuel-gauge\n");
goto error2;
}
max77818_read(max77818->regmap_pmic, REG_INTSRCMASK, &val);
pr_info("<%s> intsrc_mask %Xh\n", pdev->name, val);
return 0;
error2:
if (chip->fg_irq)
free_irq(chip->fg_irq, chip);
error1:
power_supply_unregister(chip->battery);
error:
kfree(chip);
return ret;
}
static int max77818_fg_remove(struct platform_device *pdev)
{
struct max77818_chip *chip = platform_get_drvdata(pdev);
power_supply_unregister(chip->battery);
cancel_delayed_work(&chip->work);
kfree(chip);
return 0;
}
#ifdef CONFIG_PM
static int max77818_fg_suspend(struct device *dev)
{
struct max77818_chip *chip = dev_get_drvdata(dev);
cancel_delayed_work(&chip->work);
return 0;
}
static int max77818_fg_resume(struct device *dev)
{
struct max77818_chip *chip = dev_get_drvdata(dev);
schedule_delayed_work(&chip->work, MAX77818_FG_DELAY);
return 0;
}
#else
#define max77818_fg_suspend NULL
#define max77818_fg_resume NULL
#endif /* CONFIG_PM */
#if defined(CONFIG_OF)
static struct of_device_id max77818_fg_dt_ids[] = {
{ .compatible = "maxim,max77818-fuelgauge" },
{ }
};
MODULE_DEVICE_TABLE(of, max77818_fg_dt_ids);
#endif /* CONFIG_OF */
static SIMPLE_DEV_PM_OPS(max77818_fg_pm_ops, max77818_fg_suspend,
max77818_fg_resume);
static struct platform_driver max77818_fg_driver = {
.driver = {
.name = "max77818-fuelgauge",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &max77818_fg_pm_ops,
#endif
#if defined(CONFIG_OF)
.of_match_table = max77818_fg_dt_ids,
#endif /* CONFIG_OF */
},
.probe = max77818_fg_probe,
.remove = max77818_fg_remove,
};
static int __init max77818_fg_init(void)
{
return platform_driver_register(&max77818_fg_driver);
}
module_init(max77818_fg_init);
static void __exit max77818_fg_exit(void)
{
platform_driver_unregister(&max77818_fg_driver);
}
module_exit(max77818_fg_exit);
MODULE_AUTHOR("TaiEup Kim <clark.kim@maximintegrated.com>");
MODULE_DESCRIPTION("MAX77818 Fuel Gauge");
MODULE_LICENSE("GPL");