blob: 34b533a36e831ec6ba2308722c1011b195fd031f [file] [log] [blame]
/* Copyright (c) 2017, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/qpnp/qpnp-adc.h>
#include <linux/of_gpio.h>
enum {
POWER_SUPPLY_BATTERY_ID_UNKNOWN = 0,
POWER_SUPPLY_BATTERY_ID_GUANGYU,
POWER_SUPPLY_BATTERY_ID_DESAY,
};
#define BATT_ID_VOL_MIN_UV 0
#define BATT_ID_VOL_AVG_UV 548038
#define BATT_ID_VOL_MAX_UV 1600000
static int global_batt_id = -1;
int get_global_batt_id(void)
{
return global_batt_id;
}
/**************************************************************************
FUNCTION get_batt_id
DESCRIPTION :Return batt id on success, 0 otherwise
**************************************************************************/
static int get_batt_id(struct qpnp_vadc_chip *vadc)
{
int rc = 0;
struct qpnp_vadc_result results = {0};
if (NULL == vadc)
{
pr_err("get batt id error, vadc is not exist\n");
return POWER_SUPPLY_BATTERY_ID_UNKNOWN;
}
rc = qpnp_vadc_read(vadc, LR_MUX2_BAT_ID, &results);
if (rc)
{
pr_err("unable to read channel = %d\n", LR_MUX2_BAT_ID);
return POWER_SUPPLY_BATTERY_ID_UNKNOWN;
}
if ((results.physical > BATT_ID_VOL_MIN_UV)
&& (results.physical <= BATT_ID_VOL_AVG_UV))
{
rc = POWER_SUPPLY_BATTERY_ID_GUANGYU;
}
else if ((results.physical > BATT_ID_VOL_AVG_UV)
&& (results.physical <= BATT_ID_VOL_MAX_UV))
{
rc = POWER_SUPPLY_BATTERY_ID_DESAY;
}
else
{
rc = POWER_SUPPLY_BATTERY_ID_UNKNOWN;
}
return rc;
}
static int battid_probe(struct platform_device *pdev)
{
int rc = 0;
struct device_node *np = NULL;
struct qpnp_vadc_chip *chip_battid = NULL;
pr_info("battid probe begin...\n");
/*get device tree node*/
np = pdev->dev.of_node;
if (!np)
{
pr_err("get device tree node failed!\n ");
return -1;
}
/* get VADC */
chip_battid = qpnp_get_vadc(&(pdev->dev), "battid");
if (IS_ERR(chip_battid))
{
rc = PTR_ERR(chip_battid);
if (rc != -EPROBE_DEFER)
{
pr_err("battid vadc property missing\n");
}
return rc;
}
/* initialize global batt id */
global_batt_id = get_batt_id(chip_battid);
pr_info("global batt id is %d\n", global_batt_id);
return 0;
}
static int battid_remove(struct platform_device *pdev)
{
return 0;
}
static struct of_device_id battid_match_table[] = {
{.compatible = "huawei,battid"},
{},
};
static struct platform_driver battid_driver = {
.probe = battid_probe,
.remove = battid_remove,
.driver = {
.name = "battid",
.owner = THIS_MODULE,
.of_match_table = battid_match_table,
},
};
static int __init battid_init(void)
{
return platform_driver_register(&battid_driver);
}
static void __exit battid_exit(void)
{
platform_driver_unregister(&battid_driver);
}
module_init(battid_init);
module_exit(battid_exit);
MODULE_AUTHOR("hw Inc.");
MODULE_DESCRIPTION("Driver for battery id");