aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.24/1324-gta01-battery-driver.patch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1324-gta01-battery-driver.patch.patch')
-rw-r--r--target/linux/s3c24xx/patches-2.6.24/1324-gta01-battery-driver.patch.patch326
1 files changed, 326 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1324-gta01-battery-driver.patch.patch b/target/linux/s3c24xx/patches-2.6.24/1324-gta01-battery-driver.patch.patch
new file mode 100644
index 0000000000..c98373c8a4
--- /dev/null
+++ b/target/linux/s3c24xx/patches-2.6.24/1324-gta01-battery-driver.patch.patch
@@ -0,0 +1,326 @@
+From 8aefbe43a7864e611dca9821daec3e10009e7171 Mon Sep 17 00:00:00 2001
+From: Mike Westerhof <mwester@dls.net>
+Date: Thu, 13 Nov 2008 20:50:55 +0000
+Subject: [PATCH] gta01-battery-driver.patch
+
+Adds a simple pass-through battery driver module for the GTA01.
+This will simplify user-space by providing the same sysfs API
+on both GTA01 and GTA02, and is a first step towards eliminating
+the need for APM emulation.
+
+Signed-off-by: Mike Westerhof <mwester@dls.net>
+---
+ arch/arm/configs/gta02-moredrivers-defconfig | 1 +
+ defconfig-gta01 | 1 +
+ defconfig-gta02 | 1 +
+ drivers/i2c/chips/pcf50606.c | 96 +++++++++++++++++++++++++
+ drivers/power/Kconfig | 6 ++
+ drivers/power/Makefile | 1 +
+ drivers/power/gta01_battery.c | 97 ++++++++++++++++++++++++++
+ 7 files changed, 203 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/power/gta01_battery.c
+
+diff --git a/arch/arm/configs/gta02-moredrivers-defconfig b/arch/arm/configs/gta02-moredrivers-defconfig
+index 113eaec..5e1547e 100644
+--- a/arch/arm/configs/gta02-moredrivers-defconfig
++++ b/arch/arm/configs/gta02-moredrivers-defconfig
+@@ -1060,6 +1060,7 @@ CONFIG_POWER_SUPPLY_DEBUG=y
+ CONFIG_PDA_POWER=y
+ CONFIG_APM_POWER=y
+ # CONFIG_BATTERY_DS2760 is not set
++# CONFIG_BATTERY_GTA01 is not set
+ CONFIG_BATTERY_BQ27000_HDQ=y
+ CONFIG_GTA02_HDQ=y
+ CONFIG_HWMON=y
+diff --git a/defconfig-gta01 b/defconfig-gta01
+index cecb57f..e2e4330 100644
+--- a/defconfig-gta01
++++ b/defconfig-gta01
+@@ -1021,6 +1021,7 @@ CONFIG_POWER_SUPPLY=y
+ # CONFIG_PDA_POWER is not set
+ # CONFIG_APM_POWER is not set
+ # CONFIG_BATTERY_DS2760 is not set
++CONFIG_BATTERY_GTA01=y
+ CONFIG_BATTERY_BQ27000_HDQ=y
+ CONFIG_GTA02_HDQ=y
+ # CONFIG_HWMON is not set
+diff --git a/defconfig-gta02 b/defconfig-gta02
+index 619f7f2..2a6e398 100644
+--- a/defconfig-gta02
++++ b/defconfig-gta02
+@@ -1021,6 +1021,7 @@ CONFIG_POWER_SUPPLY=y
+ # CONFIG_PDA_POWER is not set
+ CONFIG_APM_POWER=y
+ # CONFIG_BATTERY_DS2760 is not set
++# CONFIG_BATTERY_GTA01 is not set
+ CONFIG_BATTERY_BQ27000_HDQ=y
+ CONFIG_GTA02_HDQ=y
+ # CONFIG_HWMON is not set
+diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
+index 706ce6d..f585013 100644
+--- a/drivers/i2c/chips/pcf50606.c
++++ b/drivers/i2c/chips/pcf50606.c
+@@ -50,6 +50,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/pcf50606.h>
+ #include <linux/apm-emulation.h>
++#include <linux/power_supply.h>
+
+ #include <asm/mach-types.h>
+ #include <asm/arch/gta01.h>
+@@ -141,6 +142,12 @@ struct pcf50606_data {
+
+ static struct i2c_driver pcf50606_driver;
+
++/* This global is set by the pcf50606 driver to the correct callback
++ * for the gta01 battery driver. */
++int (*pmu_bat_get_property)(struct power_supply *, enum power_supply_property,
++ union power_supply_propval *);
++EXPORT_SYMBOL(pmu_bat_get_property);
++
+ /* This is an ugly construct on how to access the (currently single/global)
+ * pcf50606 handle from other code in the kernel. I didn't really come up with
+ * a more decent method of dynamically resolving this */
+@@ -1270,6 +1277,92 @@ static void pcf50606_get_power_status(struct apm_power_info *info)
+ }
+
+ /***********************************************************************
++ * Battery driver interface
++ ***********************************************************************/
++static int pcf50606_bat_get_property(struct power_supply *psy,
++ enum power_supply_property psp,
++ union power_supply_propval *val)
++{
++ u_int16_t adc, adc_adcin1;
++ u_int8_t mbcc1, chgmod;
++ struct pcf50606_data *pcf = pcf50606_global;
++ int ret = 0;
++
++ switch (psp) {
++
++ case POWER_SUPPLY_PROP_STATUS:
++ if (!(reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON)) {
++ /* No charger, clearly we're discharging then */
++ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
++ } else {
++
++ /* We have a charger present, get charge mode */
++ mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1);
++ chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK);
++ switch (chgmod) {
++
++ /* TODO: How to determine POWER_SUPPLY_STATUS_FULL? */
++
++ case PCF50606_MBCC1_CHGMOD_QUAL:
++ case PCF50606_MBCC1_CHGMOD_PRE:
++ case PCF50606_MBCC1_CHGMOD_IDLE:
++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
++ break;
++
++ case PCF50606_MBCC1_CHGMOD_TRICKLE:
++ case PCF50606_MBCC1_CHGMOD_FAST_CCCV:
++ case PCF50606_MBCC1_CHGMOD_FAST_NOCC:
++ case PCF50606_MBCC1_CHGMOD_FAST_NOCV:
++ case PCF50606_MBCC1_CHGMOD_FAST_SW:
++ val->intval = POWER_SUPPLY_STATUS_CHARGING;
++ break;
++
++ default:
++ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
++ break;
++
++ }
++ }
++
++ case POWER_SUPPLY_PROP_PRESENT:
++ val->intval = 1; /* Must be, or the magic smoke comes out */
++ break;
++
++ case POWER_SUPPLY_PROP_ONLINE:
++ val->intval = !!(reg_read(pcf, PCF50606_REG_OOCS) &
++ PCF50606_OOCS_EXTON);
++ break;
++
++ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
++ adc = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_RES, NULL);
++ /* (adc * 6000000) / 1024 == (adc * 46875) / 8 */
++ val->intval = (adc * 46875) / 8;
++ break;
++
++ case POWER_SUPPLY_PROP_CURRENT_NOW:
++ adc = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_ADCIN1,
++ &adc_adcin1);
++ val->intval = adc_to_chg_milliamps(pcf, adc_adcin1, adc) * 1000;
++ break;
++
++ case POWER_SUPPLY_PROP_TEMP:
++ adc = adc_read(pcf, PCF50606_ADCMUX_BATTEMP, NULL);
++ val->intval = rntc_to_temp(adc_to_rntc(pcf, adc)) * 10;
++ break;
++
++ case POWER_SUPPLY_PROP_CAPACITY:
++ val->intval = battvolt_scale(pcf50606_battvolt(pcf));
++ break;
++
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++/***********************************************************************
+ * RTC
+ ***********************************************************************/
+
+@@ -1900,6 +1993,7 @@ static int pcf50606_detect(struct i2c_adapter *adapter, int address, int kind)
+ }
+
+ apm_get_power_status = pcf50606_get_power_status;
++ pmu_bat_get_property = pcf50606_bat_get_property;
+
+ #ifdef CONFIG_MACH_NEO1973_GTA01
+ if (machine_is_neo1973_gta01()) {
+@@ -1962,6 +2056,8 @@ static int pcf50606_detach_client(struct i2c_client *client)
+ struct pcf50606_data *pcf = i2c_get_clientdata(client);
+
+ apm_get_power_status = NULL;
++ pmu_bat_get_property = NULL;
++
+ input_unregister_device(pcf->input_dev);
+
+ if (pcf->pdata->used_features & PCF50606_FEAT_PWM_BL)
+diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
+index 8c50ecb..470e08c 100644
+--- a/drivers/power/Kconfig
++++ b/drivers/power/Kconfig
+@@ -62,5 +62,11 @@ config GTA02_HDQ
+ on the Neo Freerunner. You probably want to select
+ at least BATTERY_BQ27000_HDQ as well
+
++config BATTERY_GTA01
++ tristate "Neo GTA01 battery"
++ depends on MACH_NEO1973_GTA01
++ help
++ Say Y to enable support for the battery on the Neo GTA01
++
+ endif # POWER_SUPPLY
+
+diff --git a/drivers/power/Makefile b/drivers/power/Makefile
+index d7e87ad..2013e89 100644
+--- a/drivers/power/Makefile
++++ b/drivers/power/Makefile
+@@ -21,5 +21,6 @@ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
+ obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
+ obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
+ obj-$(CONFIG_BATTERY_BQ27000_HDQ) += bq27000_battery.o
++obj-$(CONFIG_BATTERY_GTA01) += gta01_battery.o
+
+ obj-$(CONFIG_GTA02_HDQ) += gta02_hdq.o
+diff --git a/drivers/power/gta01_battery.c b/drivers/power/gta01_battery.c
+new file mode 100644
+index 0000000..5acb45c
+--- /dev/null
++++ b/drivers/power/gta01_battery.c
+@@ -0,0 +1,97 @@
++/*
++ * Battery driver for the Openmoko GTA01 device, using the pcf50606 chip.
++ *
++ * This is nothing more than a write-thru interface to the real logic,
++ * which is part of the pcf50606.c multifunction chip driver.
++ * Copyright © 2008 Mike Westerhof <mwester@dls.net>
++ *
++ *
++ * Portions liberally borrowed from olpc_battery.c, copyright below:
++ * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/platform_device.h>
++#include <linux/power_supply.h>
++#include <linux/jiffies.h>
++#include <linux/sched.h>
++
++/*********************************************************************
++ * This global is set by the pcf50606 driver to the correct callback
++ *********************************************************************/
++
++extern int (*pmu_bat_get_property)(struct power_supply *,
++ enum power_supply_property,
++ union power_supply_propval *);
++
++
++/*********************************************************************
++ * Battery properties
++ *********************************************************************/
++static int gta01_bat_get_property(struct power_supply *psy,
++ enum power_supply_property psp,
++ union power_supply_propval *val)
++{
++ if (pmu_bat_get_property)
++ return (pmu_bat_get_property)(psy, psp, val);
++ else
++ return -ENODEV;
++}
++
++static enum power_supply_property gta01_bat_props[] = {
++ POWER_SUPPLY_PROP_STATUS,
++ POWER_SUPPLY_PROP_PRESENT,
++ POWER_SUPPLY_PROP_ONLINE,
++ POWER_SUPPLY_PROP_VOLTAGE_NOW,
++ POWER_SUPPLY_PROP_CURRENT_NOW,
++ POWER_SUPPLY_PROP_TEMP,
++ POWER_SUPPLY_PROP_CAPACITY,
++};
++
++/*********************************************************************
++ * Initialisation
++ *********************************************************************/
++
++static struct platform_device *bat_pdev;
++
++static struct power_supply gta01_bat = {
++ .properties = gta01_bat_props,
++ .num_properties = ARRAY_SIZE(gta01_bat_props),
++ .get_property = gta01_bat_get_property,
++ .use_for_apm = 0, /* pcf50606 driver has its own apm driver */
++};
++
++static int __init gta01_bat_init(void)
++{
++ int ret;
++
++ bat_pdev = platform_device_register_simple("gta01-battery", 0, NULL, 0);
++ if (IS_ERR(bat_pdev))
++ return PTR_ERR(bat_pdev);
++
++ gta01_bat.name = bat_pdev->name;
++
++ ret = power_supply_register(&bat_pdev->dev, &gta01_bat);
++ if (ret)
++ platform_device_unregister(bat_pdev);
++
++ return ret;
++}
++
++static void __exit gta01_bat_exit(void)
++{
++ power_supply_unregister(&gta01_bat);
++ platform_device_unregister(bat_pdev);
++}
++
++module_init(gta01_bat_init);
++module_exit(gta01_bat_exit);
++
++MODULE_AUTHOR("Mike Westerhof <mwester@dls.net>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Battery driver for GTA01");
+--
+1.5.6.5
+