hh.org updates
[hh.org.git] / arch / arm / mach-pxa / htcblueangel / blueangel_battery.c
blobe256a82f25eac7e15a25048aa7cf2b5fdf429bee
1 /*
2 * Driver interface to the battery on the HTC Blueangel
4 * Use consistent with the GNU GPL is permitted,
5 * provided that this copyright notice is
6 * preserved in its entirety in all copies and derived works.
8 */
10 #include <linux/module.h>
11 #include <linux/delay.h>
12 #include <linux/version.h>
13 //#include <linux/config.h>
14 #include <linux/battery.h>
15 #include <linux/leds.h>
16 #include <linux/soc/asic3_base.h>
17 #include <linux/platform_device.h>
19 #include <asm/apm.h>
20 #include <asm/arch/hardware.h>
21 #include <asm/arch/pxa-regs.h>
22 #include <asm/arch/htcblueangel-gpio.h>
23 #include <asm/arch/htcblueangel-asic.h>
25 #include <linux/soc/tsc2200.h>
27 #ifdef DEBUG
28 #define dprintk(x...) printk(x)
29 #else
30 #define dprintk(x...)
31 #endif
33 extern struct platform_device blueangel_tsc2200;
34 DEFINE_LED_TRIGGER(ledtrig_cradle);
38 static void bat_tsc2200_start_conv_scan(void)
40 tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_REF, 31);
41 tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC,
42 TSC2200_CTRLREG_ADC_AD3 |
43 TSC2200_CTRLREG_ADC_AD1 |
44 TSC2200_CTRLREG_ADC_AD0 |
45 TSC2200_CTRLREG_ADC_RES (TSC2200_CTRLREG_ADC_RES_12BITP) |
46 TSC2200_CTRLREG_ADC_AVG (TSC2200_CTRLREG_ADC_8AVG) |
47 TSC2200_CTRLREG_ADC_CL (TSC2200_CTRLREG_ADC_CL_2MHZ_12BIT) |
48 TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
51 static void bat_tsc2200_start_conv_temp(void)
53 tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_REF, 31);
54 tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC,
55 TSC2200_CTRLREG_ADC_AD3 |
56 TSC2200_CTRLREG_ADC_AD1 |
57 TSC2200_CTRLREG_ADC_RES (TSC2200_CTRLREG_ADC_RES_12BITP) |
58 TSC2200_CTRLREG_ADC_AVG (TSC2200_CTRLREG_ADC_8AVG) |
59 TSC2200_CTRLREG_ADC_CL (TSC2200_CTRLREG_ADC_CL_2MHZ_12BIT) |
60 TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
63 static void bat_tsc2200_stop_conv(void)
65 tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC,
66 TSC2200_CTRLREG_ADC_STS |
67 TSC2200_CTRLREG_ADC_AD0 |
68 TSC2200_CTRLREG_ADC_RES (TSC2200_CTRLREG_ADC_RES_12BITP) |
69 TSC2200_CTRLREG_ADC_AVG (TSC2200_CTRLREG_ADC_8AVG) |
70 TSC2200_CTRLREG_ADC_CL (TSC2200_CTRLREG_ADC_CL_2MHZ_12BIT) |
71 TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
74 static int blueangel_battery_get_status(struct battery *bat)
76 dprintk("%s: in.\n", __FUNCTION__);
78 if ( GPLR(63) & GPIO_bit(63) ) {
79 return BATTERY_STATUS_CHARGING;
80 } else {
81 return BATTERY_STATUS_NOT_CHARGING;
86 static int blueangel_battery_get_voltage1(struct battery *bat)
88 int retval;
90 dprintk("%s: in.\n", __FUNCTION__);
92 //down_interruptible(&tsc2200_sem);
93 //tsc2200_lock(&blueangel_tsc2200.dev);
94 bat_tsc2200_start_conv_scan();
96 while ( !(tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC) & 0x4000) &&
97 !tsc2200_dav(&blueangel_tsc2200.dev )) {
98 dprintk("B2: %X\n", tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC));
99 mdelay(1);
102 retval = tsc2200_read(&blueangel_tsc2200.dev, TSC2200_DATAREG_AUX1);
104 bat_tsc2200_stop_conv();
105 //tsc2200_unlock(&blueangel_tsc2200.dev);
106 //up(&tsc2200_sem);
107 return retval;
109 static int blueangel_battery_get_voltage(struct battery *bat)
111 int retval;
113 dprintk("%s: in.\n", __FUNCTION__);
115 //down_interruptible(&tsc2200_sem);
116 //tsc2200_lock(&blueangel_tsc2200.dev);
117 bat_tsc2200_start_conv_scan();
119 while ( !(tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC) & 0x4000) &&
120 !tsc2200_dav(&blueangel_tsc2200.dev )) {
121 dprintk("B2: %X\n", tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC));
122 mdelay(1);
125 retval = tsc2200_read(&blueangel_tsc2200.dev, TSC2200_DATAREG_AUX2);
127 bat_tsc2200_stop_conv();
128 //tsc2200_unlock(&blueangel_tsc2200.dev);
129 //up(&tsc2200_sem);
130 return retval;
133 static int blueangel_battery_get_temp(struct battery *bat)
135 int retval;
137 dprintk("%s: in.\n", __FUNCTION__);
139 //down_interruptible(&tsc2200_sem);
140 //tsc2200_lock(&blueangel_tsc2200.dev);
141 bat_tsc2200_start_conv_temp();
143 while ( !(tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC) & 0x4000) &&
144 !tsc2200_dav(&blueangel_tsc2200.dev)) {
145 dprintk("1: %X\n", tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC));
146 mdelay(1);
149 retval = tsc2200_read(&blueangel_tsc2200.dev, TSC2200_DATAREG_TEMP1);
150 dprintk("retval=0x%x\n", retval);
152 bat_tsc2200_stop_conv();
153 //tsc2200_unlock(&blueangel_tsc2200.dev);
154 //up(&tsc2200_sem);
155 dprintk("%s: out\n", __FUNCTION__);
156 return retval;
159 struct battery battery_dev = {
160 .name = "Main battery",
161 .id = "battery0",
162 .get_voltage = blueangel_battery_get_voltage,
163 .get_status = blueangel_battery_get_status,
164 //.get_temp = blueangel_battery_get_temp,
167 struct battery battery_dev1 = {
168 .name = "Backup battery",
169 .id = "battery1",
170 .get_voltage = blueangel_battery_get_voltage1,
171 .get_status = blueangel_battery_get_status,
172 //.get_temp = blueangel_battery_get_tempi1,
175 static void
176 blueangel_battery_get_power_status (struct apm_power_info *info)
178 int val;
179 int val1;
180 int full=0x8ea;
181 int empty=0x8a3;
183 int full1=0xb0f;
184 int empty1=0x8a3;
185 val=blueangel_battery_get_voltage(NULL);
186 val1=blueangel_battery_get_voltage1(NULL);
188 info->battery_life = (val1-empty)*100/(full-empty);
189 if (info->battery_life < 0 || info->battery_life > 100)
190 printk("battery voltage (0x%x) not within [0x%x,0x%x]. Please report.\n", val, full, empty);
191 if (info->battery_life < 0)
192 info->battery_life = 0;
193 if (info->battery_life > 100)
194 info->battery_life = 100;
195 info->ac_line_status = APM_AC_OFFLINE;
196 if (!(asic3_get_gpio_status_d(&blueangel_tsc2200.dev) & GPIOD_AC_CHARGER_N)) {
197 info->ac_line_status = APM_AC_ONLINE;
199 if (!(GPLR(GPIO_NR_BLUEANGEL_USB_DETECT_N) & GPIO_bit(GPIO_NR_BLUEANGEL_USB_DETECT_N))) {
200 info->ac_line_status = APM_AC_ONLINE;
202 info->units=APM_UNITS_MINS;
203 info->time = 360 * info->battery_life/100; /* time remaining */
204 info->battery_flag = 0;
205 if (info->ac_line_status == APM_AC_OFFLINE) {
206 #ifdef CONFIG_LEDS_TRIGGERS
207 led_trigger_event(ledtrig_cradle, LED_OFF);
208 #endif
209 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
210 if(info->battery_life > 5) {
211 info->battery_status = APM_BATTERY_STATUS_LOW;
213 if(info->battery_life > 20) {
214 info->battery_status = APM_BATTERY_STATUS_HIGH;
216 } else {
217 info->battery_status = APM_BATTERY_STATUS_CHARGING;
218 #ifdef CONFIG_LEDS_TRIGGERS
219 led_trigger_event(ledtrig_cradle, LED_FULL);
220 #endif
224 static int bat_setup(void)
226 battery_class_register(&battery_dev);
227 battery_class_register(&battery_dev1);
228 return 0;
231 static int __init bat_init(void)
233 bat_setup();
234 blueangel_battery_get_voltage(NULL);
235 blueangel_battery_get_voltage1(NULL);
236 blueangel_battery_get_temp(NULL);
237 apm_get_power_status = blueangel_battery_get_power_status;
238 #ifdef CONFIG_LEDS_TRIGGERS
239 led_trigger_register_simple("charge", &ledtrig_cradle);
240 #endif
242 return 0;
245 static void __exit bat_exit(void)
247 apm_get_power_status = NULL;
248 battery_class_unregister(&battery_dev);
249 battery_class_unregister(&battery_dev1);
250 #ifdef CONFIG_LEDS_TRIGGERS
251 led_trigger_unregister_simple(ledtrig_cradle);
252 #endif
255 module_init(bat_init)
256 module_exit(bat_exit)
258 MODULE_AUTHOR("Matthias Burghardt");
259 MODULE_DESCRIPTION("Battery (TI TSC2200) support for the HTC Blueangel");
260 MODULE_LICENSE("GPL");