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 <asm/arch/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");