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.
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>
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>
28 #define dprintk(x...) printk(x)
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
;
81 return BATTERY_STATUS_NOT_CHARGING
;
86 static int blueangel_battery_get_voltage1(struct battery
*bat
)
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
));
102 retval
= tsc2200_read(&blueangel_tsc2200
.dev
, TSC2200_DATAREG_AUX1
);
104 bat_tsc2200_stop_conv();
105 //tsc2200_unlock(&blueangel_tsc2200.dev);
109 static int blueangel_battery_get_voltage(struct battery
*bat
)
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
));
125 retval
= tsc2200_read(&blueangel_tsc2200
.dev
, TSC2200_DATAREG_AUX2
);
127 bat_tsc2200_stop_conv();
128 //tsc2200_unlock(&blueangel_tsc2200.dev);
133 static int blueangel_battery_get_temp(struct battery
*bat
)
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
));
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);
155 dprintk("%s: out\n", __FUNCTION__
);
159 struct battery battery_dev
= {
160 .name
= "Main battery",
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",
170 .get_voltage
= blueangel_battery_get_voltage1
,
171 .get_status
= blueangel_battery_get_status
,
172 //.get_temp = blueangel_battery_get_tempi1,
176 blueangel_battery_get_power_status (struct apm_power_info
*info
)
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
);
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
;
217 info
->battery_status
= APM_BATTERY_STATUS_CHARGING
;
218 #ifdef CONFIG_LEDS_TRIGGERS
219 led_trigger_event(ledtrig_cradle
, LED_FULL
);
224 static int bat_setup(void)
226 battery_class_register(&battery_dev
);
227 battery_class_register(&battery_dev1
);
231 static int __init
bat_init(void)
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
);
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
);
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");