[Balloon-svn] r1835 - balloon/branches/menuconfig2/package/k…

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: subversion@balloonboard.org
Date:  
To: balloon-svn
Subject: [Balloon-svn] r1835 - balloon/branches/menuconfig2/package/kernel/patches/2.6.39.4
Author: nick
Date: 2012-01-30 16:35:35 +0000 (Mon, 30 Jan 2012)
New Revision: 1835

Modified:
balloon/branches/menuconfig2/package/kernel/patches/2.6.39.4/battery-tt.patch
Log:
update battery to include vbus sysfs entry. Also to poll voltage on read/interrupt not periodically

Modified: balloon/branches/menuconfig2/package/kernel/patches/2.6.39.4/battery-tt.patch
===================================================================
--- balloon/branches/menuconfig2/package/kernel/patches/2.6.39.4/battery-tt.patch    2012-01-30 16:34:34 UTC (rev 1834)
+++ balloon/branches/menuconfig2/package/kernel/patches/2.6.39.4/battery-tt.patch    2012-01-30 16:35:35 UTC (rev 1835)
@@ -1,24 +1,29 @@
 Index: linux-2.6.39.4/drivers/power/Kconfig
 ===================================================================
---- linux-2.6.39.4.orig/drivers/power/Kconfig    2012-01-06 13:48:02.000000000 +0000
-+++ linux-2.6.39.4/drivers/power/Kconfig    2012-01-06 13:48:08.000000000 +0000
-@@ -219,4 +219,12 @@
+--- linux-2.6.39.4.orig/drivers/power/Kconfig    2012-01-30 10:34:18.000000000 +0000
++++ linux-2.6.39.4/drivers/power/Kconfig    2012-01-30 10:35:54.000000000 +0000
+@@ -219,4 +219,17 @@
        This driver can be build as a module. If so, the module will be
        called gpio-charger.


 +config BATTERY_TT
 +    tristate "Battery driver for Bubble TT"
-+#    depends on INTEL_SCU_IPC && SPI
-+    depends on MACH_BALLOON3_BUBBLE
++    depends on MACH_BALLOON3_BUBBLE && SPI_TT
 +    help
 +      Say Y here to enable the battery driver on Bubble TT
 +      platforms.
 +
++config BATTERY_TT_LED
++    bool "Use leds to indicate battery state"
++    depends on BATTERY_TT
++    help
++      Say Y here to enable the low battery led warning.
++
  endif # POWER_SUPPLY
 Index: linux-2.6.39.4/drivers/power/Makefile
 ===================================================================
---- linux-2.6.39.4.orig/drivers/power/Makefile    2012-01-06 13:48:02.000000000 +0000
-+++ linux-2.6.39.4/drivers/power/Makefile    2012-01-06 13:48:08.000000000 +0000
+--- linux-2.6.39.4.orig/drivers/power/Makefile    2012-01-30 10:34:18.000000000 +0000
++++ linux-2.6.39.4/drivers/power/Makefile    2012-01-30 10:35:54.000000000 +0000
 @@ -34,3 +34,4 @@
  obj-$(CONFIG_CHARGER_ISP1704)    += isp1704_charger.o
  obj-$(CONFIG_CHARGER_TWL4030)    += twl4030_charger.o
@@ -27,8 +32,8 @@
 Index: linux-2.6.39.4/drivers/power/tt_battery.c
 ===================================================================
 --- /dev/null    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.39.4/drivers/power/tt_battery.c    2012-01-06 15:17:48.000000000 +0000
