2 * linux/drivers/power/palmtx_battery.c
4 * Battery measurement code for Palm T|X Handheld computer
6 * based on tosa_battery.c
8 * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/power_supply.h>
18 #include <linux/wm97xx.h>
19 #include <linux/delay.h>
20 #include <linux/spinlock.h>
21 #include <linux/interrupt.h>
22 #include <linux/gpio.h>
24 #include <asm/mach-types.h>
25 #include <mach/palmtx.h>
27 static DEFINE_MUTEX(bat_lock);
28 static struct work_struct bat_work;
29 struct mutex work_lock;
30 int bat_status = POWER_SUPPLY_STATUS_DISCHARGING;
32 static unsigned long palmtx_read_bat(struct power_supply *bat_ps)
34 return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
35 WM97XX_AUX_ID3) * 1000 / 414;
38 static unsigned long palmtx_read_temp(struct power_supply *bat_ps)
40 return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
44 static int palmtx_bat_get_property(struct power_supply *bat_ps,
45 enum power_supply_property psp,
46 union power_supply_propval *val)
49 case POWER_SUPPLY_PROP_STATUS:
50 val->intval = bat_status;
52 case POWER_SUPPLY_PROP_TECHNOLOGY:
53 val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
55 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
56 val->intval = palmtx_read_bat(bat_ps);
58 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
59 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
60 val->intval = PALMTX_BAT_MAX_VOLTAGE;
62 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
63 val->intval = PALMTX_BAT_MIN_VOLTAGE;
65 case POWER_SUPPLY_PROP_TEMP:
66 val->intval = palmtx_read_temp(bat_ps);
68 case POWER_SUPPLY_PROP_PRESENT:
77 static void palmtx_bat_external_power_changed(struct power_supply *bat_ps)
79 schedule_work(&bat_work);
82 static char *status_text[] = {
83 [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
84 [POWER_SUPPLY_STATUS_CHARGING] = "Charging",
85 [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
88 static void palmtx_bat_update(struct power_supply *bat_ps)
90 int old_status = bat_status;
92 mutex_lock(&work_lock);
94 bat_status = gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT) ?
95 POWER_SUPPLY_STATUS_CHARGING :
96 POWER_SUPPLY_STATUS_DISCHARGING;
98 if (old_status != bat_status) {
99 pr_debug("%s %s -> %s\n", bat_ps->name,
100 status_text[old_status],
101 status_text[bat_status]);
102 power_supply_changed(bat_ps);
105 mutex_unlock(&work_lock);
108 static enum power_supply_property palmtx_bat_main_props[] = {
109 POWER_SUPPLY_PROP_STATUS,
110 POWER_SUPPLY_PROP_TECHNOLOGY,
111 POWER_SUPPLY_PROP_VOLTAGE_NOW,
112 POWER_SUPPLY_PROP_VOLTAGE_MAX,
113 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
114 POWER_SUPPLY_PROP_TEMP,
115 POWER_SUPPLY_PROP_PRESENT,
118 struct power_supply bat_ps = {
119 .name = "main-battery",
120 .type = POWER_SUPPLY_TYPE_BATTERY,
121 .properties = palmtx_bat_main_props,
122 .num_properties = ARRAY_SIZE(palmtx_bat_main_props),
123 .get_property = palmtx_bat_get_property,
124 .external_power_changed = palmtx_bat_external_power_changed,
128 static void palmtx_bat_work(struct work_struct *work)
130 palmtx_bat_update(&bat_ps);
134 static int palmtx_bat_suspend(struct platform_device *dev, pm_message_t state)
136 flush_scheduled_work();
140 static int palmtx_bat_resume(struct platform_device *dev)
142 schedule_work(&bat_work);
146 #define palmtx_bat_suspend NULL
147 #define palmtx_bat_resume NULL
150 static int __devinit palmtx_bat_probe(struct platform_device *dev)
154 if (!machine_is_palmtx())
157 mutex_init(&work_lock);
159 INIT_WORK(&bat_work, palmtx_bat_work);
161 ret = power_supply_register(&dev->dev, &bat_ps);
163 schedule_work(&bat_work);
168 static int __devexit palmtx_bat_remove(struct platform_device *dev)
170 power_supply_unregister(&bat_ps);
174 static struct platform_driver palmtx_bat_driver = {
175 .driver.name = "wm97xx-battery",
176 .driver.owner = THIS_MODULE,
177 .probe = palmtx_bat_probe,
178 .remove = __devexit_p(palmtx_bat_remove),
179 .suspend = palmtx_bat_suspend,
180 .resume = palmtx_bat_resume,
183 static int __init palmtx_bat_init(void)
185 return platform_driver_register(&palmtx_bat_driver);
188 static void __exit palmtx_bat_exit(void)
190 platform_driver_unregister(&palmtx_bat_driver);
193 module_init(palmtx_bat_init);
194 module_exit(palmtx_bat_exit);
196 MODULE_LICENSE("GPL");
197 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
198 MODULE_DESCRIPTION("Palm T|X battery driver");