summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorRong Dian <b38775@freescale.com>2012-06-15 12:33:58 +0800
committerRong Dian <b38775@freescale.com>2012-06-18 20:45:07 +0800
commit18cc49c15de3fd99a334eef49ec8119e46115919 (patch)
tree808e6b0fa321fc6833afa34ea34a61d9d4fbea50 /drivers/power
parent45b2fd28854a4128c1a0031430522b534274ac9d (diff)
ENGR00213722:MX6 SABRESD battery:add voltage offset sysfs
interface and modify driver 1.add battery sample voltage offset sysfs interface. 2.add usb charger powersupply from max8903 UOK. 3.modify battery max coulomb data to 99% in charger full stage and modify battery max coulomb data to 100% in discharger stage,because hardware cannot support battery internal resistance and coulomb calculation.Battery voltage and coulomb may increase a bit in charger stage,so keep max coulomb data 99% in charger full stage. Signed-off-by: Rong Dian <b38775@freescale.com>
Diffstat (limited to 'drivers/power')
-rwxr-xr-xdrivers/power/sabresd_battery.c172
1 files changed, 130 insertions, 42 deletions
diff --git a/drivers/power/sabresd_battery.c b/drivers/power/sabresd_battery.c
index b302a177e086..21294fb8311a 100755
--- a/drivers/power/sabresd_battery.c
+++ b/drivers/power/sabresd_battery.c
@@ -38,6 +38,7 @@ struct max8903_data {
struct max8903_pdata *pdata;
struct device *dev;
struct power_supply psy;
+ struct power_supply usb;
bool fault;
bool usb_in;
bool ta_in;
@@ -53,7 +54,9 @@ struct max8903_data {
int real_capacity;
int percent;
int old_percent;
+ int usb_charger_online;
struct power_supply bat;
+ struct power_supply detect_usb;
struct mutex work_lock;
};
@@ -64,13 +67,14 @@ typedef struct {
static bool capacity_changed_flag;
static int cpu_type_flag;
+static int offset_discharger;
+static int offset_charger;
static battery_capacity chargingTable[] = {
- {4146, 100},
- {4133, 99},
- {4123, 98},
- {4115, 97},
- {4090, 96},
+ {4105, 99},
+ {4100, 98},
+ {4095, 97},
+ {4085, 96},
{4075, 95},
{4060, 94},
{4045, 93},
@@ -98,7 +102,7 @@ static battery_capacity chargingTable[] = {
{0, 0}
};
static battery_capacity dischargingTable[] = {
- {4110, 100},
+ {4050, 100},
{4020, 99},
{3950, 98},
{3920, 97},
@@ -169,24 +173,35 @@ extern u32 max11801_read_adc(void);
static void max8903_charger_update_status(struct max8903_data *data)
{
- if (data->usb_in || data->ta_in)
+ if (data->usb_in || data->ta_in) {
+ if (data->ta_in)
data->charger_online = 1;
- else
- data->charger_online = 0;
- if (data->charger_online == 0) {
+
+ if (data->usb_in)
+ data->usb_charger_online = 1;
+ } else {
+ data->charger_online = 0;
+ data->usb_charger_online = 0;
+ }
+ if (data->charger_online == 0 && data->usb_charger_online == 0) {
data->battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
} else {
- if (data->pdata->chg) {
if (gpio_get_value(data->pdata->chg) == 0) {
data->battery_status = POWER_SUPPLY_STATUS_CHARGING;
- } else if ((data->usb_in || data->ta_in) &&
+ } else if (data->ta_in &&
gpio_get_value(data->pdata->chg) == 1) {
- if (data->percent == 100)
+ if (data->percent >= 99)
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+ else if (data->usb_in &&
+ gpio_get_value(data->pdata->chg) == 1) {
+ if (data->percent >= 99)
data->battery_status = POWER_SUPPLY_STATUS_FULL;
else
data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
}
- }
}
pr_debug("chg: %d \n", gpio_get_value(data->pdata->chg));
}
@@ -207,19 +222,19 @@ u32 calibration_voltage(struct max8903_data *data)
int i;
for (i = 0; i < ADC_SAMPLE_COUNT; i++) {
if (cpu_type_flag == 1) {
- if (data->charger_online == 0) {
+ if (data->charger_online == 0 && data->usb_charger_online == 0) {
/* ADC offset when battery is discharger*/
- volt[i] = max11801_read_adc()-1694;
+ volt[i] = max11801_read_adc()-offset_discharger;
} else {
- volt[i] = max11801_read_adc()-1900;
+ volt[i] = max11801_read_adc()-offset_charger;
}
}
if (cpu_type_flag == 0) {
- if (data->charger_online == 0) {
+ if (data->charger_online == 0 && data->usb_charger_online == 0) {
/* ADC offset when battery is discharger*/
- volt[i] = max11801_read_adc()-1464;
+ volt[i] = max11801_read_adc()-offset_discharger;
} else {
- volt[i] = max11801_read_adc()-1485;
+ volt[i] = max11801_read_adc()-offset_charger;
}
}
}
@@ -241,7 +256,7 @@ static void max8903_battery_update_status(struct max8903_data *data)
data->old_percent = data->percent;
capacity_changed_flag = true;
}
- if ((capacity_changed_flag == true) && (data->charger_online)) {
+ if ((capacity_changed_flag == true)) {
counter++;
if (counter > 2) {
counter = 0;
@@ -263,19 +278,22 @@ static int max8903_battery_get_property(struct power_supply *bat,
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
- if (di->pdata->chg) {
- if ((di->usb_in || di->ta_in) && gpio_get_value(di->pdata->chg) == 0) {
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- } else if ((di->usb_in || di->ta_in) && gpio_get_value(di->pdata->chg) == 1) {
- if (di->percent == 100)
- di->battery_status = POWER_SUPPLY_STATUS_FULL;
- else
- di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
- }
- else {
- di->battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
- }
- }
+ if (gpio_get_value(di->pdata->chg) == 0) {
+ di->battery_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if (di->ta_in &&
+ gpio_get_value(di->pdata->chg) == 1) {
+ if (di->percent >= 99)
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+ else if (di->usb_in &&
+ gpio_get_value(di->pdata->chg) == 1) {
+ if (di->percent >= 99)
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
val->intval = di->battery_status;
return 0;
default:
@@ -327,7 +345,7 @@ static int max8903_get_property(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = 0;
- if (data->usb_in || data->ta_in)
+ if (data->ta_in)
val->intval = 1;
data->charger_online = val->intval;
break;
@@ -336,7 +354,25 @@ static int max8903_get_property(struct power_supply *psy,
}
return 0;
}
+static int max8903_get_usb_property(struct power_supply *usb,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8903_data *data = container_of(usb,
+ struct max8903_data, usb);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = 0;
+ if (data->usb_in)
+ val->intval = 1;
+ data->usb_charger_online = val->intval;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
static irqreturn_t max8903_dcin(int irq, void *_data)
{
struct max8903_data *data = _data;
@@ -357,15 +393,12 @@ static irqreturn_t max8903_dcin(int irq, void *_data)
power_supply_changed(&data->bat);
return IRQ_HANDLED;
}
-
static irqreturn_t max8903_usbin(int irq, void *_data)
{
struct max8903_data *data = _data;
struct max8903_pdata *pdata = data->pdata;
bool usb_in;
-
usb_in = gpio_get_value(pdata->uok) ? false : true;
-
if (usb_in == data->usb_in)
return IRQ_HANDLED;
@@ -374,8 +407,8 @@ static irqreturn_t max8903_usbin(int irq, void *_data)
max8903_battery_update_status(data);
pr_info("USB Charger %s.\n", usb_in ?
"Connected" : "Disconnected");
- power_supply_changed(&data->psy);
power_supply_changed(&data->bat);
+ power_supply_changed(&data->usb);
return IRQ_HANDLED;
}
@@ -400,6 +433,7 @@ static irqreturn_t max8903_fault(int irq, void *_data)
max8903_battery_update_status(data);
power_supply_changed(&data->psy);
power_supply_changed(&data->bat);
+ power_supply_changed(&data->usb);
return IRQ_HANDLED;
}
@@ -419,6 +453,7 @@ static irqreturn_t max8903_chg(int irq, void *_data)
max8903_battery_update_status(data);
power_supply_changed(&data->psy);
power_supply_changed(&data->bat);
+ power_supply_changed(&data->usb);
return IRQ_HANDLED;
}
@@ -430,7 +465,6 @@ static void max8903_battery_work(struct work_struct *work)
max8903_charger_update_status(data);
max8903_battery_update_status(data);
-
pr_debug("battery voltage: %4d mV\n" , data->voltage_uV);
pr_debug("charger online status: %d\n" , data->charger_online);
pr_debug("battery status : %d\n" , data->battery_status);
@@ -439,6 +473,40 @@ static void max8903_battery_work(struct work_struct *work)
/* reschedule for the next time */
schedule_delayed_work(&data->work, data->interval);
}
+
+static ssize_t max8903_voltage_offset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "read offset_discharger:%04d,offset_charger:%04d\n",
+ offset_discharger, offset_charger);
+}
+
+static ssize_t max8903_voltage_offset_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ char *p;
+
+ offset_discharger = simple_strtoul(buf, NULL, 10);
+ p = NULL;
+ p = memchr(buf, ' ', count);
+ p += 1;
+ offset_charger = simple_strtoul(p, NULL, 10);
+
+ pr_info("read offset_discharger:%04d,offset_charger:%04d\n",
+ offset_discharger, offset_charger);
+ return count;
+}
+
+static struct device_attribute max8903_dev_attr = {
+ .attr = {
+ .name = "max8903_ctl",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .show = max8903_voltage_offset_show,
+ .store = max8903_voltage_offset_store,
+};
+
static __devinit int max8903_probe(struct platform_device *pdev)
{
struct max8903_data *data;
@@ -461,12 +529,10 @@ static __devinit int max8903_probe(struct platform_device *pdev)
}
data->pdata = pdata;
data->dev = dev;
-
platform_set_drvdata(pdev, data);
capacity_changed_flag = false;
data->usb_in = 0;
data->ta_in = 0;
-
if (pdata->dc_valid == false && pdata->usb_valid == false) {
dev_err(dev, "No valid power sources.\n");
printk(KERN_INFO "No valid power sources.\n");
@@ -566,6 +632,16 @@ static __devinit int max8903_probe(struct platform_device *pdev)
dev_err(dev, "failed: power supply register.\n");
goto err_psy;
}
+ data->usb.name = "max8903-usb";
+ data->usb.type = POWER_SUPPLY_TYPE_USB;
+ data->usb.get_property = max8903_get_usb_property;
+ data->usb.properties = max8903_charger_props;
+ data->usb.num_properties = ARRAY_SIZE(max8903_charger_props);
+ ret = power_supply_register(dev, &data->usb);
+ if (ret) {
+ dev_err(dev, "failed: power supply register.\n");
+ goto err_psy;
+ }
data->bat.name = "max8903-charger";
data->bat.type = POWER_SUPPLY_TYPE_BATTERY;
data->bat.properties = max8903_battery_props;
@@ -626,6 +702,18 @@ static __devinit int max8903_probe(struct platform_device *pdev)
goto err_chg_irq;
}
}
+
+ ret = device_create_file(&pdev->dev, &max8903_dev_attr);
+ if (ret)
+ dev_err(&pdev->dev, "create device file failed!\n");
+ if (cpu_type_flag == 1) {
+ offset_discharger = 1694;
+ offset_charger = 1900;
+ }
+ if (cpu_type_flag == 0) {
+ offset_discharger = 1464;
+ offset_charger = 1485;
+ }
return 0;
err_psy:
power_supply_unregister(&data->psy);