changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1324-gta01-battery-driver.patch.patch
1 From 8aefbe43a7864e611dca9821daec3e10009e7171 Mon Sep 17 00:00:00 2001
2 From: Mike Westerhof <mwester@dls.net>
3 Date: Thu, 13 Nov 2008 20:50:55 +0000
4 Subject: [PATCH] gta01-battery-driver.patch
5
6 Adds a simple pass-through battery driver module for the GTA01.
7 This will simplify user-space by providing the same sysfs API
8 on both GTA01 and GTA02, and is a first step towards eliminating
9 the need for APM emulation.
10
11 Signed-off-by: Mike Westerhof <mwester@dls.net>
12 ---
13  arch/arm/configs/gta02-moredrivers-defconfig |    1 +
14  defconfig-gta01                              |    1 +
15  defconfig-gta02                              |    1 +
16  drivers/i2c/chips/pcf50606.c                 |   96 +++++++++++++++++++++++++
17  drivers/power/Kconfig                        |    6 ++
18  drivers/power/Makefile                       |    1 +
19  drivers/power/gta01_battery.c                |   97 ++++++++++++++++++++++++++
20  7 files changed, 203 insertions(+), 0 deletions(-)
21  create mode 100644 drivers/power/gta01_battery.c
22
23 diff --git a/arch/arm/configs/gta02-moredrivers-defconfig b/arch/arm/configs/gta02-moredrivers-defconfig
24 index 113eaec..5e1547e 100644
25 --- a/arch/arm/configs/gta02-moredrivers-defconfig
26 +++ b/arch/arm/configs/gta02-moredrivers-defconfig
27 @@ -1060,6 +1060,7 @@ CONFIG_POWER_SUPPLY_DEBUG=y
28  CONFIG_PDA_POWER=y
29  CONFIG_APM_POWER=y
30  # CONFIG_BATTERY_DS2760 is not set
31 +# CONFIG_BATTERY_GTA01 is not set
32  CONFIG_BATTERY_BQ27000_HDQ=y
33  CONFIG_GTA02_HDQ=y
34  CONFIG_HWMON=y
35 diff --git a/defconfig-gta01 b/defconfig-gta01
36 index cecb57f..e2e4330 100644
37 --- a/defconfig-gta01
38 +++ b/defconfig-gta01
39 @@ -1021,6 +1021,7 @@ CONFIG_POWER_SUPPLY=y
40  # CONFIG_PDA_POWER is not set
41  # CONFIG_APM_POWER is not set
42  # CONFIG_BATTERY_DS2760 is not set
43 +CONFIG_BATTERY_GTA01=y
44  CONFIG_BATTERY_BQ27000_HDQ=y
45  CONFIG_GTA02_HDQ=y
46  # CONFIG_HWMON is not set
47 diff --git a/defconfig-gta02 b/defconfig-gta02
48 index 619f7f2..2a6e398 100644
49 --- a/defconfig-gta02
50 +++ b/defconfig-gta02
51 @@ -1021,6 +1021,7 @@ CONFIG_POWER_SUPPLY=y
52  # CONFIG_PDA_POWER is not set
53  CONFIG_APM_POWER=y
54  # CONFIG_BATTERY_DS2760 is not set
55 +# CONFIG_BATTERY_GTA01 is not set
56  CONFIG_BATTERY_BQ27000_HDQ=y
57  CONFIG_GTA02_HDQ=y
58  # CONFIG_HWMON is not set
59 diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
60 index 706ce6d..f585013 100644
61 --- a/drivers/i2c/chips/pcf50606.c
62 +++ b/drivers/i2c/chips/pcf50606.c
63 @@ -50,6 +50,7 @@
64  #include <linux/platform_device.h>
65  #include <linux/pcf50606.h>
66  #include <linux/apm-emulation.h>
67 +#include <linux/power_supply.h>
68  
69  #include <asm/mach-types.h>
70  #include <asm/arch/gta01.h>
71 @@ -141,6 +142,12 @@ struct pcf50606_data {
72  
73  static struct i2c_driver pcf50606_driver;
74  
75 +/* This global is set by the pcf50606 driver to the correct callback
76 + * for the gta01 battery driver. */
77 +int (*pmu_bat_get_property)(struct power_supply *, enum power_supply_property,
78 +                           union power_supply_propval *);
79 +EXPORT_SYMBOL(pmu_bat_get_property);
80 +
81  /* This is an ugly construct on how to access the (currently single/global)
82   * pcf50606 handle from other code in the kernel.  I didn't really come up with
83   * a more decent method of dynamically resolving this */
84 @@ -1270,6 +1277,92 @@ static void pcf50606_get_power_status(struct apm_power_info *info)
85  }
86  
87  /***********************************************************************
88 + * Battery driver interface
89 + ***********************************************************************/
90 +static int pcf50606_bat_get_property(struct power_supply *psy,
91 +                                    enum power_supply_property psp,
92 +                                    union power_supply_propval *val)
93 +{
94 +       u_int16_t adc, adc_adcin1;
95 +       u_int8_t mbcc1, chgmod;
96 +       struct pcf50606_data *pcf = pcf50606_global;
97 +       int ret = 0;
98 +
99 +       switch (psp) {
100 +
101 +       case POWER_SUPPLY_PROP_STATUS:
102 +               if (!(reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON)) {
103 +                       /* No charger, clearly we're discharging then */
104 +                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
105 +               } else {
106 +
107 +                       /* We have a charger present, get charge mode */
108 +                       mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1);
109 +                       chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK);
110 +                       switch (chgmod) {
111 +
112 +                       /* TODO: How to determine POWER_SUPPLY_STATUS_FULL? */
113 +
114 +                       case PCF50606_MBCC1_CHGMOD_QUAL:
115 +                       case PCF50606_MBCC1_CHGMOD_PRE:
116 +                       case PCF50606_MBCC1_CHGMOD_IDLE:
117 +                               val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
118 +                               break;
119 +
120 +                       case PCF50606_MBCC1_CHGMOD_TRICKLE:
121 +                       case PCF50606_MBCC1_CHGMOD_FAST_CCCV:
122 +                       case PCF50606_MBCC1_CHGMOD_FAST_NOCC:
123 +                       case PCF50606_MBCC1_CHGMOD_FAST_NOCV:
124 +                       case PCF50606_MBCC1_CHGMOD_FAST_SW:
125 +                               val->intval = POWER_SUPPLY_STATUS_CHARGING;
126 +                               break;
127 +
128 +                       default:
129 +                               val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
130 +                               break;
131 +
132 +                       }
133 +               }
134 +
135 +       case POWER_SUPPLY_PROP_PRESENT:
136 +               val->intval = 1;   /* Must be, or the magic smoke comes out */
137 +               break;
138 +
139 +       case POWER_SUPPLY_PROP_ONLINE:
140 +               val->intval = !!(reg_read(pcf, PCF50606_REG_OOCS) &
141 +                                PCF50606_OOCS_EXTON);
142 +               break;
143 +
144 +       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
145 +               adc = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_RES, NULL);
146 +               /* (adc * 6000000) / 1024 ==  (adc * 46875) / 8 */
147 +               val->intval = (adc * 46875) / 8;
148 +               break;
149 +
150 +       case POWER_SUPPLY_PROP_CURRENT_NOW:
151 +               adc = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_ADCIN1,
152 +                              &adc_adcin1);
153 +               val->intval = adc_to_chg_milliamps(pcf, adc_adcin1, adc) * 1000;
154 +               break;
155 +
156 +       case POWER_SUPPLY_PROP_TEMP:
157 +               adc = adc_read(pcf, PCF50606_ADCMUX_BATTEMP, NULL);
158 +               val->intval = rntc_to_temp(adc_to_rntc(pcf, adc)) * 10;
159 +               break;
160 +
161 +       case POWER_SUPPLY_PROP_CAPACITY:
162 +               val->intval = battvolt_scale(pcf50606_battvolt(pcf));
163 +               break;
164 +
165 +       default:
166 +               ret = -EINVAL;
167 +               break;
168 +       }
169 +
170 +       return ret;
171 +}
172 +
173 +/***********************************************************************
174   * RTC
175   ***********************************************************************/
176  
177 @@ -1900,6 +1993,7 @@ static int pcf50606_detect(struct i2c_adapter *adapter, int address, int kind)
178         }
179  
180         apm_get_power_status = pcf50606_get_power_status;
181 +       pmu_bat_get_property = pcf50606_bat_get_property;
182  
183  #ifdef CONFIG_MACH_NEO1973_GTA01
184         if (machine_is_neo1973_gta01()) {
185 @@ -1962,6 +2056,8 @@ static int pcf50606_detach_client(struct i2c_client *client)
186         struct pcf50606_data *pcf = i2c_get_clientdata(client);
187  
188         apm_get_power_status = NULL;
189 +       pmu_bat_get_property = NULL;
190 +
191         input_unregister_device(pcf->input_dev);
192  
193         if (pcf->pdata->used_features & PCF50606_FEAT_PWM_BL)
194 diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
195 index 8c50ecb..470e08c 100644
196 --- a/drivers/power/Kconfig
197 +++ b/drivers/power/Kconfig
198 @@ -62,5 +62,11 @@ config GTA02_HDQ
199           on the Neo Freerunner.  You probably want to select
200           at least BATTERY_BQ27000_HDQ as well
201  
202 +config BATTERY_GTA01
203 +       tristate "Neo GTA01 battery"
204 +       depends on MACH_NEO1973_GTA01
205 +       help
206 +         Say Y to enable support for the battery on the Neo GTA01
207 +
208  endif # POWER_SUPPLY
209  
210 diff --git a/drivers/power/Makefile b/drivers/power/Makefile
211 index d7e87ad..2013e89 100644
212 --- a/drivers/power/Makefile
213 +++ b/drivers/power/Makefile
214 @@ -21,5 +21,6 @@ obj-$(CONFIG_BATTERY_DS2760)  += ds2760_battery.o
215  obj-$(CONFIG_BATTERY_PMU)      += pmu_battery.o
216  obj-$(CONFIG_BATTERY_OLPC)     += olpc_battery.o
217  obj-$(CONFIG_BATTERY_BQ27000_HDQ)      += bq27000_battery.o
218 +obj-$(CONFIG_BATTERY_GTA01)    += gta01_battery.o
219  
220  obj-$(CONFIG_GTA02_HDQ)                += gta02_hdq.o
221 diff --git a/drivers/power/gta01_battery.c b/drivers/power/gta01_battery.c
222 new file mode 100644
223 index 0000000..5acb45c
224 --- /dev/null
225 +++ b/drivers/power/gta01_battery.c
226 @@ -0,0 +1,97 @@
227 +/*
228 + * Battery driver for the Openmoko GTA01 device, using the pcf50606 chip.
229 + *
230 + * This is nothing more than a write-thru interface to the real logic,
231 + * which is part of the pcf50606.c multifunction chip driver.
232 + *     Copyright Â© 2008  Mike Westerhof <mwester@dls.net>
233 + *
234 + *
235 + * Portions liberally borrowed from olpc_battery.c, copyright below:
236 + *     Copyright Â© 2006  David Woodhouse <dwmw2@infradead.org>
237 + *
238 + * This program is free software; you can redistribute it and/or modify
239 + * it under the terms of the GNU General Public License version 2 as
240 + * published by the Free Software Foundation.
241 + */
242 +
243 +#include <linux/module.h>
244 +#include <linux/err.h>
245 +#include <linux/platform_device.h>
246 +#include <linux/power_supply.h>
247 +#include <linux/jiffies.h>
248 +#include <linux/sched.h>
249 +
250 +/*********************************************************************
251 + * This global is set by the pcf50606 driver to the correct callback
252 + *********************************************************************/
253 +
254 +extern int (*pmu_bat_get_property)(struct power_supply *,
255 +                                  enum power_supply_property,
256 +                                  union power_supply_propval *);
257 +
258 +
259 +/*********************************************************************
260 + *             Battery properties
261 + *********************************************************************/
262 +static int gta01_bat_get_property(struct power_supply *psy,
263 +                                 enum power_supply_property psp,
264 +                                 union power_supply_propval *val)
265 +{
266 +       if (pmu_bat_get_property)
267 +               return (pmu_bat_get_property)(psy, psp, val);
268 +       else
269 +               return -ENODEV;
270 +}
271 +
272 +static enum power_supply_property gta01_bat_props[] = {
273 +       POWER_SUPPLY_PROP_STATUS,
274 +       POWER_SUPPLY_PROP_PRESENT,
275 +       POWER_SUPPLY_PROP_ONLINE,
276 +       POWER_SUPPLY_PROP_VOLTAGE_NOW,
277 +       POWER_SUPPLY_PROP_CURRENT_NOW,
278 +       POWER_SUPPLY_PROP_TEMP,
279 +       POWER_SUPPLY_PROP_CAPACITY,
280 +};
281 +
282 +/*********************************************************************
283 + *             Initialisation
284 + *********************************************************************/
285 +
286 +static struct platform_device *bat_pdev;
287 +
288 +static struct power_supply gta01_bat = {
289 +       .properties = gta01_bat_props,
290 +       .num_properties = ARRAY_SIZE(gta01_bat_props),
291 +       .get_property = gta01_bat_get_property,
292 +       .use_for_apm = 0,  /* pcf50606 driver has its own apm driver */
293 +};
294 +
295 +static int __init gta01_bat_init(void)
296 +{
297 +       int ret;
298 +
299 +       bat_pdev = platform_device_register_simple("gta01-battery", 0, NULL, 0);
300 +       if (IS_ERR(bat_pdev))
301 +               return PTR_ERR(bat_pdev);
302 +
303 +       gta01_bat.name = bat_pdev->name;
304 +
305 +       ret = power_supply_register(&bat_pdev->dev, &gta01_bat);
306 +       if (ret)
307 +               platform_device_unregister(bat_pdev);
308 +
309 +       return ret;
310 +}
311 +
312 +static void __exit gta01_bat_exit(void)
313 +{
314 +       power_supply_unregister(&gta01_bat);
315 +       platform_device_unregister(bat_pdev);
316 +}
317 +
318 +module_init(gta01_bat_init);
319 +module_exit(gta01_bat_exit);
320 +
321 +MODULE_AUTHOR("Mike Westerhof <mwester@dls.net>");
322 +MODULE_LICENSE("GPL");
323 +MODULE_DESCRIPTION("Battery driver for GTA01");
324 -- 
325 1.5.6.5
326