-@@ -0,0 +1,322 @@
++++ linux-2.6.39.4/drivers/power/tt_battery.c    2012-01-30 16:08:59.000000000 +0000
+@@ -0,0 +1,398 @@
 +/*
 + * Battery and Power Management code for the Bubble TT device
 + * Copyright (c) 2011 Nick Bane
@@ -56,11 +61,17 @@
 +#include <asm/mach-types.h>
 +#include <mach/balloon3.h>
 +
++//#define BATTERY_POLL
++//#define BATTERY_WARN
++
++#ifdef BATTERY_POLL
++static unsigned long batt_delay;
++#endif
++
 +static struct delayed_work bat_work;
 +static DEFINE_MUTEX(bat_lock);
-+static unsigned long batt_delay;
-+
 +struct tt_bat {
++    int vbus_status;
 +    int status;
 +    int charge_type;
 +    struct power_supply psy;
@@ -77,10 +88,33 @@
 +    int bat_min;
 +    int bat_scale;
 +
++#ifdef BATTERY_WARN
++    int bat_warn;
++    int bat_warn_counter;
++#endif
++
 +};
 +
 +static struct tt_bat tt_bat;
 +
++static ssize_t
++show_vbus(struct device *dev, struct device_attribute *attr, char *buf)
++{
++    return sprintf(buf, tt_bat.vbus_status ? "ok\n" : "n/c\n");
++}
++
++static DEVICE_ATTR(vbus, S_IRUGO, show_vbus, NULL);
++
++static struct attribute *tt_bat_sysfs_entries[] = {
++    &dev_attr_vbus.attr,
++    NULL,
++};
++
++static struct attribute_group tt_bat_attr_group = {
++    .name    = NULL,            /* put in device directory */
++    .attrs    = tt_bat_sysfs_entries,
++};
++
 +static int spiReadReg16(struct spi_device *spi, u8 *result)
 +{
 +    int res = 0;
@@ -103,21 +137,66 @@
 +{
 +    unsigned long value = 0;
 +    u8 result[2]={0,0};
-+    
-+    mutex_lock(&bat_lock);
++
++//    mutex_lock(&bat_lock);
 +    value = spiReadReg16(bat->spi, result);
-+    mutex_unlock(&bat_lock);
++//    mutex_unlock(&bat_lock);
 +
 +    // we have to shuffle the bits around due to endianness issues
 +    // and the fact that the ADC only gives us 10 bits
-+    value=(result[0]<<5)+(result[1]>>3);
-+    // and mask off the bits which the ADC doesn't give us
-+//    value = value * 1000000 / bat->adc_bat_divider;
++    value = (result[0]<<5) + (result[1]>>3);
 +
-+//    pr_info("%s: battery level %lu (0x%lx) - scaled value %lu\n", __func__, value, value, value * bat->bat_scale);
 +    return value;
 +}
 +
++static void tt_bat_update(struct tt_bat *bat)
++{
++    int old_status;
++    int old_charge_type;
++    struct power_supply *psy = &bat->psy;
++
++    u8 bat_status = samosa_read8(SAMOSA_ADDR_USB_CHG_REG_STATUS);
++    int vbus_ok = bat_status & (1 << USB_VBUS_OK_BIT);
++    int charger_present = bat_status & (1 << USB_CHARGER_PRESENT_BIT);
++    int charge_fast = bat_status & (1 << USB_CHARGE_FAST_BIT);
++    int notify_changed = 0;
++
++    u16 bat_val;
++//    mutex_lock(&bat->work_lock);
++    bat_val = tt_read_bat(bat);
++
++    // see if we have changed in status or charging type
++    old_status = bat->status;
++    old_charge_type = bat->charge_type;
++
++    bat->status = charger_present ? POWER_SUPPLY_STATUS_CHARGING : POWER_SUPPLY_STATUS_DISCHARGING;
++    bat->charge_type = charger_present ? (charge_fast ? POWER_SUPPLY_CHARGE_TYPE_FAST : POWER_SUPPLY_CHARGE_TYPE_TRICKLE) : POWER_SUPPLY_CHARGE_TYPE_NONE;
++
++    notify_changed = (vbus_ok != bat->vbus_status) || (old_status != bat->status) || (old_charge_type != bat->charge_type);
++
++    bat->vbus_status = vbus_ok;
++
++#ifdef BATTERY_WARN
++    // see if we have crossed a bat_warn threshold for long enough to believe it
++    if ((bat_val * bat->bat_scale) < bat->bat_warn) {
++        bat->bat_warn_counter++;
++        // if below bat_warn for 5 secs, do something
++        if (bat->bat_warn_counter == 5) {
++            pr_info("%s: battery level crossed below warn threshold 5 times in a row\n", __func__);
++            notify_changed = 1;
++        }
++    }
++    else {
++        if (bat->bat_warn_counter)
++            bat->bat_warn_counter--;
++    }
++#endif
++    // report if power supply has changed
++    if (notify_changed)
++        power_supply_changed(psy);
++//    mutex_unlock(&bat->work_lock);
++}
++
 +static int tt_bat_get_property(struct power_supply *psy,
 +                enum power_supply_property psp,
 +                union power_supply_propval *val)
@@ -125,6 +204,10 @@
 +    int ret = 0;
 +    struct tt_bat *bat = container_of(psy, struct tt_bat, psy);
 +
++#ifndef BATTERY_POLL
++    tt_bat_update(bat);
++#endif
++
 +    switch (psp) {
 +    case POWER_SUPPLY_PROP_STATUS:
 +        val->intval = bat->status;
@@ -153,6 +236,14 @@
 +    case POWER_SUPPLY_PROP_PRESENT:
 +        val->intval = 1;
 +        break;
++    case POWER_SUPPLY_PROP_MODEL_NAME:
++        val->strval = "Swift";
++        break;
++    case POWER_SUPPLY_PROP_MANUFACTURER:
++        val->strval = "Toby Churchill Ltd";
++        break;
++//    case POWER_SUPPLY_PROP_SERIAL_NUMBER:
++//        break;
 +    default:
 +        ret = -EINVAL;
 +        break;
@@ -162,53 +253,25 @@
 +
 +static void tt_bat_external_power_changed(struct power_supply *psy)
 +{
-+    schedule_delayed_work(&bat_work, batt_delay);
++    schedule_delayed_work(&bat_work, 1);
 +}
 +
 +static irqreturn_t tt_bat_isr(int irq, void *data)
 +{
 +    pr_info("%s: vbus changed\n", __func__);
-+    // update in 1/2 sec after volts settled
-+    schedule_delayed_work(&bat_work, msecs_to_jiffies(500));
++    // update in 1/4 sec after volts settled
++    schedule_delayed_work(&bat_work, msecs_to_jiffies(250));
 +    return IRQ_HANDLED;
 +}
 +
-+static void tt_bat_update(struct tt_bat *bat)
-+{
-+    int old_status;
-+    int old_charge_type;
-+    struct power_supply *psy = &bat->psy;
-+
-+    u8 bat_status = samosa_read8(SAMOSA_ADDR_USB_CHG_REG_STATUS);
-+    int vbus_ok = bat_status & (1 << USB_VBUS_OK_BIT);
-+    int charger_present = bat_status & (1 << USB_CHARGER_PRESENT_BIT);
-+    int charge_fast = bat_status & (1 << USB_CHARGE_FAST_BIT);
-+
-+    u16 bat_val;
-+//    mutex_lock(&bat->work_lock);
-+    bat_val = tt_read_bat(bat);
-+
-+//pr_info("%s: status vbus %s. Charger %s. Fast charging %s\n", __func__, vbus_ok ? "ok":"absent", charger_present ? "present":"absent", charge_fast ? "on":"off");
-+
-+    old_status = bat->status;
-+    old_charge_type = bat->charge_type;
-+
-+    bat->status = charger_present ? POWER_SUPPLY_STATUS_CHARGING : POWER_SUPPLY_STATUS_DISCHARGING;
-+    bat->charge_type = charger_present ? (charge_fast ? POWER_SUPPLY_CHARGE_TYPE_FAST : POWER_SUPPLY_CHARGE_TYPE_TRICKLE) : POWER_SUPPLY_CHARGE_TYPE_NONE;
-+
-+    if ((old_status != bat->status) || (old_charge_type != bat->charge_type))
-+        power_supply_changed(psy);
-+
-+//    mutex_unlock(&bat->work_lock);
-+}
-+
 +static void tt_bat_work(struct work_struct *work)
 +{
 +    tt_bat_update(&tt_bat);
++#ifdef BATTERY_POLL
 +    schedule_delayed_work(&bat_work, batt_delay);
++#endif
 +}
 +
-+
 +static enum power_supply_property tt_bat_main_props[] = {
 +    POWER_SUPPLY_PROP_STATUS,
 +    POWER_SUPPLY_PROP_CHARGE_TYPE,
@@ -217,13 +280,18 @@
 +    POWER_SUPPLY_PROP_VOLTAGE_MAX,
 +    POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 +    POWER_SUPPLY_PROP_PRESENT,
++    POWER_SUPPLY_PROP_MODEL_NAME,
++    POWER_SUPPLY_PROP_MANUFACTURER,
++//    POWER_SUPPLY_PROP_SERIAL_NUMBER,
 +};
 +
 +static struct tt_bat tt_bat = {
++    .vbus_status = -1,
 +    .status = POWER_SUPPLY_STATUS_DISCHARGING,
 +    .full_chrg = -1,
 +    .psy = {
-+        .name        = "tt-battery",
++        // a standard name for laptop batteries
++        .name        = "BAT0",
 +        .type        = POWER_SUPPLY_TYPE_BATTERY,
 +        .properties    = tt_bat_main_props,
 +        .num_properties    = ARRAY_SIZE(tt_bat_main_props),
@@ -237,7 +305,10 @@
 +    .bat_max = 5800000,
 +    .bat_min = 4400000,
 +    .bat_scale = 5000000 / 744,
-+
++#ifdef BATTERY_WARN
++    .bat_warn = 4600000,
++    .bat_warn_counter = 0,
++#endif
 +};
 +
 +#ifdef CONFIG_PM
@@ -249,7 +320,7 @@
 +
 +static int tt_bat_resume(struct device *dev)
 +{
-+    schedule_delayed_work(&bat_work, batt_delay);
++    schedule_delayed_work(&bat_work, msecs_to_jiffies(250));
 +    return 0;
 +}
 +#else
@@ -265,9 +336,12 @@
 +        return -ENODEV;
 +
 +    INIT_DELAYED_WORK(&bat_work, tt_bat_work);
-+    // check battery state every 2 secs
-+    batt_delay = msecs_to_jiffies(2000);
 +
++#ifdef BATTERY_POLL
++    // check battery state every sec
++    batt_delay = msecs_to_jiffies(1000);
++#endif
++
 +    dev->bits_per_word = 8;
 +    ret = spi_setup(dev);
 +    if (ret)
@@ -275,7 +349,7 @@
 +
 +    tt_bat.spi = dev;
 +    tt_bat.irq = dev->irq;
-+    
++
 +    ret = power_supply_register(&dev->dev, &tt_bat.psy);
 +    if (ret)
 +        goto err_psy_reg_main;
@@ -291,8 +365,13 @@
 +    if (ret)
 +        goto err_req_main;
 +
-+    schedule_delayed_work(&bat_work, batt_delay);
++//    ret = sysfs_create_group(&dev->dev.kobj, &tt_bat_attr_group);
++    ret = sysfs_create_group(&tt_bat.psy.dev->kobj, &tt_bat_attr_group);
++    if (ret)
++        dev_err(&dev->dev, "failed to create sysfs entries\n");
 +
++    schedule_delayed_work(&bat_work, msecs_to_jiffies(250));
++
 +    pr_info("%s: added tt-battery support\n", __func__);
 +    return 0;
 +
@@ -310,6 +389,8 @@
 +static int __devexit tt_bat_remove(struct spi_device *dev)
 +{
 +
++    sysfs_remove_group(&tt_bat.psy.dev->kobj, &tt_bat_attr_group);
++
 +    power_supply_unregister(&tt_bat.psy);
 +
 +    cancel_delayed_work(&bat_work);