pull master
[hh.org.git] / drivers / hwmon / battery / simpad-battery.c
blob0c42e14438473ad0528bbf7c2d40d2adeb45cb5e
1 /*
2 * linux/drivers/misc/simpad-battery.c
4 * Copyright (C) 2005 Holger Hans Peter Freyther
5 * Copyright (C) 2001 Juergen Messerer
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License.
11 * Read the Battery Level through the UCB1x00 chip. T-Sinuspad is
12 * unsupported for now.
16 #include <linux/battery.h>
17 #include <asm/dma.h>
18 #include "ucb1x00.h"
22 * Conversion from AD -> mV
23 * 7.5V = 1023 7.3313mV/Digit
25 * 400 Units == 9.7V
26 * a = ADC value
27 * 21 = ADC error
28 * 12600 = Divident to get 2*7.3242
29 * 860 = Divider to get 2*7.3242
30 * 170 = Voltagedrop over
32 #define CALIBRATE_BATTERY(a) ((((a + 21)*12600)/860) + 170)
35 * We have two types of batteries a small and a large one
36 * To get the right value we to distinguish between those two
37 * 450 Units == 15 V
39 #define CALIBRATE_SUPPLY(a) (((a) * 1500) / 45)
40 #define MIN_SUPPLY 12000 /* Less then 12V means no powersupply */
43 * Charging Current
44 * if value is >= 50 then charging is on
46 #define CALIBRATE_CHARGING(a) (((a)* 1000)/(152/4)))
48 struct simpad_battery_t {
49 struct battery battery;
50 struct ucb1x00* ucb;
53 * Variables for the values to one time support
54 * T-Sinuspad as well
56 int min_voltage;
57 int min_current;
58 int min_charge;
60 int max_voltage;
61 int max_current;
62 int max_charge;
64 int min_supply;
65 int charging_led_label;
66 int charging_max_label;
67 int batt_full;
68 int batt_low;
69 int batt_critical;
70 int batt_empty;
73 static int simpad_get_min_voltage(struct battery* _battery )
75 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
76 return battery->min_voltage;
79 static int simpad_get_min_current(struct battery* _battery)
81 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
82 return battery->min_current;
85 static int simpad_get_min_charge(struct battery* _battery)
87 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
88 return battery->min_charge;
91 static int simpad_get_max_voltage(struct battery* _battery)
93 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
94 return battery->max_voltage;
97 static int simpad_get_max_current(struct battery* _battery)
99 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
100 return battery->max_current;
103 static int simpad_get_max_charge(struct battery* _battery)
105 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
106 return battery->max_charge;
109 static int simpad_get_temp(struct battery* _battery)
111 return 0;
114 static int simpad_get_voltage(struct battery* _battery)
116 int val;
117 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
120 ucb1x00_adc_enable(battery->ucb);
121 val = ucb1x00_adc_read(battery->ucb, UCB_ADC_INP_AD1, UCB_NOSYNC);
122 ucb1x00_adc_disable(battery->ucb);
124 return CALIBRATE_BATTERY(val);
127 static int simpad_get_current(struct battery* _battery)
129 int val;
130 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
132 ucb1x00_adc_enable(battery->ucb);
133 val = ucb1x00_adc_read(battery->ucb, UCB_ADC_INP_AD3, UCB_NOSYNC);
134 ucb1x00_adc_disable(battery->ucb);
136 return val;
139 static int simpad_get_charge(struct battery* _battery)
141 int val;
142 struct simpad_battery_t* battery = (struct simpad_battery_t*)_battery;
144 ucb1x00_adc_enable(battery->ucb);
145 val = ucb1x00_adc_read(battery->ucb, UCB_ADC_INP_AD2, UCB_NOSYNC);
146 ucb1x00_adc_disable(battery->ucb);
148 return CALIBRATE_SUPPLY(val);
152 static int simpad_get_status(struct battery* _battery)
154 struct simpad_battery_t* battery = (struct simpad_battery_t*)(_battery);
155 int vcharger = simpad_get_voltage(_battery);
156 int icharger = simpad_get_current(_battery);
158 int status = BATTERY_STATUS_UNKNOWN;
159 if(icharger > battery->charging_led_label)
160 status = BATTERY_STATUS_CHARGING;
161 else if(vcharger > battery->min_supply)
162 status = BATTERY_STATUS_NOT_CHARGING;
163 else
164 status = BATTERY_STATUS_DISCHARGING;
166 return status;
169 static struct simpad_battery_t simpad_battery = {
170 .battery = {
171 .get_min_voltage = simpad_get_min_voltage,
172 .get_min_current = simpad_get_min_current,
173 .get_min_charge = simpad_get_min_charge,
174 .get_max_voltage = simpad_get_max_voltage,
175 .get_max_current = simpad_get_max_current,
176 .get_max_charge = simpad_get_max_charge,
177 .get_temp = simpad_get_temp,
178 .get_voltage = simpad_get_voltage,
179 .get_current = simpad_get_current,
180 .get_charge = simpad_get_charge,
181 .get_status = simpad_get_status,
183 .min_voltage = 0,
184 .min_current = 0,
185 .min_charge = 0,
186 .max_voltage = 0,
187 .max_current = 0,
188 .max_charge = 0,
190 .min_supply = 1200,
191 .charging_led_label = 18,
192 .charging_max_label = 265,
193 .batt_full = 8300,
194 .batt_low = 7300,
195 .batt_critical = 6800,
196 .batt_empty = 6500,
202 * UCB glue code
204 static int ucb1x00_battery_add(struct class_device *dev)
206 struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
207 simpad_battery.ucb = ucb;
209 battery_class_register(&simpad_battery.battery);
211 return 0;
214 static void ucb1x00_battery_remove(struct class_device *dev)
216 return battery_class_unregister(&simpad_battery.battery);
220 static struct ucb1x00_class_interface ucb1x00_battery_interface = {
221 .interface = {
222 .add = ucb1x00_battery_add,
223 .remove = ucb1x00_battery_remove,
228 static int __init battery_register(void)
230 return ucb1x00_register_interface(&ucb1x00_battery_interface);
233 static void __exit battery_unregister(void)
235 ucb1x00_unregister_interface(&ucb1x00_battery_interface);
238 module_init(battery_register);
239 module_exit(battery_unregister);
241 MODULE_AUTHOR("Holger Hans Peter Freyther");
242 MODULE_LICENSE("GPL");