M7350v3_en_gpl
This commit is contained in:
13
kernel/drivers/power/Kconfig
Executable file → Normal file
13
kernel/drivers/power/Kconfig
Executable file → Normal file
@@ -350,12 +350,6 @@ config SMB137C_CHARGER
|
||||
charging, setting the input current limit, and enabling USB OTG mode
|
||||
in order to supply 5 V on the VBUS line.
|
||||
|
||||
config MP2617_CHARGER
|
||||
tristate "Summit MP2617 Battery Charger"
|
||||
help
|
||||
The MP2617 charger chip is a charging solution. This driver supports
|
||||
enabling and disabling charging, setting the input current limit.
|
||||
|
||||
config SMB349_CHARGER
|
||||
tristate "smb349 charger"
|
||||
depends on I2C
|
||||
@@ -501,11 +495,4 @@ config QPNP_BMS
|
||||
Say Y here to enable support for QPNP chip bms device.
|
||||
It registers a fuelgauge bms power supply to report
|
||||
State of Charge.
|
||||
|
||||
config POWER_BANK_DETECT_SUPPORT
|
||||
tristate "Support Power Bank Detection"
|
||||
default n
|
||||
help
|
||||
If support power bank detection, we can get the current
|
||||
output.
|
||||
endif # POWER_SUPPLY
|
||||
|
1
kernel/drivers/power/Makefile
Executable file → Normal file
1
kernel/drivers/power/Makefile
Executable file → Normal file
@@ -56,7 +56,6 @@ obj-$(CONFIG_BATTERY_BQ27541) += bq27541_fuelgauger.o
|
||||
obj-$(CONFIG_BATTERY_BQ28400) += bq28400_battery.o
|
||||
obj-$(CONFIG_SMB137B_CHARGER) += smb137b.o
|
||||
obj-$(CONFIG_SMB137C_CHARGER) += smb137c-charger.o
|
||||
obj-$(CONFIG_MP2617_CHARGER) += mp2617-charger.o
|
||||
obj-$(CONFIG_PM8XXX_CCADC) += pm8xxx-ccadc.o
|
||||
obj-$(CONFIG_PM8921_BMS) += pm8921-bms.o
|
||||
obj-$(CONFIG_QPNP_BMS) += qpnp-bms.o
|
||||
|
@@ -1,879 +0,0 @@
|
||||
/*******************************************************************************
|
||||
Copyright (C), 2014, TP-LINK TECHNOLOGIES CO., LTD.
|
||||
File name : mp2617-charger.c
|
||||
Description : Driver for charge ic mp2617.
|
||||
Author : linyunfeng
|
||||
|
||||
History:
|
||||
------------------------------
|
||||
V0.2, 2014-04-29, linyunfeng complete the driver of mp2617.
|
||||
V0.1, 2014-03-29, linyunfeng create file.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/qpnp/qpnp-adc.h>
|
||||
|
||||
#ifdef MP2617_DEBUG
|
||||
#undef dev_dbg
|
||||
#define dev_dbg(dev, format, arg...) dev_printk(KERN_INFO, dev, format, ##arg)
|
||||
#endif
|
||||
|
||||
/* USB, set 500mA limit */
|
||||
#define USB_INPUT_CURRENT_LIMIT_UA 500000
|
||||
|
||||
/* Charger, set 1000mA limit */
|
||||
#define CHARGER_INPUT_CURRENT_LIMIT_UA 1000000
|
||||
|
||||
static u32 supported_input_current[] = {
|
||||
USB_INPUT_CURRENT_LIMIT_UA,
|
||||
CHARGER_INPUT_CURRENT_LIMIT_UA,
|
||||
};
|
||||
|
||||
#define DEFAULT_INPUT_CURRENT_LIMIT_UA CHARGER_INPUT_CURRENT_LIMIT_UA
|
||||
|
||||
/* Default resistor used for detection */
|
||||
#define DEFAULT_CHARGE_DET_RESISTOR 100
|
||||
|
||||
/* Default battery resistor */
|
||||
#define DEFAULT_BATTERY_RESISTOR 120
|
||||
|
||||
/* Correspondence table of voltage and temperature */
|
||||
static const int adc_map_temp[][2] =
|
||||
{
|
||||
{1800, -100},
|
||||
{1577, -20},
|
||||
{1524, -15},
|
||||
{1463, -10},
|
||||
{1396, -5},
|
||||
{1322, 0},
|
||||
{1243, 5},
|
||||
{1159, 10},
|
||||
{1073, 15},
|
||||
{986, 20},
|
||||
{900, 25},
|
||||
{816, 30},
|
||||
{736, 35},
|
||||
{660, 40},
|
||||
{590, 45},
|
||||
{526, 50},
|
||||
{468, 55},
|
||||
{416, 60},
|
||||
{369, 65},
|
||||
{327, 70},
|
||||
{0, 1000}
|
||||
};
|
||||
|
||||
struct mp2617_chip {
|
||||
struct platform_device *client;
|
||||
struct power_supply psy;
|
||||
struct power_supply *usb_psy;
|
||||
struct mutex lock;
|
||||
int input_current_limit_ua;
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
int charging_det_resistor;
|
||||
int battery_resistor;
|
||||
u32 boost_en_gpio;
|
||||
#endif
|
||||
int battery_health;
|
||||
int charging_vbat_div;
|
||||
bool battery_present;
|
||||
bool charging_enabled;
|
||||
bool charging_allowed;
|
||||
u32 charging_en_gpio;
|
||||
u32 charging_ok_gpio;
|
||||
u32 charging_m0_gpio;
|
||||
u32 charging_m1_gpio;
|
||||
};
|
||||
|
||||
static enum power_supply_property mp2617_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_TEMP,
|
||||
POWER_SUPPLY_PROP_CHARGING_ENABLED,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_CHG_OK,
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
POWER_SUPPLY_PROP_VOLTAGE_DROP,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
/*******************************************************************************
|
||||
Function : mp2617_enable_boost
|
||||
Description : Enable or disable the boost chip
|
||||
Input : chip: chip data
|
||||
enable: true: enable, false: disable
|
||||
Output : None
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_enable_boost(struct mp2617_chip *chip, bool enable)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (true == enable) {
|
||||
rc = gpio_direction_output(chip->boost_en_gpio, 1);
|
||||
} else {
|
||||
rc = gpio_direction_output(chip->boost_en_gpio, 0);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
dev_err(&chip->client->dev, "%s: enable or disable boost error\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
dev_dbg(&chip->client->dev, "%s, enable=%d, rc = %d\n", __func__, enable, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_get_property_voltage_drop
|
||||
Description : Get the voltage drop by power supply
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : voltage or error code
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_get_property_voltage_drop(struct mp2617_chip *chip)
|
||||
{
|
||||
int rc = 0;
|
||||
int vol_drop = 0;
|
||||
|
||||
struct qpnp_vadc_result results;
|
||||
|
||||
rc = qpnp_vadc_read(P_MUX1_1_1, &results);
|
||||
if (rc) {
|
||||
pr_err("Unable to read vbat rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
vol_drop = ((int)(results.physical)/chip->charging_det_resistor)
|
||||
* chip->battery_resistor / 1000;
|
||||
return vol_drop;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_enable_charging
|
||||
Description : Enable charging
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_enable_charging(struct mp2617_chip *chip)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if ((!chip->charging_enabled) && (true == chip->charging_allowed)
|
||||
&& (true == chip->battery_present)) {
|
||||
rc = gpio_direction_output(chip->charging_en_gpio, 1);
|
||||
|
||||
if (!rc) {
|
||||
chip->charging_enabled = true;
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
mp2617_enable_boost(chip, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(&chip->client->dev, "%s, rc = %d\n", __func__, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_disable_charging
|
||||
Description : Disable charging
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_disable_charging(struct mp2617_chip *chip)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (chip->charging_enabled) {
|
||||
rc = gpio_direction_output(chip->charging_en_gpio, 0);
|
||||
|
||||
if (!rc) {
|
||||
chip->charging_enabled = false;
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
mp2617_enable_boost(chip, true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(&chip->client->dev, "%s, rc = %d\n", __func__, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_get_property_chg_ok_level
|
||||
Description : Get the level of chg_ok gpio
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : Gpio level
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_get_property_chg_ok_level(struct mp2617_chip *chip)
|
||||
{
|
||||
int rc = 0;
|
||||
int result = 0;
|
||||
|
||||
rc = gpio_direction_input(chip->charging_ok_gpio);
|
||||
if (!rc) {
|
||||
result = gpio_get_value_cansleep(chip->charging_ok_gpio);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_set_input_current_limit
|
||||
Description : Set the limit of input current
|
||||
Input : chip: chip data
|
||||
current_limit_ua: the limit of input current
|
||||
Output : None
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_set_input_current_limit(struct mp2617_chip *chip,
|
||||
int current_limit_ua)
|
||||
{
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = ARRAY_SIZE(supported_input_current) - 1; i >= 0; i--) {
|
||||
if (current_limit_ua >= supported_input_current[i]) {
|
||||
current_limit_ua = supported_input_current[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (current_limit_ua) {
|
||||
case USB_INPUT_CURRENT_LIMIT_UA:
|
||||
gpio_direction_output(chip->charging_m0_gpio, 0);
|
||||
gpio_direction_output(chip->charging_m1_gpio, 0);
|
||||
break;
|
||||
|
||||
case CHARGER_INPUT_CURRENT_LIMIT_UA:
|
||||
gpio_direction_output(chip->charging_m0_gpio, 1);
|
||||
gpio_direction_output(chip->charging_m1_gpio, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&chip->client->dev, "%s: Unsupported current_limit_ua=%d uA\n",
|
||||
__func__, current_limit_ua);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
chip->input_current_limit_ua = current_limit_ua;
|
||||
|
||||
dev_dbg(&chip->client->dev, "%s: current_limit_ua=%d uA\n", __func__,
|
||||
current_limit_ua);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_set_property_battery_present
|
||||
Description : Set the present state of battery
|
||||
Input : chip: chip data
|
||||
batt_present_state: the present state of battery
|
||||
Output : None
|
||||
Return : 0: OK
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_set_property_battery_present(struct mp2617_chip *chip,
|
||||
bool batt_present_state)
|
||||
{
|
||||
chip->battery_present = batt_present_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_get_property_battery_present
|
||||
Description : Get the present state of battery
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : The present state of battery
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_get_property_battery_present(struct mp2617_chip *chip)
|
||||
{
|
||||
return chip->battery_present;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_set_property_battery_health
|
||||
Description : Set the health state of battery
|
||||
Input : chip: chip data
|
||||
health_state: the health state of battery
|
||||
Output : None
|
||||
Return : 0: OK
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_set_property_battery_health(struct mp2617_chip *chip,
|
||||
int health_state)
|
||||
{
|
||||
if ((health_state > POWER_SUPPLY_HEALTH_UNKNOWN) &&
|
||||
(health_state <= POWER_SUPPLY_HEALTH_DEAD_OVERCOLD))
|
||||
{
|
||||
chip->battery_health = health_state;
|
||||
|
||||
if (POWER_SUPPLY_HEALTH_GOOD == health_state)
|
||||
{
|
||||
chip->charging_allowed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->charging_allowed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->battery_health = POWER_SUPPLY_HEALTH_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_get_property_battery_health
|
||||
Description : Get the health state of battery
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : The health state of battery
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_get_property_battery_health(struct mp2617_chip *chip)
|
||||
{
|
||||
return chip->battery_health;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_get_property_battery_voltage
|
||||
Description : Get the voltage of battery
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : The voltage of battery
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_get_property_battery_voltage(struct mp2617_chip *chip)
|
||||
{
|
||||
int rc = 0;
|
||||
struct qpnp_vadc_result results;
|
||||
|
||||
rc = qpnp_vadc_read(P_MUX2_1_1, &results);
|
||||
if (rc) {
|
||||
pr_err("Unable to read vbat rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return ((int)(results.physical * chip->charging_vbat_div)/1000);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : em_batt_map_linear
|
||||
Description : Get the result form table by linear map
|
||||
Input : table: linear map table
|
||||
table_size: table size
|
||||
in_num: number input
|
||||
Output : out_num: result with linear map
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int em_batt_map_linear(const int (*table)[2], const u32 table_size,
|
||||
int in_num, int *out_num)
|
||||
{
|
||||
u32 i = 0;
|
||||
|
||||
if ((NULL == table) || (NULL == out_num)) {
|
||||
pr_err("Invalid input or output parameter\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (i < table_size) {
|
||||
if (table[i][0] < in_num) {
|
||||
break;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
*out_num = table[0][1];
|
||||
} else if (i == table_size) {
|
||||
*out_num = table[table_size-1][1];
|
||||
} else {
|
||||
/* result is between search_index and search_index-1, interpolate linearly */
|
||||
*out_num = (((table[i][1] - table[i-1][1]) * (in_num - table[i-1][0]))
|
||||
/ (table[i][0] - table[i-1][0])) + table[i-1][1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_get_property_battery_id_therm
|
||||
Description : Get the temperature of battery
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : The temperature of battery or error code
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int mp2617_get_property_battery_id_therm(struct mp2617_chip *chip)
|
||||
{
|
||||
int rc = 0;
|
||||
int temp_value = 0;
|
||||
struct qpnp_vadc_result results;
|
||||
|
||||
rc = qpnp_vadc_read(LR_MUX2_BAT_ID, &results);
|
||||
if (rc) {
|
||||
pr_err("Unable to read battery temperature, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
temp_value = ((int)results.physical) / 1000; /* convert to mV */
|
||||
|
||||
rc = em_batt_map_linear(adc_map_temp,
|
||||
sizeof(adc_map_temp)/sizeof(adc_map_temp[0]),
|
||||
temp_value, &temp_value);
|
||||
if(rc) {
|
||||
pr_err("Unable to get battery temperature, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return temp_value;
|
||||
}
|
||||
|
||||
static int mp2617_property_is_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_CHARGING_ENABLED:
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp2617_power_set_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
const union power_supply_propval *val)
|
||||
{
|
||||
struct mp2617_chip *chip = container_of(psy, struct mp2617_chip, psy);
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_CHARGING_ENABLED:
|
||||
if (val->intval) {
|
||||
mp2617_enable_charging(chip);
|
||||
} else {
|
||||
mp2617_disable_charging(chip);
|
||||
}
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
mp2617_set_input_current_limit(chip, val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
mp2617_set_property_battery_health(chip, val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
mp2617_set_property_battery_present(chip, (bool)val->intval);
|
||||
break;
|
||||
default:
|
||||
mutex_unlock(&chip->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
power_supply_changed(&chip->psy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp2617_power_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct mp2617_chip *chip = container_of(psy, struct mp2617_chip, psy);
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
val->intval = mp2617_get_property_battery_health(chip);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
val->intval = mp2617_get_property_battery_present(chip);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
val->intval = mp2617_get_property_battery_voltage(chip);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
val->intval = mp2617_get_property_battery_id_therm(chip);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHG_OK:
|
||||
val->intval = mp2617_get_property_chg_ok_level(chip);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGING_ENABLED:
|
||||
val->intval = chip->charging_enabled;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
val->intval = chip->input_current_limit_ua;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TECHNOLOGY:
|
||||
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_MODEL_NAME:
|
||||
val->strval = "MP2617";
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_MANUFACTURER:
|
||||
val->strval = "MPS";
|
||||
break;
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_DROP:
|
||||
val->intval = mp2617_get_property_voltage_drop(chip);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
mutex_unlock(&chip->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_external_power_changed
|
||||
Description : Set charging parameters because power supply device changes
|
||||
Input : psy: power supply psy
|
||||
Output : None
|
||||
Return : None
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static void mp2617_external_power_changed(struct power_supply *psy)
|
||||
{
|
||||
struct mp2617_chip *chip = container_of(psy, struct mp2617_chip, psy);
|
||||
union power_supply_propval prop = {0,};
|
||||
int scope = POWER_SUPPLY_SCOPE_DEVICE;
|
||||
int current_limit = 0;
|
||||
int online = 0;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
dev_dbg(&chip->client->dev, "%s: start\n", __func__);
|
||||
|
||||
rc = chip->usb_psy->get_property(chip->usb_psy,
|
||||
POWER_SUPPLY_PROP_ONLINE, &prop);
|
||||
if (rc) {
|
||||
dev_err(&chip->client->dev,
|
||||
"%s: could not read USB online property, rc=%d\n", __func__, rc);
|
||||
} else {
|
||||
online = prop.intval;
|
||||
}
|
||||
|
||||
rc = chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_SCOPE,
|
||||
&prop);
|
||||
if (rc) {
|
||||
dev_err(&chip->client->dev,
|
||||
"%s: could not read USB scope property, rc=%d\n", __func__, rc);
|
||||
} else {
|
||||
scope = prop.intval;
|
||||
}
|
||||
|
||||
rc = chip->usb_psy->get_property(chip->usb_psy,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
|
||||
if (rc) {
|
||||
dev_err(&chip->client->dev,
|
||||
"%s: could not read USB current max property, rc=%d\n", __func__, rc);
|
||||
} else {
|
||||
current_limit = prop.intval;
|
||||
}
|
||||
|
||||
dev_dbg(&chip->client->dev,
|
||||
"%s: online=%d, scope=%d, current_limit=%d, present=%d\n",
|
||||
__func__, online, scope, current_limit, chip->battery_present);
|
||||
|
||||
if (scope == POWER_SUPPLY_SCOPE_DEVICE) {
|
||||
if (online && chip->battery_present) {
|
||||
mp2617_set_input_current_limit(chip, current_limit);
|
||||
|
||||
if (current_limit != 0 &&
|
||||
POWER_SUPPLY_HEALTH_GOOD == chip->battery_health) {
|
||||
mp2617_enable_charging(chip);
|
||||
}
|
||||
} else {
|
||||
mp2617_disable_charging(chip);
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(&chip->client->dev, "%s: end\n", __func__);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
power_supply_changed(&chip->psy);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_apply_dt_configs
|
||||
Description : Set default config
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int __devinit mp2617_apply_dt_configs(struct mp2617_chip *chip)
|
||||
{
|
||||
struct device *dev = &chip->client->dev;
|
||||
struct device_node *node = chip->client->dev.of_node;
|
||||
int current_ma = 0;
|
||||
int value = 0;
|
||||
int rc = 0;
|
||||
|
||||
chip->input_current_limit_ua = DEFAULT_INPUT_CURRENT_LIMIT_UA;
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
chip->charging_det_resistor = DEFAULT_CHARGE_DET_RESISTOR;
|
||||
chip->battery_resistor = DEFAULT_BATTERY_RESISTOR;
|
||||
mp2617_enable_boost(chip, true);
|
||||
#endif
|
||||
chip->battery_health = POWER_SUPPLY_HEALTH_GOOD;
|
||||
chip->battery_present = true;
|
||||
chip->charging_allowed = true;
|
||||
|
||||
mp2617_disable_charging(chip);
|
||||
|
||||
/*
|
||||
* All device tree parameters are optional so it is ok if read calls
|
||||
* fail.
|
||||
*/
|
||||
rc = of_property_read_u32(node, "mps,chg-current-ma", ¤t_ma);
|
||||
if (rc == 0) {
|
||||
chip->input_current_limit_ua = current_ma * 1000;
|
||||
} else {
|
||||
dev_err(dev, "%s: Failed to get charge current node, rc=%d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(node, "mps,chg-vbat-div", &value);
|
||||
if (rc == 0) {
|
||||
chip->charging_vbat_div = value;
|
||||
} else {
|
||||
chip->charging_vbat_div = 1;
|
||||
|
||||
dev_err(dev, "%s: Failed to get battery voltage division, rc=%d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
rc = mp2617_set_input_current_limit(chip, chip->input_current_limit_ua);
|
||||
if (rc) {
|
||||
dev_err(dev, "%s: Failed to set charge current, rc=%d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
rc = of_property_read_u32(node, "mps,chg-det-resistor", &value);
|
||||
if (rc == 0) {
|
||||
chip->charging_det_resistor = value;
|
||||
} else {
|
||||
dev_err(dev, "%s: Failed to get detection resistor, rc=%d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(node, "mps,chg-batt-resistor", &value);
|
||||
if (rc == 0) {
|
||||
chip->battery_resistor = value;
|
||||
} else {
|
||||
dev_err(dev, "%s: Failed to get battery resistor, rc=%d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Function : mp2617_gpio_configs
|
||||
Description : Set gpio default config
|
||||
Input : chip: chip data
|
||||
Output : None
|
||||
Return : 0: OK, Others: Error
|
||||
Others : None
|
||||
*******************************************************************************/
|
||||
static int __devinit mp2617_gpio_configs(struct mp2617_chip *chip)
|
||||
{
|
||||
struct device_node *node = chip->client->dev.of_node;
|
||||
int rc = 0;
|
||||
|
||||
chip->charging_en_gpio = of_get_named_gpio(node, "mps,chg-en-gpio", 0);
|
||||
rc = gpio_request(chip->charging_en_gpio, "mps,chg-en-gpio");
|
||||
if (rc) {
|
||||
pr_err("request charge en gpio failed, rc=%d\n", rc);
|
||||
gpio_free(chip->charging_en_gpio);
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->charging_ok_gpio = of_get_named_gpio(node, "mps,chg-ok-gpio", 0);
|
||||
rc = gpio_request(chip->charging_ok_gpio, "mps,chg-ok-gpio");
|
||||
if (rc) {
|
||||
pr_err("request charge ok gpio failed, rc=%d\n",rc);
|
||||
gpio_free(chip->charging_ok_gpio);
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->charging_m0_gpio = of_get_named_gpio(node, "mps,chg-m0-gpio", 0);
|
||||
rc = gpio_request(chip->charging_m0_gpio, "mps,chg-m0-gpio");
|
||||
if (rc) {
|
||||
pr_err("request charge m0 gpio failed, rc=%d\n",
|
||||
rc);
|
||||
gpio_free(chip->charging_m0_gpio);
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->charging_m1_gpio = of_get_named_gpio(node, "mps,chg-m1-gpio", 0);
|
||||
rc = gpio_request(chip->charging_m1_gpio, "mps,chg-m1-gpio");
|
||||
if (rc) {
|
||||
pr_err("request charge m1 gpio failed, rc=%d\n",
|
||||
rc);
|
||||
gpio_free(chip->charging_m1_gpio);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
chip->boost_en_gpio = of_get_named_gpio(node, "mps,chg-boost-en-gpio", 0);
|
||||
rc = gpio_request(chip->boost_en_gpio, "mps,chg-boost-en-gpio");
|
||||
if (rc) {
|
||||
pr_err("request charge m1 gpio failed, rc=%d\n",
|
||||
rc);
|
||||
gpio_free(chip->boost_en_gpio);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __devinit mp2617_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mp2617_chip *chip;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int rc = 0;
|
||||
|
||||
if (!node) {
|
||||
dev_err(dev, "%s: device tree information missing\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip) {
|
||||
dev_err(dev, "%s: devm_kzalloc failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&chip->lock);
|
||||
chip->client = pdev;
|
||||
|
||||
chip->usb_psy = power_supply_get_by_name("usb");
|
||||
if (!chip->usb_psy) {
|
||||
dev_dbg(dev, "%s: USB supply not found; deferring charger probe\n",
|
||||
__func__);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
rc = mp2617_gpio_configs(chip);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mp2617_apply_dt_configs(chip);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->psy.name = "battery";
|
||||
chip->psy.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
chip->psy.properties = mp2617_power_properties;
|
||||
chip->psy.num_properties = ARRAY_SIZE(mp2617_power_properties);
|
||||
chip->psy.get_property = mp2617_power_get_property;
|
||||
chip->psy.set_property = mp2617_power_set_property;
|
||||
chip->psy.property_is_writeable = mp2617_property_is_writeable;
|
||||
chip->psy.external_power_changed = mp2617_external_power_changed;
|
||||
|
||||
rc = power_supply_register(dev, &chip->psy);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "%s: power_supply_register failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
mp2617_external_power_changed(&chip->psy);
|
||||
|
||||
dev_info(dev, "%s: MP2617 charger probed successfully\n", __func__);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __devexit mp2617_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mp2617_match[] = {
|
||||
{ .compatible = "mps,mp2617", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver mp2617_driver = {
|
||||
.driver = {
|
||||
.name = "mp2617",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mp2617_match,
|
||||
},
|
||||
.probe = mp2617_probe,
|
||||
.remove = __devexit_p(mp2617_remove),
|
||||
};
|
||||
|
||||
static int __init mp2617_init(void)
|
||||
{
|
||||
return platform_driver_register(&mp2617_driver);
|
||||
}
|
||||
module_init(mp2617_init);
|
||||
|
||||
static void __exit mp2617_exit(void)
|
||||
{
|
||||
return platform_driver_unregister(&mp2617_driver);
|
||||
}
|
||||
module_exit(mp2617_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MP2617 Charger");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("mp2617");
|
6
kernel/drivers/power/power_supply_sysfs.c
Executable file → Normal file
6
kernel/drivers/power/power_supply_sysfs.c
Executable file → Normal file
@@ -55,7 +55,7 @@ static ssize_t power_supply_show_property(struct device *dev,
|
||||
};
|
||||
static char *health_text[] = {
|
||||
"Unknown", "Good", "Overheat", "Dead", "Over voltage",
|
||||
"Unspecified failure", "Cold","Dead over cold",
|
||||
"Unspecified failure", "Cold",
|
||||
};
|
||||
static char *technology_text[] = {
|
||||
"Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd",
|
||||
@@ -177,10 +177,6 @@ static struct device_attribute power_supply_attrs[] = {
|
||||
POWER_SUPPLY_ATTR(scope),
|
||||
POWER_SUPPLY_ATTR(system_temp_level),
|
||||
POWER_SUPPLY_ATTR(resistance),
|
||||
POWER_SUPPLY_ATTR(chg_ok), /* [linyunfeng] Charge ok gpio level */
|
||||
#ifdef CONFIG_POWER_BANK_DETECT_SUPPORT
|
||||
POWER_SUPPLY_ATTR(voltage_drop),
|
||||
#endif
|
||||
/* Properties of type `const char *' */
|
||||
POWER_SUPPLY_ATTR(model_name),
|
||||
POWER_SUPPLY_ATTR(manufacturer),
|
||||
|
Reference in New Issue
Block a user