changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.26 / 0024-pcf50633.patch.patch
1 From b04e2c56a057f288342a8ce8f88b7a1dfc88afa1 Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Wed, 16 Jul 2008 14:44:50 +0100
4 Subject: [PATCH] pcf50633.patch
5
6 ---
7  drivers/i2c/chips/Kconfig    |    9 +
8  drivers/i2c/chips/Makefile   |    1 +
9  drivers/i2c/chips/pcf50633.c | 1964 ++++++++++++++++++++++++++++++++++++++++++
10  drivers/i2c/chips/pcf50633.h |  402 +++++++++
11  include/linux/i2c-id.h       |    1 +
12  include/linux/pcf50633.h     |  114 +++
13  6 files changed, 2491 insertions(+), 0 deletions(-)
14  create mode 100644 drivers/i2c/chips/pcf50633.c
15  create mode 100644 drivers/i2c/chips/pcf50633.h
16  create mode 100644 include/linux/pcf50633.h
17
18 diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
19 index e8e64aa..e38c006 100644
20 --- a/drivers/i2c/chips/Kconfig
21 +++ b/drivers/i2c/chips/Kconfig
22 @@ -35,6 +35,15 @@ config SENSORS_PCF50606
23           This driver can also be built as a module.  If so, the module
24           will be called pcf50606.
25  
26 +config SENSORS_PCF50633
27 +       tristate "Philips PCF50633"
28 +       depends on I2C
29 +       help
30 +         If you say yes here you get support for Philips PCF50633
31 +         PMU (Power Management Unit) chips.
32 +
33 +         This driver can also be built as a module.  If so, the module
34 +         will be called pcf50633.
35  
36  config SENSORS_PCF8574
37         tristate "Philips PCF8574 and PCF8574A"
38 diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
39 index 60d3d5a..9fa353d 100644
40 --- a/drivers/i2c/chips/Makefile
41 +++ b/drivers/i2c/chips/Makefile
42 @@ -14,6 +14,7 @@ obj-$(CONFIG_SENSORS_EEPROM)  += eeprom.o
43  obj-$(CONFIG_SENSORS_MAX6875)  += max6875.o
44  obj-$(CONFIG_SENSORS_PCA9539)  += pca9539.o
45  obj-$(CONFIG_SENSORS_PCF50606) += pcf50606.o
46 +obj-$(CONFIG_SENSORS_PCF50633) += pcf50633.o
47  obj-$(CONFIG_SENSORS_PCF8574)  += pcf8574.o
48  obj-$(CONFIG_PCF8575)          += pcf8575.o
49  obj-$(CONFIG_SENSORS_PCF8591)  += pcf8591.o
50 diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
51 new file mode 100644
52 index 0000000..5488084
53 --- /dev/null
54 +++ b/drivers/i2c/chips/pcf50633.c
55 @@ -0,0 +1,1964 @@
56 +/* Philips PCF50633 Power Management Unit (PMU) driver
57 + *
58 + * (C) 2006-2007 by OpenMoko, Inc.
59 + * Author: Harald Welte <laforge@openmoko.org>
60 + * All rights reserved.
61 + *
62 + * This program is free software; you can redistribute it and/or
63 + * modify it under the terms of the GNU General Public License as
64 + * published by the Free Software Foundation; either version 2 of
65 + * the License, or (at your option) any later version.
66 + *
67 + * This program is distributed in the hope that it will be useful,
68 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
69 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
70 + * GNU General Public License for more details.
71 + *
72 + * You should have received a copy of the GNU General Public License
73 + * along with this program; if not, write to the Free Software
74 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
75 + * MA 02111-1307 USA
76 + *
77 + * This driver is a monster ;) It provides the following features
78 + * - voltage control for a dozen different voltage domains
79 + * - charging control for main and backup battery
80 + * - rtc / alarm
81 + * - adc driver (hw_sensors like)
82 + * - backlight
83 + *
84 + */
85 +
86 +#include <linux/module.h>
87 +#include <linux/init.h>
88 +#include <linux/i2c.h>
89 +#include <linux/types.h>
90 +#include <linux/interrupt.h>
91 +#include <linux/irq.h>
92 +#include <linux/workqueue.h>
93 +#include <linux/delay.h>
94 +#include <linux/rtc.h>
95 +#include <linux/bcd.h>
96 +#include <linux/watchdog.h>
97 +#include <linux/miscdevice.h>
98 +#include <linux/input.h>
99 +#include <linux/fb.h>
100 +#include <linux/backlight.h>
101 +#include <linux/sched.h>
102 +#include <linux/platform_device.h>
103 +#include <linux/pcf50633.h>
104 +#include <linux/apm-emulation.h>
105 +
106 +#include <asm/mach-types.h>
107 +#include <asm/arch/gta02.h>
108 +
109 +#include "pcf50633.h"
110 +
111 +#if 1
112 +#define DEBUGP(x, args ...) printk("%s: " x, __FUNCTION__, ## args)
113 +#define DEBUGPC(x, args ...) printk(x, ## args)
114 +#else
115 +#define DEBUGP(x, args ...)
116 +#define DEBUGPC(x, args ...)
117 +#endif
118 +
119 +/***********************************************************************
120 + * Static data / structures
121 + ***********************************************************************/
122 +
123 +static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
124 +
125 +I2C_CLIENT_INSMOD_1(pcf50633);
126 +
127 +#define PCF50633_FIDX_CHG_ENABLED      0       /* Charger enabled */
128 +#define PCF50633_FIDX_CHG_PRESENT      1       /* Charger present */
129 +#define PCF50633_FIDX_CHG_ERR          3       /* Charger Error */
130 +#define PCF50633_FIDX_CHG_PROT         4       /* Charger Protection */
131 +#define PCF50633_FIDX_CHG_READY                5       /* Charging completed */
132 +#define PCF50633_FIDX_PWR_PRESSED      8
133 +#define PCF50633_FIDX_RTC_SECOND       9
134 +#define PCF50633_FIDX_USB_PRESENT      10
135 +
136 +#define PCF50633_F_CHG_ENABLED (1 << PCF50633_FIDX_CHG_ENABLED)
137 +#define PCF50633_F_CHG_PRESENT (1 << PCF50633_FIDX_CHG_PRESENT)
138 +#define PCF50633_F_CHG_ERR     (1 << PCF50633_FIDX_CHG_ERR)
139 +#define PCF50633_F_CHG_PROT    (1 << PCF50633_FIDX_CHG_PROT)
140 +#define PCF50633_F_CHG_READY   (1 << PCF50633_FIDX_CHG_READY)
141 +
142 +#define PCF50633_F_CHG_MASK    0x000000fc
143 +
144 +#define PCF50633_F_PWR_PRESSED (1 << PCF50633_FIDX_PWR_PRESSED)
145 +#define PCF50633_F_RTC_SECOND  (1 << PCF50633_FIDX_RTC_SECOND)
146 +#define PCF50633_F_USB_PRESENT (1 << PCF50633_FIDX_USB_PRESENT)
147 +
148 +enum close_state {
149 +       CLOSE_STATE_NOT,
150 +       CLOSE_STATE_ALLOW = 0x2342,
151 +};
152 +
153 +enum charger_type {
154 +       CHARGER_TYPE_NONE = 0,
155 +       CHARGER_TYPE_HOSTUSB,
156 +       CHARGER_TYPE_1A
157 +};
158 +
159 +#define ADC_NOM_CHG_DETECT_1A 6
160 +#define ADC_NOM_CHG_DETECT_NONE 43
161 +
162 +#define MAX_ADC_FIFO_DEPTH 8
163 +
164 +struct pcf50633_data {
165 +       struct i2c_client client;
166 +       struct pcf50633_platform_data *pdata;
167 +       struct backlight_device *backlight;
168 +       struct mutex lock;
169 +       unsigned int flags;
170 +       unsigned int working;
171 +       struct mutex working_lock;
172 +       struct work_struct work;
173 +       struct rtc_device *rtc;
174 +       struct input_dev *input_dev;
175 +       int allow_close;
176 +       int onkey_seconds;
177 +       int irq;
178 +
179 +       int coldplug_done; /* cleared by probe, set by first work service */
180 +       int flag_bat_voltage_read; /* ipc to /sys batt voltage read func */
181 +
182 +       int charger_adc_result_raw;
183 +       enum charger_type charger_type;
184 +
185 +       /* we have a FIFO of ADC measurement requests that are used only by
186 +        * the workqueue service code after the ADC completion interrupt
187 +        */
188 +       int adc_queue_mux[MAX_ADC_FIFO_DEPTH]; /* which ADC input to use */
189 +       int adc_queue_avg[MAX_ADC_FIFO_DEPTH]; /* amount of averaging */
190 +       int adc_queue_head; /* head owned by foreground code */
191 +       int adc_queue_tail; /* tail owned by service code */
192 +
193 +#ifdef CONFIG_PM
194 +       struct {
195 +               u_int8_t int1m, int2m, int3m, int4m, int5m;
196 +               u_int8_t ooctim2;
197 +               u_int8_t autoout, autoena, automxc;
198 +               u_int8_t down1out, down1mxc;
199 +               u_int8_t down2out, down2ena;
200 +               u_int8_t memldoout, memldoena;
201 +               u_int8_t ledout, ledena, leddim;
202 +               struct {
203 +                       u_int8_t out;
204 +                       u_int8_t ena;
205 +               } ldo[__NUM_PCF50633_REGS];
206 +       } standby_regs;
207 +#endif
208 +};
209 +
210 +static struct i2c_driver pcf50633_driver;
211 +
212 +struct pcf50633_data *pcf50633_global;
213 +EXPORT_SYMBOL_GPL(pcf50633_global);
214 +
215 +static struct platform_device *pcf50633_pdev;
216 +
217 +/***********************************************************************
218 + * Low-Level routines
219 + ***********************************************************************/
220 +
221 +static int __reg_write(struct pcf50633_data *pcf, u_int8_t reg, u_int8_t val)
222 +{
223 +       return i2c_smbus_write_byte_data(&pcf->client, reg, val);
224 +}
225 +
226 +static int reg_write(struct pcf50633_data *pcf, u_int8_t reg, u_int8_t val)
227 +{
228 +       int ret;
229 +
230 +       mutex_lock(&pcf->lock);
231 +       ret = __reg_write(pcf, reg, val);
232 +       mutex_unlock(&pcf->lock);
233 +
234 +       return ret;
235 +}
236 +
237 +static int32_t __reg_read(struct pcf50633_data *pcf, u_int8_t reg)
238 +{
239 +       int32_t ret;
240 +
241 +       ret = i2c_smbus_read_byte_data(&pcf->client, reg);
242 +
243 +       return ret;
244 +}
245 +
246 +static u_int8_t reg_read(struct pcf50633_data *pcf, u_int8_t reg)
247 +{
248 +       int32_t ret;
249 +
250 +       mutex_lock(&pcf->lock);
251 +       ret = __reg_read(pcf, reg);
252 +       mutex_unlock(&pcf->lock);
253 +
254 +       return ret & 0xff;
255 +}
256 +
257 +static int reg_set_bit_mask(struct pcf50633_data *pcf,
258 +                           u_int8_t reg, u_int8_t mask, u_int8_t val)
259 +{
260 +       int ret;
261 +       u_int8_t tmp;
262 +
263 +       val &= mask;
264 +
265 +       mutex_lock(&pcf->lock);
266 +
267 +       tmp = __reg_read(pcf, reg);
268 +       tmp &= ~mask;
269 +       tmp |= val;
270 +       ret = __reg_write(pcf, reg, tmp);
271 +
272 +       mutex_unlock(&pcf->lock);
273 +
274 +       return ret;
275 +}
276 +
277 +static int reg_clear_bits(struct pcf50633_data *pcf, u_int8_t reg, u_int8_t val)
278 +{
279 +       int ret;
280 +       u_int8_t tmp;
281 +
282 +       mutex_lock(&pcf->lock);
283 +
284 +       tmp = __reg_read(pcf, reg);
285 +       tmp &= ~val;
286 +       ret = __reg_write(pcf, reg, tmp);
287 +
288 +       mutex_unlock(&pcf->lock);
289 +
290 +       return ret;
291 +}
292 +
293 +/* asynchronously setup reading one ADC channel */
294 +static void async_adc_read_setup(struct pcf50633_data *pcf,
295 +                                int channel, int avg)
296 +{
297 +       channel &= PCF50633_ADCC1_ADCMUX_MASK;
298 +
299 +       /* kill ratiometric, but enable ACCSW biasing */
300 +       __reg_write(pcf, PCF50633_REG_ADCC2, 0x00);
301 +       __reg_write(pcf, PCF50633_REG_ADCC3, 0x01);
302 +
303 +       /* start ADC conversion of selected channel */
304 +       __reg_write(pcf, PCF50633_REG_ADCC1, channel | avg |
305 +                   PCF50633_ADCC1_ADCSTART | PCF50633_ADCC1_RES_10BIT);
306 +
307 +}
308 +
309 +static u_int16_t async_adc_complete(struct pcf50633_data *pcf)
310 +{
311 +       u_int16_t ret = (__reg_read(pcf, PCF50633_REG_ADCS1) << 2) |
312 +                       (__reg_read(pcf, PCF50633_REG_ADCS3) &
313 +                                                 PCF50633_ADCS3_ADCDAT1L_MASK);
314 +
315 +       return ret;
316 +}
317 +
318 +
319 +
320 +
321 +/***********************************************************************
322 + * Voltage / ADC
323 + ***********************************************************************/
324 +
325 +static u_int8_t auto_voltage(unsigned int millivolts)
326 +{
327 +       if (millivolts < 1800)
328 +               return 0;
329 +       if (millivolts > 3800)
330 +               return 0xff;
331 +
332 +       millivolts -= 625;
333 +       return millivolts/25;
334 +}
335 +
336 +static unsigned int auto_2voltage(u_int8_t bits)
337 +{
338 +       if (bits < 0x2f)
339 +               return 0;
340 +       return 625 + (bits * 25);
341 +}
342 +
343 +static u_int8_t down_voltage(unsigned int millivolts)
344 +{
345 +       if (millivolts < 625)
346 +               return 0;
347 +       else if (millivolts > 3000)
348 +               return 0xff;
349 +
350 +       millivolts -= 625;
351 +       return millivolts/25;
352 +}
353 +
354 +static unsigned int down_2voltage(u_int8_t bits)
355 +{
356 +       return 625 + (bits*25);
357 +}
358 +
359 +static u_int8_t ldo_voltage(unsigned int millivolts)
360 +{
361 +       if (millivolts < 900)
362 +               return 0;
363 +       else if (millivolts > 3600)
364 +               return 0x1f;
365 +
366 +       millivolts -= 900;
367 +       return millivolts/100;
368 +}
369 +
370 +static unsigned int ldo_2voltage(u_int8_t bits)
371 +{
372 +       bits &= 0x1f;
373 +       return 900 + (bits * 100);
374 +}
375 +
376 +static const u_int8_t regulator_registers[__NUM_PCF50633_REGULATORS] = {
377 +       [PCF50633_REGULATOR_AUTO]       = PCF50633_REG_AUTOOUT,
378 +       [PCF50633_REGULATOR_DOWN1]      = PCF50633_REG_DOWN1OUT,
379 +       [PCF50633_REGULATOR_DOWN2]      = PCF50633_REG_DOWN2OUT,
380 +       [PCF50633_REGULATOR_MEMLDO]     = PCF50633_REG_MEMLDOOUT,
381 +       [PCF50633_REGULATOR_LDO1]       = PCF50633_REG_LDO1OUT,
382 +       [PCF50633_REGULATOR_LDO2]       = PCF50633_REG_LDO2OUT,
383 +       [PCF50633_REGULATOR_LDO3]       = PCF50633_REG_LDO3OUT,
384 +       [PCF50633_REGULATOR_LDO4]       = PCF50633_REG_LDO4OUT,
385 +       [PCF50633_REGULATOR_LDO5]       = PCF50633_REG_LDO5OUT,
386 +       [PCF50633_REGULATOR_LDO6]       = PCF50633_REG_LDO6OUT,
387 +       [PCF50633_REGULATOR_HCLDO]      = PCF50633_REG_HCLDOOUT,
388 +};
389 +
390 +int pcf50633_onoff_set(struct pcf50633_data *pcf,
391 +                      enum pcf50633_regulator_id reg, int on)
392 +{
393 +       u_int8_t addr;
394 +
395 +       if (reg >= __NUM_PCF50633_REGULATORS)
396 +               return -EINVAL;
397 +
398 +       /* the *ENA register is always one after the *OUT register */
399 +       addr = regulator_registers[reg] + 1;
400 +
401 +       if (on == 0)
402 +               reg_set_bit_mask(pcf, addr, PCF50633_REGULATOR_ON, 0);
403 +       else
404 +               reg_set_bit_mask(pcf, addr, PCF50633_REGULATOR_ON,
405 +                                PCF50633_REGULATOR_ON);
406 +
407 +       return 0;
408 +}
409 +EXPORT_SYMBOL_GPL(pcf50633_onoff_set);
410 +
411 +int pcf50633_onoff_get(struct pcf50633_data *pcf,
412 +                      enum pcf50633_regulator_id reg)
413 +{
414 +       u_int8_t val, addr;
415 +
416 +       if (reg >= __NUM_PCF50633_REGULATORS)
417 +               return -EINVAL;
418 +
419 +       /* the *ENA register is always one after the *OUT register */
420 +       addr = regulator_registers[reg] + 1;
421 +       val = reg_read(pcf, addr) & PCF50633_REGULATOR_ON;
422 +
423 +       return val;
424 +}
425 +EXPORT_SYMBOL_GPL(pcf50633_onoff_get);
426 +
427 +int pcf50633_voltage_set(struct pcf50633_data *pcf,
428 +                        enum pcf50633_regulator_id reg,
429 +                        unsigned int millivolts)
430 +{
431 +       u_int8_t volt_bits;
432 +       u_int8_t regnr;
433 +
434 +       DEBUGP("pcf=%p, reg=%d, mvolts=%d\n", pcf, reg, millivolts);
435 +
436 +       if (reg >= __NUM_PCF50633_REGULATORS)
437 +               return -EINVAL;
438 +
439 +       regnr = regulator_registers[reg];
440 +
441 +       if (millivolts > pcf->pdata->rails[reg].voltage.max)
442 +               return -EINVAL;
443 +
444 +       switch (reg) {
445 +       case PCF50633_REGULATOR_AUTO:
446 +               volt_bits = auto_voltage(millivolts);
447 +               break;
448 +       case PCF50633_REGULATOR_DOWN1:
449 +               volt_bits = down_voltage(millivolts);
450 +               break;
451 +       case PCF50633_REGULATOR_DOWN2:
452 +               volt_bits = down_voltage(millivolts);
453 +               break;
454 +       case PCF50633_REGULATOR_LDO1:
455 +       case PCF50633_REGULATOR_LDO2:
456 +       case PCF50633_REGULATOR_LDO3:
457 +       case PCF50633_REGULATOR_LDO4:
458 +       case PCF50633_REGULATOR_LDO5:
459 +       case PCF50633_REGULATOR_LDO6:
460 +       case PCF50633_REGULATOR_HCLDO:
461 +               volt_bits = ldo_voltage(millivolts);
462 +               DEBUGP("ldo_voltage(0x%x)=%u\n", millivolts, volt_bits);
463 +               break;
464 +       default:
465 +               return -EINVAL;
466 +       }
467 +
468 +       return reg_write(pcf, regnr, volt_bits);
469 +}
470 +EXPORT_SYMBOL_GPL(pcf50633_voltage_set);
471 +
472 +unsigned int pcf50633_voltage_get(struct pcf50633_data *pcf,
473 +                        enum pcf50633_regulator_id reg)
474 +{
475 +       u_int8_t volt_bits;
476 +       u_int8_t regnr;
477 +       unsigned int rc = 0;
478 +
479 +       if (reg >= __NUM_PCF50633_REGULATORS)
480 +               return -EINVAL;
481 +
482 +       regnr = regulator_registers[reg];
483 +       volt_bits = reg_read(pcf, regnr);
484 +
485 +       switch (reg) {
486 +       case PCF50633_REGULATOR_AUTO:
487 +               rc = auto_2voltage(volt_bits);
488 +               break;
489 +       case PCF50633_REGULATOR_DOWN1:
490 +               rc = down_2voltage(volt_bits);
491 +               break;
492 +       case PCF50633_REGULATOR_DOWN2:
493 +               rc = down_2voltage(volt_bits);
494 +               break;
495 +       case PCF50633_REGULATOR_LDO1:
496 +       case PCF50633_REGULATOR_LDO2:
497 +       case PCF50633_REGULATOR_LDO3:
498 +       case PCF50633_REGULATOR_LDO4:
499 +       case PCF50633_REGULATOR_LDO5:
500 +       case PCF50633_REGULATOR_LDO6:
501 +       case PCF50633_REGULATOR_HCLDO:
502 +               rc = ldo_2voltage(volt_bits);
503 +               break;
504 +       default:
505 +               return -EINVAL;
506 +       }
507 +
508 +       return rc;
509 +}
510 +EXPORT_SYMBOL_GPL(pcf50633_voltage_get);
511 +
512 +/* go into 'STANDBY' mode, i.e. power off the main CPU and peripherals */
513 +void pcf50633_go_standby(void)
514 +{
515 +       reg_set_bit_mask(pcf50633_global, PCF50633_REG_OOCSHDWN,
516 +                 PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY);
517 +}
518 +EXPORT_SYMBOL_GPL(pcf50633_go_standby);
519 +
520 +void pcf50633_gpio_set(struct pcf50633_data *pcf, enum pcf50633_gpio gpio,
521 +                       int on)
522 +{
523 +       u_int8_t reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
524 +
525 +       if (on)
526 +               reg_set_bit_mask(pcf, reg, 0x0f, 0x07);
527 +       else
528 +               reg_set_bit_mask(pcf, reg, 0x0f, 0x00);
529 +}
530 +EXPORT_SYMBOL_GPL(pcf50633_gpio_set);
531 +
532 +int pcf50633_gpio_get(struct pcf50633_data *pcf, enum pcf50633_gpio gpio)
533 +{
534 +       u_int8_t reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
535 +       u_int8_t val = reg_read(pcf, reg) & 0x0f;
536 +
537 +       if (val == PCF50633_GPOCFG_GPOSEL_1 ||
538 +           val == (PCF50633_GPOCFG_GPOSEL_0|PCF50633_GPOCFG_GPOSEL_INVERSE))
539 +               return 1;
540 +
541 +       return 0;
542 +}
543 +EXPORT_SYMBOL_GPL(pcf50633_gpio_get);
544 +
545 +static int interpret_charger_type_from_adc(struct pcf50633_data *pcf,
546 +                                          int sample)
547 +{
548 +       /* 1A capable charger? */
549 +
550 +       if (sample < ((ADC_NOM_CHG_DETECT_NONE + ADC_NOM_CHG_DETECT_1A) / 2))
551 +               return CHARGER_TYPE_1A;
552 +
553 +       /* well then, nothing in the USB hole, or USB host / unk adapter */
554 +
555 +       if (pcf->flags & PCF50633_F_USB_PRESENT) /* ooh power is in there */
556 +               return CHARGER_TYPE_HOSTUSB; /* HOSTUSB is the catchall */
557 +
558 +       return CHARGER_TYPE_NONE; /* no really -- nothing in there */
559 +}
560 +
561 +
562 +
563 +static void configure_pmu_for_charger(struct pcf50633_data *pcf,
564 +                                     enum charger_type type)
565 +{
566 +       switch (type) {
567 +       case CHARGER_TYPE_NONE:
568 +               __reg_write(pcf, PCF50633_REG_MBCC7,
569 +                                                   PCF50633_MBCC7_USB_SUSPEND);
570 +               break;
571 +       /*
572 +        * the PCF50633 has a feature that it will supply only excess current
573 +        * from the charger that is not used to power the device.  So this
574 +        * 500mA setting is "up to 500mA" according to that.
575 +        */
576 +       case CHARGER_TYPE_HOSTUSB:
577 +               __reg_write(pcf, PCF50633_REG_MBCC7, PCF50633_MBCC7_USB_500mA);
578 +               break;
579 +       case CHARGER_TYPE_1A:
580 +               __reg_write(pcf, PCF50633_REG_MBCC7, PCF50633_MBCC7_USB_1000mA);
581 +               break;
582 +       }
583 +}
584 +
585 +static void trigger_next_adc_job_if_any(struct pcf50633_data *pcf)
586 +{
587 +       if (pcf->adc_queue_head == pcf->adc_queue_tail)
588 +               return;
589 +       async_adc_read_setup(pcf,
590 +                            pcf->adc_queue_mux[pcf->adc_queue_tail],
591 +                            pcf->adc_queue_avg[pcf->adc_queue_tail]);
592 +}
593 +
594 +static void add_request_to_adc_queue(struct pcf50633_data *pcf,
595 +                                    int mux, int avg)
596 +{
597 +       int old_head = pcf->adc_queue_head;
598 +       pcf->adc_queue_mux[pcf->adc_queue_head] = mux;
599 +       pcf->adc_queue_avg[pcf->adc_queue_head] = avg;
600 +
601 +       pcf->adc_queue_head = (pcf->adc_queue_head + 1) &
602 +                             (MAX_ADC_FIFO_DEPTH - 1);
603 +
604 +       /* it was idle before we just added this?  we need to kick it then */
605 +       if (old_head == pcf->adc_queue_tail)
606 +               trigger_next_adc_job_if_any(pcf);
607 +}
608 +
609 +static void pcf50633_work(struct work_struct *work)
610 +{
611 +       struct pcf50633_data *pcf =
612 +                       container_of(work, struct pcf50633_data, work);
613 +       u_int8_t pcfirq[5];
614 +       int ret;
615 +       int tail;
616 +
617 +       mutex_lock(&pcf->working_lock);
618 +       pcf->working = 1;
619 +       /*
620 +        * datasheet says we have to read the five IRQ
621 +        * status regs in one transaction
622 +        */
623 +       ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50633_REG_INT1, 5,
624 +                                           pcfirq);
625 +       if (ret != 5)
626 +               DEBUGP("Oh crap PMU IRQ register read failed %d\n", ret);
627 +
628 +       if (!pcf->coldplug_done) {
629 +               DEBUGP("PMU Coldplug init\n");
630 +
631 +               /* we used SECOND to kick ourselves started -- turn it off */
632 +               pcfirq[0] &= ~PCF50633_INT1_SECOND;
633 +               reg_set_bit_mask(pcf, PCF50633_REG_INT1M,
634 +                                       PCF50633_INT1_SECOND,
635 +                                       PCF50633_INT1_SECOND);
636 +
637 +               /* coldplug the USB if present */
638 +               if ((__reg_read(pcf, PCF50633_REG_MBCS1) &
639 +                   (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) ==
640 +                   (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) {
641 +                       DEBUGPC("COLD USBINS\n");
642 +                       input_report_key(pcf->input_dev, KEY_POWER2, 1);
643 +                       apm_queue_event(APM_POWER_STATUS_CHANGE);
644 +                       pcf->flags |= PCF50633_F_USB_PRESENT;
645 +                       if (pcf->pdata->cb)
646 +                               pcf->pdata->cb(&pcf->client.dev,
647 +                                       PCF50633_FEAT_MBC, PMU_EVT_USB_INSERT);
648 +               }
649 +
650 +               /* figure out our initial charging stance */
651 +               add_request_to_adc_queue(pcf, PCF50633_ADCC1_MUX_ADCIN1,
652 +                                             PCF50633_ADCC1_AVERAGE_16);
653 +
654 +               pcf->coldplug_done = 1;
655 +       }
656 +
657 +       DEBUGP("INT1=0x%02x INT2=0x%02x INT3=0x%02x INT4=0x%02x INT5=0x%02x\n",
658 +               pcfirq[0], pcfirq[1], pcfirq[2], pcfirq[3], pcfirq[4]);
659 +
660 +       if (pcfirq[0] & PCF50633_INT1_ADPINS) {
661 +               /* Charger inserted */
662 +               DEBUGPC("ADPINS ");
663 +               input_report_key(pcf->input_dev, KEY_BATTERY, 1);
664 +               apm_queue_event(APM_POWER_STATUS_CHANGE);
665 +               pcf->flags |= PCF50633_F_CHG_PRESENT;
666 +               if (pcf->pdata->cb)
667 +                       pcf->pdata->cb(&pcf->client.dev,
668 +                                      PCF50633_FEAT_MBC, PMU_EVT_INSERT);
669 +               /* FIXME: signal this to userspace */
670 +               //kobject_uevent( ,KOBJ_ADD);
671 +       }
672 +       if (pcfirq[0] & PCF50633_INT1_ADPREM) {
673 +               /* Charger removed */
674 +               DEBUGPC("ADPREM ");
675 +               input_report_key(pcf->input_dev, KEY_BATTERY, 0);
676 +               apm_queue_event(APM_POWER_STATUS_CHANGE);
677 +               pcf->flags &= ~PCF50633_F_CHG_PRESENT;
678 +               if (pcf->pdata->cb)
679 +                       pcf->pdata->cb(&pcf->client.dev,
680 +                                      PCF50633_FEAT_MBC, PMU_EVT_REMOVE);
681 +               /* FIXME: signal this to userspace */
682 +               //kobject_uevent( ,KOBJ_ADD);
683 +       }
684 +       if (pcfirq[0] & PCF50633_INT1_USBINS) {
685 +               DEBUGPC("USBINS ");
686 +               input_report_key(pcf->input_dev, KEY_POWER2, 1);
687 +               apm_queue_event(APM_POWER_STATUS_CHANGE);
688 +               pcf->flags |= PCF50633_F_USB_PRESENT;
689 +               if (pcf->pdata->cb)
690 +                       pcf->pdata->cb(&pcf->client.dev,
691 +                                      PCF50633_FEAT_MBC, PMU_EVT_USB_INSERT);
692 +               /* completion irq will figure out our charging stance */
693 +               add_request_to_adc_queue(pcf, PCF50633_ADCC1_MUX_ADCIN1,
694 +                                    PCF50633_ADCC1_AVERAGE_16);
695 +       }
696 +       if (pcfirq[0] & PCF50633_INT1_USBREM) {
697 +               DEBUGPC("USBREM ");
698 +               /* only deal if we had understood it was in */
699 +               if (pcf->flags & PCF50633_F_USB_PRESENT) {
700 +                       input_report_key(pcf->input_dev, KEY_POWER2, 0);
701 +                       apm_queue_event(APM_POWER_STATUS_CHANGE);
702 +                       pcf->flags &= ~PCF50633_F_USB_PRESENT;
703 +                       if (pcf->pdata->cb)
704 +                               pcf->pdata->cb(&pcf->client.dev,
705 +                                       PCF50633_FEAT_MBC, PMU_EVT_USB_REMOVE);
706 +                       /* completion irq will figure out our charging stance */
707 +                       add_request_to_adc_queue(pcf, PCF50633_ADCC1_MUX_ADCIN1,
708 +                                       PCF50633_ADCC1_AVERAGE_16);
709 +               }
710 +       }
711 +       if (pcfirq[0] & PCF50633_INT1_ALARM) {
712 +               DEBUGPC("ALARM ");
713 +               if (pcf->pdata->used_features & PCF50633_FEAT_RTC)
714 +                       rtc_update_irq(pcf->rtc, 1, RTC_AF | RTC_IRQF);
715 +       }
716 +       if (pcfirq[0] & PCF50633_INT1_SECOND) {
717 +               DEBUGPC("SECOND ");
718 +               if (pcf->flags & PCF50633_F_RTC_SECOND)
719 +                       rtc_update_irq(pcf->rtc, 1, RTC_PF | RTC_IRQF);
720 +
721 +               if (pcf->onkey_seconds >= 0 &&
722 +                   pcf->flags & PCF50633_F_PWR_PRESSED) {
723 +                       DEBUGP("ONKEY_SECONDS(%u, OOCSTAT=0x%02x) ",
724 +                               pcf->onkey_seconds,
725 +                               reg_read(pcf, PCF50633_REG_OOCSTAT));
726 +                       pcf->onkey_seconds++;
727 +                       if (pcf->onkey_seconds >=
728 +                           pcf->pdata->onkey_seconds_sig_init) {
729 +                               /* Ask init to do 'ctrlaltdel' */
730 +                               DEBUGPC("SIGINT(init) ");
731 +                               kill_proc(1, SIGINT, 1);
732 +                               /* FIXME: what if userspace doesn't shut down? */
733 +                       }
734 +                       if (pcf->onkey_seconds >=
735 +                               pcf->pdata->onkey_seconds_shutdown) {
736 +                               DEBUGPC("Power Off ");
737 +                               pcf50633_go_standby();
738 +                       }
739 +               }
740 +       }
741 +
742 +       if (pcfirq[1] & PCF50633_INT2_ONKEYF) {
743 +               /* ONKEY falling edge (start of button press) */
744 +               DEBUGPC("ONKEYF ");
745 +               pcf->flags |= PCF50633_F_PWR_PRESSED;
746 +               input_report_key(pcf->input_dev, KEY_POWER, 1);
747 +       }
748 +       if (pcfirq[1] & PCF50633_INT2_ONKEYR) {
749 +               /* ONKEY rising edge (end of button press) */
750 +               DEBUGPC("ONKEYR ");
751 +               pcf->flags &= ~PCF50633_F_PWR_PRESSED;
752 +               pcf->onkey_seconds = -1;
753 +               input_report_key(pcf->input_dev, KEY_POWER, 0);
754 +               /* disable SECOND interrupt in case RTC didn't
755 +                * request it */
756 +               if (!(pcf->flags & PCF50633_F_RTC_SECOND))
757 +                       reg_set_bit_mask(pcf, PCF50633_REG_INT1M,
758 +                                        PCF50633_INT1_SECOND,
759 +                                        PCF50633_INT1_SECOND);
760 +       }
761 +       /* FIXME: we don't use EXTON1/2/3. thats why we skip it */
762 +
763 +       if (pcfirq[2] & PCF50633_INT3_BATFULL) {
764 +               DEBUGPC("BATFULL ");
765 +               /* FIXME: signal this to userspace */
766 +       }
767 +       if (pcfirq[2] & PCF50633_INT3_CHGHALT) {
768 +               DEBUGPC("CHGHALT ");
769 +               /*
770 +                * this is really "battery not pulling current" -- it can
771 +                * appear with no battery attached
772 +                */
773 +               /* FIXME: signal this to userspace */
774 +       }
775 +       if (pcfirq[2] & PCF50633_INT3_THLIMON) {
776 +               DEBUGPC("THLIMON ");
777 +               pcf->flags |= PCF50633_F_CHG_PROT;
778 +               /* FIXME: signal this to userspace */
779 +       }
780 +       if (pcfirq[2] & PCF50633_INT3_THLIMOFF) {
781 +               DEBUGPC("THLIMOFF ");
782 +               pcf->flags &= ~PCF50633_F_CHG_PROT;
783 +               /* FIXME: signal this to userspace */
784 +       }
785 +       if (pcfirq[2] & PCF50633_INT3_USBLIMON) {
786 +               DEBUGPC("USBLIMON ");
787 +               /* FIXME: signal this to userspace */
788 +       }
789 +       if (pcfirq[2] & PCF50633_INT3_USBLIMOFF) {
790 +               DEBUGPC("USBLIMOFF ");
791 +               /* FIXME: signal this to userspace */
792 +       }
793 +       if (pcfirq[2] & PCF50633_INT3_ADCRDY) {
794 +               /* ADC result ready */
795 +               DEBUGPC("ADCRDY ");
796 +               tail = pcf->adc_queue_tail;
797 +               pcf->adc_queue_tail = (pcf->adc_queue_tail + 1) &
798 +                                     (MAX_ADC_FIFO_DEPTH - 1);
799 +
800 +               switch (pcf->adc_queue_mux[tail]) {
801 +               case PCF50633_ADCC1_MUX_BATSNS_RES: /* battery voltage */
802 +                       pcf->flag_bat_voltage_read =
803 +                                                 async_adc_complete(pcf);
804 +                       break;
805 +               case PCF50633_ADCC1_MUX_ADCIN1: /* charger type */
806 +                       pcf->charger_adc_result_raw = async_adc_complete(pcf);
807 +                       pcf->charger_type = interpret_charger_type_from_adc(
808 +                                            pcf, pcf->charger_adc_result_raw);
809 +                       configure_pmu_for_charger(pcf, pcf->charger_type);
810 +                       break;
811 +               default:
812 +                       async_adc_complete(pcf);
813 +                       break;
814 +               }
815 +               trigger_next_adc_job_if_any(pcf);
816 +       }
817 +       if (pcfirq[2] & PCF50633_INT3_ONKEY1S) {
818 +               /* ONKEY pressed for more than 1 second */
819 +               pcf->onkey_seconds = 0;
820 +               DEBUGPC("ONKEY1S ");
821 +               /* Tell PMU we are taking care of this */
822 +               reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
823 +                                PCF50633_OOCSHDWN_TOTRST,
824 +                                PCF50633_OOCSHDWN_TOTRST);
825 +               /* enable SECOND interrupt (hz tick) */
826 +               reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND);
827 +       }
828 +
829 +       if (pcfirq[3] & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) {
830 +               /* Really low battery voltage, we have 8 seconds left */
831 +               DEBUGPC("LOWBAT ");
832 +               apm_queue_event(APM_LOW_BATTERY);
833 +               DEBUGPC("SIGPWR(init) ");
834 +               kill_proc(1, SIGPWR, 1);
835 +               /* Tell PMU we are taking care of this */
836 +               reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
837 +                                PCF50633_OOCSHDWN_TOTRST,
838 +                                PCF50633_OOCSHDWN_TOTRST);
839 +       }
840 +       if (pcfirq[3] & PCF50633_INT4_HIGHTMP) {
841 +               /* High temperature */
842 +               DEBUGPC("HIGHTMP ");
843 +               apm_queue_event(APM_CRITICAL_SUSPEND);
844 +       }
845 +       if (pcfirq[3] & PCF50633_INT4_AUTOPWRFAIL) {
846 +               DEBUGPC("PCF50633_INT4_AUTOPWRFAIL ");
847 +               /* FIXME: deal with this */
848 +       }
849 +       if (pcfirq[3] & PCF50633_INT4_DWN1PWRFAIL) {
850 +               DEBUGPC("PCF50633_INT4_DWN1PWRFAIL ");
851 +               /* FIXME: deal with this */
852 +       }
853 +       if (pcfirq[3] & PCF50633_INT4_DWN2PWRFAIL) {
854 +               DEBUGPC("PCF50633_INT4_DWN2PWRFAIL ");
855 +               /* FIXME: deal with this */
856 +       }
857 +       if (pcfirq[3] & PCF50633_INT4_LEDPWRFAIL) {
858 +               DEBUGPC("PCF50633_INT4_LEDPWRFAIL ");
859 +               /* FIXME: deal with this */
860 +       }
861 +       if (pcfirq[3] & PCF50633_INT4_LEDOVP) {
862 +               DEBUGPC("PCF50633_INT4_LEDOVP ");
863 +               /* FIXME: deal with this */
864 +       }
865 +
866 +       DEBUGPC("\n");
867 +
868 +       pcf->working = 0;
869 +       input_sync(pcf->input_dev);
870 +       put_device(&pcf->client.dev);
871 +       mutex_unlock(&pcf->working_lock);
872 +}
873 +
874 +static irqreturn_t pcf50633_irq(int irq, void *_pcf)
875 +{
876 +       struct pcf50633_data *pcf = _pcf;
877 +
878 +       DEBUGP("entering(irq=%u, pcf=%p): scheduling work\n", irq, _pcf);
879 +
880 +       get_device(&pcf->client.dev);
881 +       if (!schedule_work(&pcf->work) && !pcf->working)
882 +               dev_dbg(&pcf->client.dev, "work item may be lost\n");
883 +
884 +       return IRQ_HANDLED;
885 +}
886 +
887 +static u_int16_t adc_to_batt_millivolts(u_int16_t adc)
888 +{
889 +       u_int16_t mvolts;
890 +
891 +       mvolts = (adc * 6000) / 1024;
892 +
893 +       return mvolts;
894 +}
895 +
896 +#define BATTVOLT_SCALE_START 2800
897 +#define BATTVOLT_SCALE_END 4200
898 +#define BATTVOLT_SCALE_DIVIDER ((BATTVOLT_SCALE_END - BATTVOLT_SCALE_START)/100)
899 +
900 +static u_int8_t battvolt_scale(u_int16_t battvolt)
901 +{
902 +       /* FIXME: this linear scale is completely bogus */
903 +       u_int16_t battvolt_relative = battvolt - BATTVOLT_SCALE_START;
904 +       unsigned int percent = battvolt_relative / BATTVOLT_SCALE_DIVIDER;
905 +
906 +       return percent;
907 +}
908 +
909 +u_int16_t pcf50633_battvolt(struct pcf50633_data *pcf)
910 +{
911 +       int count = 10;
912 +
913 +       pcf->flag_bat_voltage_read = -1;
914 +       add_request_to_adc_queue(pcf, PCF50633_ADCC1_MUX_BATSNS_RES,
915 +                                     PCF50633_ADCC1_AVERAGE_16);
916 +
917 +       while ((count--) && (pcf->flag_bat_voltage_read < 0))
918 +               msleep(1);
919 +
920 +       if (count < 0) { /* timeout somehow */
921 +               DEBUGPC("pcf50633_battvolt timeout :-(\n");
922 +               return -1;
923 +       }
924 +
925 +       return adc_to_batt_millivolts(pcf->flag_bat_voltage_read);
926 +}
927 +EXPORT_SYMBOL_GPL(pcf50633_battvolt);
928 +
929 +static ssize_t show_battvolt(struct device *dev, struct device_attribute *attr,
930 +                            char *buf)
931 +{
932 +       struct i2c_client *client = to_i2c_client(dev);
933 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
934 +
935 +       return sprintf(buf, "%u\n", pcf50633_battvolt(pcf));
936 +}
937 +static DEVICE_ATTR(battvolt, S_IRUGO | S_IWUSR, show_battvolt, NULL);
938 +
939 +static int reg_id_by_name(const char *name)
940 +{
941 +       int reg_id;
942 +
943 +       if (!strcmp(name, "voltage_auto"))
944 +               reg_id = PCF50633_REGULATOR_AUTO;
945 +       else if (!strcmp(name, "voltage_down1"))
946 +               reg_id = PCF50633_REGULATOR_DOWN1;
947 +       else if (!strcmp(name, "voltage_down2"))
948 +               reg_id = PCF50633_REGULATOR_DOWN2;
949 +       else if (!strcmp(name, "voltage_memldo"))
950 +               reg_id = PCF50633_REGULATOR_MEMLDO;
951 +       else if (!strcmp(name, "voltage_ldo1"))
952 +               reg_id = PCF50633_REGULATOR_LDO1;
953 +       else if (!strcmp(name, "voltage_ldo2"))
954 +               reg_id = PCF50633_REGULATOR_LDO2;
955 +       else if (!strcmp(name, "voltage_ldo3"))
956 +               reg_id = PCF50633_REGULATOR_LDO3;
957 +       else if (!strcmp(name, "voltage_ldo4"))
958 +               reg_id = PCF50633_REGULATOR_LDO4;
959 +       else if (!strcmp(name, "voltage_ldo5"))
960 +               reg_id = PCF50633_REGULATOR_LDO5;
961 +       else if (!strcmp(name, "voltage_ldo6"))
962 +               reg_id = PCF50633_REGULATOR_LDO6;
963 +       else if (!strcmp(name, "voltage_hcldo"))
964 +               reg_id = PCF50633_REGULATOR_HCLDO;
965 +       else
966 +               reg_id = -1;
967 +
968 +       return reg_id;
969 +}
970 +
971 +static ssize_t show_vreg(struct device *dev, struct device_attribute *attr,
972 +                        char *buf)
973 +{
974 +       struct i2c_client *client = to_i2c_client(dev);
975 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
976 +       unsigned int reg_id;
977 +
978 +       reg_id = reg_id_by_name(attr->attr.name);
979 +       if (reg_id < 0)
980 +               return 0;
981 +
982 +       if (pcf50633_onoff_get(pcf, reg_id) > 0)
983 +               return sprintf(buf, "%u\n", pcf50633_voltage_get(pcf, reg_id));
984 +       else
985 +               return strlcpy(buf, "0\n", PAGE_SIZE);
986 +}
987 +
988 +static ssize_t set_vreg(struct device *dev, struct device_attribute *attr,
989 +                       const char *buf, size_t count)
990 +{
991 +       struct i2c_client *client = to_i2c_client(dev);
992 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
993 +       unsigned long mvolts = simple_strtoul(buf, NULL, 10);
994 +       unsigned int reg_id;
995 +
996 +       reg_id = reg_id_by_name(attr->attr.name);
997 +       if (reg_id < 0)
998 +               return -EIO;
999 +
1000 +       DEBUGP("attempting to set %s(%d) to %lu mvolts\n", attr->attr.name,
1001 +               reg_id, mvolts);
1002 +
1003 +       if (mvolts == 0) {
1004 +               pcf50633_onoff_set(pcf, reg_id, 0);
1005 +       } else {
1006 +               if (pcf50633_voltage_set(pcf, reg_id, mvolts) < 0) {
1007 +                       dev_warn(dev, "refusing to set %s(%d) to %lu mvolts "
1008 +                                "(max=%u)\n", attr->attr.name, reg_id, mvolts,
1009 +                                pcf->pdata->rails[reg_id].voltage.max);
1010 +                       return -EINVAL;
1011 +               }
1012 +               pcf50633_onoff_set(pcf, reg_id, 1);
1013 +       }
1014 +
1015 +       return count;
1016 +}
1017 +
1018 +static DEVICE_ATTR(voltage_auto, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1019 +static DEVICE_ATTR(voltage_down1, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1020 +static DEVICE_ATTR(voltage_down2, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1021 +static DEVICE_ATTR(voltage_memldo, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1022 +static DEVICE_ATTR(voltage_ldo1, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1023 +static DEVICE_ATTR(voltage_ldo2, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1024 +static DEVICE_ATTR(voltage_ldo3, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1025 +static DEVICE_ATTR(voltage_ldo4, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1026 +static DEVICE_ATTR(voltage_ldo5, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1027 +static DEVICE_ATTR(voltage_ldo6, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1028 +static DEVICE_ATTR(voltage_hcldo, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
1029 +
1030 +/***********************************************************************
1031 + * Charger Control
1032 + ***********************************************************************/
1033 +
1034 +/* Set maximum USB current limit */
1035 +void pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma)
1036 +{
1037 +       u_int8_t bits;
1038 +
1039 +       dev_dbg(&pcf->client.dev, "setting usb current limit to %d ma", ma);
1040 +
1041 +       if (ma >= 1000)
1042 +               bits = PCF50633_MBCC7_USB_1000mA;
1043 +       else if (ma >= 500)
1044 +               bits = PCF50633_MBCC7_USB_500mA;
1045 +       else if (ma >= 100)
1046 +               bits = PCF50633_MBCC7_USB_100mA;
1047 +       else
1048 +               bits = PCF50633_MBCC7_USB_SUSPEND;
1049 +
1050 +       reg_set_bit_mask(pcf, PCF50633_REG_MBCC7, PCF56033_MBCC7_USB_MASK,
1051 +                        bits);
1052 +}
1053 +EXPORT_SYMBOL_GPL(pcf50633_usb_curlim_set);
1054 +
1055 +static ssize_t show_usblim(struct device *dev, struct device_attribute *attr,
1056 +                          char *buf)
1057 +{
1058 +       struct i2c_client *client = to_i2c_client(dev);
1059 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1060 +       u_int8_t usblim = reg_read(pcf, PCF50633_REG_MBCC7) &
1061 +                                               PCF56033_MBCC7_USB_MASK;
1062 +       unsigned int ma;
1063 +
1064 +       if (usblim == PCF50633_MBCC7_USB_1000mA)
1065 +               ma = 1000;
1066 +       else if (usblim == PCF50633_MBCC7_USB_500mA)
1067 +               ma = 500;
1068 +       else if (usblim == PCF50633_MBCC7_USB_100mA)
1069 +               ma = 100;
1070 +       else
1071 +               ma = 0;
1072 +
1073 +       return sprintf(buf, "%u\n", ma);
1074 +}
1075 +static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, NULL);
1076 +
1077 +/* Enable/disable charging */
1078 +void pcf50633_charge_enable(struct pcf50633_data *pcf, int on)
1079 +{
1080 +       u_int8_t bits;
1081 +
1082 +       if (!(pcf->pdata->used_features & PCF50633_FEAT_MBC))
1083 +               return;
1084 +
1085 +       if (on) {
1086 +               pcf->flags |= PCF50633_F_CHG_ENABLED;
1087 +               bits = PCF50633_MBCC1_CHGENA;
1088 +       } else {
1089 +               pcf->flags &= ~PCF50633_F_CHG_ENABLED;
1090 +               bits = 0;
1091 +       }
1092 +       reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA,
1093 +                        bits);
1094 +}
1095 +EXPORT_SYMBOL_GPL(pcf50633_charge_enable);
1096 +
1097 +#if 0
1098 +#define ONE                    1000000
1099 +static u_int16_t adc_to_rntc(struct pcf50633_data *pcf, u_int16_t adc)
1100 +{
1101 +       u_int32_t r_batt = (adc * pcf->pdata->r_fix_batt) / (1023 - adc);
1102 +       u_int16_t r_ntc;
1103 +
1104 +       /* The battery NTC has a parallell 10kOhms resistor */
1105 +       r_ntc = ONE / ((ONE/r_batt) - (ONE/pcf->pdata->r_fix_batt_par));
1106 +
1107 +       return r_ntc;
1108 +}
1109 +#endif
1110 +static ssize_t show_battemp(struct device *dev, struct device_attribute *attr,
1111 +                           char *buf)
1112 +{
1113 +       return sprintf(buf, "\n");
1114 +}
1115 +static DEVICE_ATTR(battemp, S_IRUGO | S_IWUSR, show_battemp, NULL);
1116 +#if 0
1117 +static u_int16_t adc_to_chg_milliamps(struct pcf50633_data *pcf,
1118 +                                            u_int16_t adc_adcin1,
1119 +                                            u_int16_t adc_batvolt)
1120 +{
1121 +       u_int32_t res = ((adc_adcin1 - adc_batvolt) * 6000);
1122 +       return res / (pcf->pdata->r_sense_milli * 1024 / 1000);
1123 +}
1124 +#endif
1125 +static ssize_t show_chgcur(struct device *dev, struct device_attribute *attr,
1126 +                          char *buf)
1127 +{
1128 +       return sprintf(buf, "\n");
1129 +}
1130 +static DEVICE_ATTR(chgcur, S_IRUGO | S_IWUSR, show_chgcur, NULL);
1131 +
1132 +static const char *chgmode_names[] = {
1133 +       [PCF50633_MBCS2_MBC_PLAY]               = "play-only",
1134 +       [PCF50633_MBCS2_MBC_USB_PRE]            = "pre",
1135 +       [PCF50633_MBCS2_MBC_ADP_PRE]            = "pre",
1136 +       [PCF50633_MBCS2_MBC_USB_PRE_WAIT]       = "pre-wait",
1137 +       [PCF50633_MBCS2_MBC_ADP_PRE_WAIT]       = "pre-wait",
1138 +       [PCF50633_MBCS2_MBC_USB_FAST]           = "fast",
1139 +       [PCF50633_MBCS2_MBC_ADP_FAST]           = "fast",
1140 +       [PCF50633_MBCS2_MBC_USB_FAST_WAIT]      = "fast-wait",
1141 +       [PCF50633_MBCS2_MBC_ADP_FAST_WAIT]      = "fast-wait",
1142 +       [PCF50633_MBCS2_MBC_ADP_FAST_WAIT]      = "bat-full",
1143 +};
1144 +
1145 +static ssize_t show_chgmode(struct device *dev, struct device_attribute *attr,
1146 +                           char *buf)
1147 +{
1148 +       struct i2c_client *client = to_i2c_client(dev);
1149 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1150 +       u_int8_t mbcs2 = reg_read(pcf, PCF50633_REG_MBCS2);
1151 +       u_int8_t chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
1152 +
1153 +       return sprintf(buf, "%s\n", chgmode_names[chgmod]);
1154 +}
1155 +
1156 +static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr,
1157 +                          const char *buf, size_t count)
1158 +{
1159 +       struct i2c_client *client = to_i2c_client(dev);
1160 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1161 +
1162 +       /* As opposed to the PCF50606, we can only enable or disable
1163 +        * charging and not directly jump into a certain mode! */
1164 +
1165 +       if (!strcmp(buf, "0\n"))
1166 +               pcf50633_charge_enable(pcf, 0);
1167 +       else
1168 +               pcf50633_charge_enable(pcf, 1);
1169 +
1170 +       return count;
1171 +}
1172 +
1173 +static DEVICE_ATTR(chgmode, S_IRUGO | S_IWUSR, show_chgmode, set_chgmode);
1174 +
1175 +static const char *chgstate_names[] = {
1176 +       [PCF50633_FIDX_CHG_ENABLED]             = "enabled",
1177 +       [PCF50633_FIDX_CHG_PRESENT]             = "charger_present",
1178 +       [PCF50633_FIDX_USB_PRESENT]             = "usb_present",
1179 +       [PCF50633_FIDX_CHG_ERR]                 = "error",
1180 +       [PCF50633_FIDX_CHG_PROT]                = "protection",
1181 +       [PCF50633_FIDX_CHG_READY]               = "ready",
1182 +};
1183 +
1184 +static ssize_t show_chgstate(struct device *dev, struct device_attribute *attr,
1185 +                           char *buf)
1186 +{
1187 +       struct i2c_client *client = to_i2c_client(dev);
1188 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1189 +
1190 +       char *b = buf;
1191 +       int i;
1192 +
1193 +       for (i = 0; i < 32; i++)
1194 +               if (pcf->flags & (1 << i) && i < ARRAY_SIZE(chgstate_names))
1195 +                       b += sprintf(b, "%s ", chgstate_names[i]);
1196 +
1197 +       if (b > buf)
1198 +               b += sprintf(b, "\n");
1199 +
1200 +       return b - buf;
1201 +}
1202 +static DEVICE_ATTR(chgstate, S_IRUGO | S_IWUSR, show_chgstate, NULL);
1203 +
1204 +/***********************************************************************
1205 + * APM emulation
1206 + ***********************************************************************/
1207 +
1208 +extern void (*apm_get_power_status)(struct apm_power_info *);
1209 +
1210 +static void pcf50633_get_power_status(struct apm_power_info *info)
1211 +{
1212 +        struct pcf50633_data *pcf = pcf50633_global;
1213 +       u_int8_t chgmod = reg_read(pcf, PCF50633_REG_MBCS2) &
1214 +                                  PCF50633_MBCS2_MBC_MASK;
1215 +
1216 +       u_int16_t battvolt = pcf50633_battvolt(pcf);
1217 +
1218 +       if (reg_read(pcf, PCF50633_REG_MBCS1) &
1219 +                       (PCF50633_MBCS1_USBPRES|PCF50633_MBCS1_ADAPTPRES))
1220 +               info->ac_line_status = APM_AC_ONLINE;
1221 +       else
1222 +               info->ac_line_status = APM_AC_OFFLINE;
1223 +
1224 +       switch (chgmod) {
1225 +       case PCF50633_MBCS2_MBC_PLAY:
1226 +       case PCF50633_MBCS2_MBC_USB_PRE:
1227 +       case PCF50633_MBCS2_MBC_USB_PRE_WAIT:
1228 +       case PCF50633_MBCS2_MBC_USB_FAST_WAIT:
1229 +       case PCF50633_MBCS2_MBC_ADP_PRE:
1230 +       case PCF50633_MBCS2_MBC_ADP_PRE_WAIT:
1231 +       case PCF50633_MBCS2_MBC_ADP_FAST_WAIT:
1232 +       case PCF50633_MBCS2_MBC_BAT_FULL:
1233 +       case PCF50633_MBCS2_MBC_HALT:
1234 +               info->battery_life = battvolt_scale(battvolt);
1235 +               break;
1236 +       case PCF50633_MBCS2_MBC_USB_FAST:
1237 +       case PCF50633_MBCS2_MBC_ADP_FAST:
1238 +               info->battery_status = APM_BATTERY_STATUS_CHARGING;
1239 +               info->battery_flag = APM_BATTERY_FLAG_CHARGING;
1240 +       default:
1241 +               break;
1242 +       }
1243 +}
1244 +
1245 +/***********************************************************************
1246 + * RTC
1247 + ***********************************************************************/
1248 +
1249 +struct pcf50633_time {
1250 +       u_int8_t sec;
1251 +       u_int8_t min;
1252 +       u_int8_t hour;
1253 +       u_int8_t wkday;
1254 +       u_int8_t day;
1255 +       u_int8_t month;
1256 +       u_int8_t year;
1257 +};
1258 +
1259 +static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf)
1260 +{
1261 +       rtc->tm_sec = BCD2BIN(pcf->sec);
1262 +       rtc->tm_min = BCD2BIN(pcf->min);
1263 +       rtc->tm_hour = BCD2BIN(pcf->hour);
1264 +       rtc->tm_wday = BCD2BIN(pcf->wkday);
1265 +       rtc->tm_mday = BCD2BIN(pcf->day);
1266 +       rtc->tm_mon = BCD2BIN(pcf->month);
1267 +       rtc->tm_year = BCD2BIN(pcf->year) + 100;
1268 +}
1269 +
1270 +static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc)
1271 +{
1272 +       pcf->sec = BIN2BCD(rtc->tm_sec);
1273 +       pcf->min = BIN2BCD(rtc->tm_min);
1274 +       pcf->hour = BIN2BCD(rtc->tm_hour);
1275 +       pcf->wkday = BIN2BCD(rtc->tm_wday);
1276 +       pcf->day = BIN2BCD(rtc->tm_mday);
1277 +       pcf->month = BIN2BCD(rtc->tm_mon);
1278 +       pcf->year = BIN2BCD(rtc->tm_year - 100);
1279 +}
1280 +
1281 +static int pcf50633_rtc_ioctl(struct device *dev, unsigned int cmd,
1282 +                             unsigned long arg)
1283 +{
1284 +       struct i2c_client *client = to_i2c_client(dev);
1285 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1286 +       switch (cmd) {
1287 +       case RTC_PIE_OFF:
1288 +               /* disable periodic interrupt (hz tick) */
1289 +               pcf->flags &= ~PCF50633_F_RTC_SECOND;
1290 +               reg_set_bit_mask(pcf, PCF50633_REG_INT1M,
1291 +                                PCF50633_INT1_SECOND, PCF50633_INT1_SECOND);
1292 +               return 0;
1293 +       case RTC_PIE_ON:
1294 +               /* ensable periodic interrupt (hz tick) */
1295 +               pcf->flags |= PCF50633_F_RTC_SECOND;
1296 +               reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND);
1297 +               return 0;
1298 +       }
1299 +       return -ENOIOCTLCMD;
1300 +}
1301 +
1302 +static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
1303 +{
1304 +       struct i2c_client *client = to_i2c_client(dev);
1305 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1306 +       struct pcf50633_time pcf_tm;
1307 +
1308 +       mutex_lock(&pcf->lock);
1309 +       pcf_tm.sec = __reg_read(pcf, PCF50633_REG_RTCSC);
1310 +       pcf_tm.min = __reg_read(pcf, PCF50633_REG_RTCMN);
1311 +       pcf_tm.hour = __reg_read(pcf, PCF50633_REG_RTCHR);
1312 +       pcf_tm.wkday = __reg_read(pcf, PCF50633_REG_RTCWD);
1313 +       pcf_tm.day = __reg_read(pcf, PCF50633_REG_RTCDT);
1314 +       pcf_tm.month = __reg_read(pcf, PCF50633_REG_RTCMT);
1315 +       pcf_tm.year = __reg_read(pcf, PCF50633_REG_RTCYR);
1316 +       mutex_unlock(&pcf->lock);
1317 +
1318 +       DEBUGP("PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
1319 +               pcf_tm.day, pcf_tm.month, pcf_tm.year,
1320 +               pcf_tm.hour, pcf_tm.min, pcf_tm.sec);
1321 +
1322 +       pcf2rtc_time(tm, &pcf_tm);
1323 +
1324 +       DEBUGP("RTC_TIME: %u.%u.%u %u:%u:%u\n",
1325 +               tm->tm_mday, tm->tm_mon, tm->tm_year,
1326 +               tm->tm_hour, tm->tm_min, tm->tm_sec);
1327 +
1328 +       return 0;
1329 +}
1330 +
1331 +static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
1332 +{
1333 +       struct i2c_client *client = to_i2c_client(dev);
1334 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1335 +       struct pcf50633_time pcf_tm;
1336 +
1337 +       DEBUGP("RTC_TIME: %u.%u.%u %u:%u:%u\n",
1338 +               tm->tm_mday, tm->tm_mon, tm->tm_year,
1339 +               tm->tm_hour, tm->tm_min, tm->tm_sec);
1340 +       rtc2pcf_time(&pcf_tm, tm);
1341 +       DEBUGP("PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
1342 +               pcf_tm.day, pcf_tm.month, pcf_tm.year,
1343 +               pcf_tm.hour, pcf_tm.min, pcf_tm.sec);
1344 +
1345 +       mutex_lock(&pcf->lock);
1346 +       /* FIXME: disable second interrupt */
1347 +       __reg_write(pcf, PCF50633_REG_RTCSC, pcf_tm.sec);
1348 +       __reg_write(pcf, PCF50633_REG_RTCMN, pcf_tm.min);
1349 +       __reg_write(pcf, PCF50633_REG_RTCHR, pcf_tm.hour);
1350 +       __reg_write(pcf, PCF50633_REG_RTCWD, pcf_tm.wkday);
1351 +       __reg_write(pcf, PCF50633_REG_RTCDT, pcf_tm.day);
1352 +       __reg_write(pcf, PCF50633_REG_RTCMT, pcf_tm.month);
1353 +       __reg_write(pcf, PCF50633_REG_RTCYR, pcf_tm.year);
1354 +       /* FIXME: re-enable second interrupt */
1355 +       mutex_unlock(&pcf->lock);
1356 +
1357 +       return 0;
1358 +}
1359 +
1360 +static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
1361 +{
1362 +       struct i2c_client *client = to_i2c_client(dev);
1363 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1364 +       struct pcf50633_time pcf_tm;
1365 +
1366 +       mutex_lock(&pcf->lock);
1367 +       alrm->enabled =
1368 +            __reg_read(pcf, PCF50633_REG_INT1M) & PCF50633_INT1_ALARM ? 0 : 1;
1369 +       pcf_tm.sec = __reg_read(pcf, PCF50633_REG_RTCSCA);
1370 +       pcf_tm.min = __reg_read(pcf, PCF50633_REG_RTCMNA);
1371 +       pcf_tm.hour = __reg_read(pcf, PCF50633_REG_RTCHRA);
1372 +       pcf_tm.wkday = __reg_read(pcf, PCF50633_REG_RTCWDA);
1373 +       pcf_tm.day = __reg_read(pcf, PCF50633_REG_RTCDTA);
1374 +       pcf_tm.month = __reg_read(pcf, PCF50633_REG_RTCMTA);
1375 +       pcf_tm.year = __reg_read(pcf, PCF50633_REG_RTCYRA);
1376 +       mutex_unlock(&pcf->lock);
1377 +
1378 +       pcf2rtc_time(&alrm->time, &pcf_tm);
1379 +
1380 +       return 0;
1381 +}
1382 +
1383 +static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
1384 +{
1385 +       struct i2c_client *client = to_i2c_client(dev);
1386 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1387 +       struct pcf50633_time pcf_tm;
1388 +       u_int8_t irqmask;
1389 +
1390 +       rtc2pcf_time(&pcf_tm, &alrm->time);
1391 +
1392 +       mutex_lock(&pcf->lock);
1393 +
1394 +       /* disable alarm interrupt */
1395 +       irqmask = __reg_read(pcf, PCF50633_REG_INT1M);
1396 +       irqmask |= PCF50633_INT1_ALARM;
1397 +       __reg_write(pcf, PCF50633_REG_INT1M, irqmask);
1398 +
1399 +       __reg_write(pcf, PCF50633_REG_RTCSCA, pcf_tm.sec);
1400 +       __reg_write(pcf, PCF50633_REG_RTCMNA, pcf_tm.min);
1401 +       __reg_write(pcf, PCF50633_REG_RTCHRA, pcf_tm.hour);
1402 +       __reg_write(pcf, PCF50633_REG_RTCWDA, pcf_tm.wkday);
1403 +       __reg_write(pcf, PCF50633_REG_RTCDTA, pcf_tm.day);
1404 +       __reg_write(pcf, PCF50633_REG_RTCMTA, pcf_tm.month);
1405 +       __reg_write(pcf, PCF50633_REG_RTCYRA, pcf_tm.year);
1406 +
1407 +       if (alrm->enabled) {
1408 +               /* (re-)enaable alarm interrupt */
1409 +               irqmask = __reg_read(pcf, PCF50633_REG_INT1M);
1410 +               irqmask &= ~PCF50633_INT1_ALARM;
1411 +               __reg_write(pcf, PCF50633_REG_INT1M, irqmask);
1412 +       }
1413 +
1414 +       mutex_unlock(&pcf->lock);
1415 +
1416 +       /* FIXME */
1417 +       return 0;
1418 +}
1419 +
1420 +static struct rtc_class_ops pcf50633_rtc_ops = {
1421 +       .ioctl          = pcf50633_rtc_ioctl,
1422 +       .read_time      = pcf50633_rtc_read_time,
1423 +       .set_time       = pcf50633_rtc_set_time,
1424 +       .read_alarm     = pcf50633_rtc_read_alarm,
1425 +       .set_alarm      = pcf50633_rtc_set_alarm,
1426 +};
1427 +
1428 +/***********************************************************************
1429 + * Backlight device
1430 + ***********************************************************************/
1431 +
1432 +static int pcf50633bl_get_intensity(struct backlight_device *bd)
1433 +{
1434 +       struct pcf50633_data *pcf = bl_get_data(bd);
1435 +       int intensity = reg_read(pcf, PCF50633_REG_LEDOUT);
1436 +
1437 +       return intensity & 0x3f;
1438 +}
1439 +
1440 +static int pcf50633bl_set_intensity(struct backlight_device *bd)
1441 +{
1442 +       struct pcf50633_data *pcf = bl_get_data(bd);
1443 +       int intensity = bd->props.brightness;
1444 +       int old_intensity = reg_read(pcf, PCF50633_REG_LEDOUT);
1445 +       u_int8_t ledena;
1446 +       int ret;
1447 +
1448 +       if (bd->props.power != FB_BLANK_UNBLANK)
1449 +               intensity = 0;
1450 +       if (bd->props.fb_blank != FB_BLANK_UNBLANK)
1451 +               intensity = 0;
1452 +
1453 +       /* The PCF50633 seems to have some kind of oddity (bug?) when
1454 +        * the intensity was 0, you need to completely switch it off
1455 +        * and re-enable it, before it produces any output voltage again */
1456 +
1457 +       if (intensity != 0 && old_intensity == 0) {
1458 +               ledena = reg_read(pcf, PCF50633_REG_LEDENA);
1459 +               reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
1460 +       }
1461 +
1462 +       ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
1463 +                              intensity);
1464 +
1465 +       if (intensity != 0 && old_intensity == 0)
1466 +               reg_write(pcf, PCF50633_REG_LEDENA, ledena);
1467 +
1468 +       return ret;
1469 +}
1470 +
1471 +static struct backlight_ops pcf50633bl_ops = {
1472 +       .get_brightness = pcf50633bl_get_intensity,
1473 +       .update_status  = pcf50633bl_set_intensity,
1474 +};
1475 +
1476 +/*
1477 + * Charger type
1478 + */
1479 +
1480 +static ssize_t show_charger_type(struct device *dev,
1481 +                                struct device_attribute *attr, char *buf)
1482 +{
1483 +       struct i2c_client *client = to_i2c_client(dev);
1484 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1485 +       static const char *names_charger_type[] = {
1486 +               [CHARGER_TYPE_NONE]     = "none",
1487 +               [CHARGER_TYPE_HOSTUSB]  = "host/500mA usb",
1488 +               [CHARGER_TYPE_1A]       = "charger 1A",
1489 +       };
1490 +       static const char *names_charger_modes[] = {
1491 +               [PCF50633_MBCC7_USB_1000mA]     = "1A",
1492 +               [PCF50633_MBCC7_USB_500mA]      = "500mA",
1493 +               [PCF50633_MBCC7_USB_100mA]      = "100mA",
1494 +               [PCF50633_MBCC7_USB_SUSPEND]    = "suspend",
1495 +       };
1496 +       int mode = reg_read(pcf, PCF50633_REG_MBCC7) & PCF56033_MBCC7_USB_MASK;
1497 +
1498 +       return sprintf(buf, "%s mode %s\n",
1499 +                           names_charger_type[pcf->charger_type],
1500 +                           names_charger_modes[mode]);
1501 +}
1502 +
1503 +static DEVICE_ATTR(charger_type, 0444, show_charger_type, NULL);
1504 +
1505 +/*
1506 + * Charger adc
1507 + */
1508 +
1509 +static ssize_t show_charger_adc(struct device *dev,
1510 +                               struct device_attribute *attr, char *buf)
1511 +{
1512 +       struct i2c_client *client = to_i2c_client(dev);
1513 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1514 +
1515 +       return sprintf(buf, "%d\n", pcf->charger_adc_result_raw);
1516 +}
1517 +
1518 +static DEVICE_ATTR(charger_adc, 0444, show_charger_adc, NULL);
1519 +
1520 +/*
1521 + * Dump regs
1522 + */
1523 +
1524 +static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr,
1525 +                           char *buf)
1526 +{
1527 +       struct i2c_client *client = to_i2c_client(dev);
1528 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1529 +       u8 dump[16];
1530 +       int n, n1, idx = 0;
1531 +       char *buf1 = buf;
1532 +       static u8 address_no_read[] = { /* must be ascending */
1533 +               PCF50633_REG_INT1,
1534 +               PCF50633_REG_INT2,
1535 +               PCF50633_REG_INT3,
1536 +               PCF50633_REG_INT4,
1537 +               PCF50633_REG_INT5,
1538 +               0 /* terminator */
1539 +       };
1540 +
1541 +       for (n = 0; n < 256; n += sizeof(dump)) {
1542 +
1543 +               for (n1 = 0; n1 < sizeof(dump); n1++)
1544 +                       if (n == address_no_read[idx]) {
1545 +                               idx++;
1546 +                               dump[n1] = 0x00;
1547 +                       } else
1548 +                               dump[n1] = reg_read(pcf, n + n1);
1549 +
1550 +               hex_dump_to_buffer(dump, sizeof(dump), 16, 1, buf1, 128, 0);
1551 +               buf1 += strlen(buf1);
1552 +               *buf1++ = '\n';
1553 +               *buf1 = '\0';
1554 +       }
1555 +
1556 +       return buf1 - buf;
1557 +}
1558 +
1559 +static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL);
1560 +
1561 +
1562 +/***********************************************************************
1563 + * Driver initialization
1564 + ***********************************************************************/
1565 +
1566 +#ifdef CONFIG_MACH_NEO1973_GTA02
1567 +/* We currently place those platform devices here to make sure the device
1568 + * suspend/resume order is correct */
1569 +static struct platform_device gta01_pm_gps_dev = {
1570 +       .name           = "neo1973-pm-gps",
1571 +};
1572 +
1573 +static struct platform_device gta01_pm_bt_dev = {
1574 +       .name           = "neo1973-pm-bt",
1575 +};
1576 +#endif
1577 +
1578 +/*
1579 + * CARE!  This table is modified at runtime!
1580 + */
1581 +static struct attribute *pcf_sysfs_entries[] = {
1582 +       &dev_attr_voltage_auto.attr,
1583 +       &dev_attr_voltage_down1.attr,
1584 +       &dev_attr_voltage_down2.attr,
1585 +       &dev_attr_voltage_memldo.attr,
1586 +       &dev_attr_voltage_ldo1.attr,
1587 +       &dev_attr_voltage_ldo2.attr,
1588 +       &dev_attr_voltage_ldo3.attr,
1589 +       &dev_attr_voltage_ldo4.attr,
1590 +       &dev_attr_voltage_ldo5.attr,
1591 +       &dev_attr_voltage_ldo6.attr,
1592 +       &dev_attr_voltage_hcldo.attr,
1593 +       &dev_attr_charger_type.attr,
1594 +       &dev_attr_charger_adc.attr,
1595 +       &dev_attr_dump_regs.attr,
1596 +       NULL, /* going to add things at this point! */
1597 +       NULL,
1598 +       NULL,
1599 +       NULL,
1600 +       NULL,
1601 +       NULL,
1602 +       NULL,
1603 +};
1604 +
1605 +static struct attribute_group pcf_attr_group = {
1606 +       .name   = NULL,                 /* put in device directory */
1607 +       .attrs  = pcf_sysfs_entries,
1608 +};
1609 +
1610 +static void populate_sysfs_group(struct pcf50633_data *pcf)
1611 +{
1612 +       int i = 0;
1613 +       struct attribute **attr;
1614 +
1615 +       for (attr = pcf_sysfs_entries; *attr; attr++)
1616 +               i++;
1617 +
1618 +       if (pcf->pdata->used_features & PCF50633_FEAT_MBC) {
1619 +               pcf_sysfs_entries[i++] = &dev_attr_chgstate.attr;
1620 +               pcf_sysfs_entries[i++] = &dev_attr_chgmode.attr;
1621 +               pcf_sysfs_entries[i++] = &dev_attr_usb_curlim.attr;
1622 +       }
1623 +
1624 +       if (pcf->pdata->used_features & PCF50633_FEAT_CHGCUR)
1625 +               pcf_sysfs_entries[i++] = &dev_attr_chgcur.attr;
1626 +
1627 +       if (pcf->pdata->used_features & PCF50633_FEAT_BATVOLT)
1628 +               pcf_sysfs_entries[i++] = &dev_attr_battvolt.attr;
1629 +
1630 +       if (pcf->pdata->used_features & PCF50633_FEAT_BATTEMP)
1631 +               pcf_sysfs_entries[i++] = &dev_attr_battemp.attr;
1632 +
1633 +}
1634 +
1635 +static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
1636 +{
1637 +       struct i2c_client *new_client;
1638 +       struct pcf50633_data *data;
1639 +       int err = 0;
1640 +       int irq;
1641 +
1642 +       DEBUGP("entering\n");
1643 +       if (!pcf50633_pdev) {
1644 +               printk(KERN_ERR "pcf50633: driver needs a platform_device!\n");
1645 +               return -EIO;
1646 +       }
1647 +
1648 +       irq = platform_get_irq(pcf50633_pdev, 0);
1649 +       if (irq < 0) {
1650 +               dev_err(&pcf50633_pdev->dev, "no irq in platform resources!\n");
1651 +               return -EIO;
1652 +       }
1653 +
1654 +       /* At the moment, we only support one PCF50633 in a system */
1655 +       if (pcf50633_global) {
1656 +               dev_err(&pcf50633_pdev->dev,
1657 +                       "currently only one chip supported\n");
1658 +               return -EBUSY;
1659 +       }
1660 +
1661 +       if (!(data = kzalloc(sizeof(*data), GFP_KERNEL)))
1662 +               return -ENOMEM;
1663 +
1664 +       mutex_init(&data->lock);
1665 +       mutex_init(&data->working_lock);
1666 +       INIT_WORK(&data->work, pcf50633_work);
1667 +       data->irq = irq;
1668 +       data->working = 0;
1669 +       data->onkey_seconds = -1;
1670 +       data->pdata = pcf50633_pdev->dev.platform_data;
1671 +
1672 +       new_client = &data->client;
1673 +       i2c_set_clientdata(new_client, data);
1674 +       new_client->addr = address;
1675 +       new_client->adapter = adapter;
1676 +       new_client->driver = &pcf50633_driver;
1677 +       new_client->flags = 0;
1678 +       strlcpy(new_client->name, "pcf50633", I2C_NAME_SIZE);
1679 +
1680 +       /* now we try to detect the chip */
1681 +
1682 +       /* register with i2c core */
1683 +       if ((err = i2c_attach_client(new_client))) {
1684 +               dev_err(&new_client->dev,
1685 +                       "error during i2c_attach_client()\n");
1686 +               goto exit_free;
1687 +       }
1688 +
1689 +       pcf50633_global = data;
1690 +
1691 +       populate_sysfs_group(data);
1692 +
1693 +       err = sysfs_create_group(&new_client->dev.kobj, &pcf_attr_group);
1694 +       if (err) {
1695 +               dev_err(&new_client->dev, "error creating sysfs group\n");
1696 +               goto exit_detach;
1697 +       }
1698 +
1699 +       /* create virtual charger 'device' */
1700 +
1701 +       /* register power off handler with core power management */
1702 +       pm_power_off = &pcf50633_go_standby;
1703 +
1704 +       data->input_dev = input_allocate_device();
1705 +       if (!data->input_dev)
1706 +               goto exit_sysfs;
1707 +
1708 +       data->input_dev->name = "GTA02 PMU events";
1709 +       data->input_dev->phys = "FIXME";
1710 +       data->input_dev->id.bustype = BUS_I2C;
1711 +       data->input_dev->cdev.dev = &new_client->dev;
1712 +
1713 +       data->input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
1714 +       set_bit(KEY_POWER, data->input_dev->keybit);
1715 +       set_bit(KEY_POWER2, data->input_dev->keybit);
1716 +       set_bit(KEY_BATTERY, data->input_dev->keybit);
1717 +
1718 +       err = input_register_device(data->input_dev);
1719 +       if (err)
1720 +               goto exit_sysfs;
1721 +
1722 +       /* configure interrupt mask */
1723 +       reg_write(data, PCF50633_REG_INT1M, 0x00); /* we want SECOND to kick */
1724 +       reg_write(data, PCF50633_REG_INT2M, 0x00);
1725 +       reg_write(data, PCF50633_REG_INT3M, 0x00);
1726 +       reg_write(data, PCF50633_REG_INT4M, 0x00);
1727 +       reg_write(data, PCF50633_REG_INT5M, 0x00);
1728 +
1729 +       err = request_irq(irq, pcf50633_irq, IRQF_TRIGGER_FALLING,
1730 +                         "pcf50633", data);
1731 +       if (err < 0)
1732 +               goto exit_input;
1733 +
1734 +       if (enable_irq_wake(irq) < 0)
1735 +               dev_err(&new_client->dev, "IRQ %u cannot be enabled as wake-up"
1736 +                       "source in this hardware revision!", irq);
1737 +
1738 +       if (data->pdata->used_features & PCF50633_FEAT_RTC) {
1739 +               data->rtc = rtc_device_register("pcf50633", &new_client->dev,
1740 +                                               &pcf50633_rtc_ops, THIS_MODULE);
1741 +               if (IS_ERR(data->rtc)) {
1742 +                       err = PTR_ERR(data->rtc);
1743 +                       goto exit_irq;
1744 +               }
1745 +       }
1746 +
1747 +       if (data->pdata->used_features & PCF50633_FEAT_PWM_BL) {
1748 +               data->backlight = backlight_device_register("pcf50633-bl",
1749 +                                                           &new_client->dev,
1750 +                                                           data,
1751 +                                                           &pcf50633bl_ops);
1752 +               if (!data->backlight)
1753 +                       goto exit_rtc;
1754 +               /* FIXME: are we sure we want default == off? */
1755 +               data->backlight->props.max_brightness = 0x3f;
1756 +               data->backlight->props.power = FB_BLANK_UNBLANK;
1757 +               data->backlight->props.fb_blank = FB_BLANK_UNBLANK;
1758 +               data->backlight->props.brightness =
1759 +                                       data->backlight->props.max_brightness;
1760 +               backlight_update_status(data->backlight);
1761 +       }
1762 +
1763 +       apm_get_power_status = pcf50633_get_power_status;
1764 +
1765 +#ifdef CONFIG_MACH_NEO1973_GTA02
1766 +       if (machine_is_neo1973_gta02()) {
1767 +               gta01_pm_gps_dev.dev.parent = &new_client->dev;
1768 +               gta01_pm_bt_dev.dev.parent = &new_client->dev;
1769 +               platform_device_register(&gta01_pm_bt_dev);
1770 +               platform_device_register(&gta01_pm_gps_dev);
1771 +       }
1772 +#endif
1773 +
1774 +       return 0;
1775 +exit_rtc:
1776 +       if (data->pdata->used_features & PCF50633_FEAT_RTC)
1777 +               rtc_device_unregister(pcf50633_global->rtc);
1778 +exit_irq:
1779 +       free_irq(pcf50633_global->irq, pcf50633_global);
1780 +exit_input:
1781 +       input_unregister_device(data->input_dev);
1782 +exit_sysfs:
1783 +       pm_power_off = NULL;
1784 +       sysfs_remove_group(&new_client->dev.kobj, &pcf_attr_group);
1785 +exit_detach:
1786 +       i2c_detach_client(new_client);
1787 +exit_free:
1788 +       kfree(data);
1789 +       pcf50633_global = NULL;
1790 +       return err;
1791 +}
1792 +
1793 +static int pcf50633_attach_adapter(struct i2c_adapter *adapter)
1794 +{
1795 +       DEBUGP("entering, calling i2c_probe\n");
1796 +       return i2c_probe(adapter, &addr_data, &pcf50633_detect);
1797 +}
1798 +
1799 +static int pcf50633_detach_client(struct i2c_client *client)
1800 +{
1801 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1802 +
1803 +       DEBUGP("entering\n");
1804 +
1805 +       apm_get_power_status = NULL;
1806 +
1807 +       free_irq(pcf->irq, pcf);
1808 +
1809 +       input_unregister_device(pcf->input_dev);
1810 +
1811 +       if (pcf->pdata->used_features & PCF50633_FEAT_PWM_BL)
1812 +               backlight_device_unregister(pcf->backlight);
1813 +
1814 +       if (pcf->pdata->used_features & PCF50633_FEAT_RTC)
1815 +               rtc_device_unregister(pcf->rtc);
1816 +
1817 +#ifdef CONFIG_MACH_NEO1973_GTA02
1818 +       if (machine_is_neo1973_gta02()) {
1819 +               platform_device_unregister(&gta01_pm_bt_dev);
1820 +               platform_device_unregister(&gta01_pm_gps_dev);
1821 +       }
1822 +#endif
1823 +
1824 +       sysfs_remove_group(&client->dev.kobj, &pcf_attr_group);
1825 +
1826 +       pm_power_off = NULL;
1827 +
1828 +       kfree(pcf);
1829 +
1830 +       return 0;
1831 +}
1832 +
1833 +#ifdef CONFIG_PM
1834 +#define INT1M_RESUMERS (PCF50633_INT1_ADPINS           | \
1835 +                        PCF50633_INT1_ADPREM           | \
1836 +                        PCF50633_INT1_USBINS           | \
1837 +                        PCF50633_INT1_USBREM           | \
1838 +                        PCF50633_INT1_ALARM)
1839 +#define INT2M_RESUMERS (PCF50633_INT2_ONKEYF)
1840 +#define INT3M_RESUMERS (PCF50633_INT3_BATFULL          | \
1841 +                        PCF50633_INT3_CHGHALT          | \
1842 +                        PCF50633_INT3_THLIMON          | \
1843 +                        PCF50633_INT3_THLIMOFF         | \
1844 +                        PCF50633_INT3_USBLIMON         | \
1845 +                        PCF50633_INT3_USBLIMOFF        | \
1846 +                        PCF50633_INT3_ONKEY1S)
1847 +#define INT4M_RESUMERS (PCF50633_INT4_LOWSYS           | \
1848 +                        PCF50633_INT4_LOWBAT           | \
1849 +                        PCF50633_INT4_HIGHTMP)
1850 +#define INT5M_RESUMERS (0)
1851 +
1852 +static int pcf50633_suspend(struct device *dev, pm_message_t state)
1853 +{
1854 +       struct i2c_client *client = to_i2c_client(dev);
1855 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1856 +       int i;
1857 +
1858 +       /* The general idea is to power down all unused power supplies,
1859 +        * and then mask all PCF50606 interrup sources but EXTONR, ONKEYF
1860 +        * and ALARM */
1861 +
1862 +       mutex_lock(&pcf->lock);
1863 +
1864 +       /* Save all registers that don't "survive" standby state */
1865 +       pcf->standby_regs.ooctim2 = __reg_read(pcf, PCF50633_REG_OOCTIM2);
1866 +       pcf->standby_regs.autoout = __reg_read(pcf, PCF50633_REG_AUTOOUT);
1867 +       pcf->standby_regs.autoena = __reg_read(pcf, PCF50633_REG_AUTOENA);
1868 +       pcf->standby_regs.automxc = __reg_read(pcf, PCF50633_REG_AUTOMXC);
1869 +       pcf->standby_regs.down1out = __reg_read(pcf, PCF50633_REG_DOWN1OUT);
1870 +       pcf->standby_regs.down1mxc = __reg_read(pcf, PCF50633_REG_DOWN1MXC);
1871 +       pcf->standby_regs.down2out = __reg_read(pcf, PCF50633_REG_DOWN2OUT);
1872 +       pcf->standby_regs.down2ena = __reg_read(pcf, PCF50633_REG_DOWN2ENA);
1873 +       pcf->standby_regs.memldoout = __reg_read(pcf, PCF50633_REG_MEMLDOOUT);
1874 +       pcf->standby_regs.memldoena = __reg_read(pcf, PCF50633_REG_MEMLDOENA);
1875 +       pcf->standby_regs.ledout = __reg_read(pcf, PCF50633_REG_LEDOUT);
1876 +       pcf->standby_regs.ledena = __reg_read(pcf, PCF50633_REG_LEDENA);
1877 +       pcf->standby_regs.leddim = __reg_read(pcf, PCF50633_REG_LEDDIM);
1878 +       /* FIXME: one big read? */
1879 +       for (i = 0; i < 7; i++) {
1880 +               u_int8_t reg_out = PCF50633_REG_LDO1OUT + 2*i;
1881 +               pcf->standby_regs.ldo[i].out = __reg_read(pcf, reg_out);
1882 +               pcf->standby_regs.ldo[i].ena = __reg_read(pcf, reg_out+1);
1883 +       }
1884 +
1885 +       /* switch off power supplies that are not needed during suspend */
1886 +       for (i = 0; i < __NUM_PCF50633_REGULATORS; i++) {
1887 +               if (!(pcf->pdata->rails[i].flags & PMU_VRAIL_F_SUSPEND_ON)) {
1888 +                       u_int8_t tmp;
1889 +
1890 +                       DEBUGP("disabling pcf50633 regulator %u\n", i);
1891 +                       /* we cannot use pcf50633_onoff_set() because we're
1892 +                        * already under the mutex */
1893 +                       tmp = __reg_read(pcf, regulator_registers[i]+1);
1894 +                       tmp &= 0xfe;
1895 +                       __reg_write(pcf, regulator_registers[i]+1, tmp);
1896 +               }
1897 +       }
1898 +
1899 +       pcf->standby_regs.int1m = __reg_read(pcf, PCF50633_REG_INT1M);
1900 +       pcf->standby_regs.int2m = __reg_read(pcf, PCF50633_REG_INT2M);
1901 +       pcf->standby_regs.int3m = __reg_read(pcf, PCF50633_REG_INT3M);
1902 +       pcf->standby_regs.int4m = __reg_read(pcf, PCF50633_REG_INT4M);
1903 +       pcf->standby_regs.int5m = __reg_read(pcf, PCF50633_REG_INT5M);
1904 +       __reg_write(pcf, PCF50633_REG_INT1M, ~INT1M_RESUMERS & 0xff);
1905 +       __reg_write(pcf, PCF50633_REG_INT2M, ~INT2M_RESUMERS & 0xff);
1906 +       __reg_write(pcf, PCF50633_REG_INT3M, ~INT3M_RESUMERS & 0xff);
1907 +       __reg_write(pcf, PCF50633_REG_INT4M, ~INT4M_RESUMERS & 0xff);
1908 +       __reg_write(pcf, PCF50633_REG_INT5M, ~INT5M_RESUMERS & 0xff);
1909 +
1910 +       mutex_unlock(&pcf->lock);
1911 +
1912 +       return 0;
1913 +}
1914 +
1915 +static int pcf50633_resume(struct device *dev)
1916 +{
1917 +       struct i2c_client *client = to_i2c_client(dev);
1918 +       struct pcf50633_data *pcf = i2c_get_clientdata(client);
1919 +       int i;
1920 +
1921 +       mutex_lock(&pcf->lock);
1922 +
1923 +       /* Resume all saved registers that don't "survive" standby state */
1924 +       __reg_write(pcf, PCF50633_REG_INT1M, pcf->standby_regs.int1m);
1925 +       __reg_write(pcf, PCF50633_REG_INT2M, pcf->standby_regs.int2m);
1926 +       __reg_write(pcf, PCF50633_REG_INT3M, pcf->standby_regs.int3m);
1927 +       __reg_write(pcf, PCF50633_REG_INT4M, pcf->standby_regs.int4m);
1928 +       __reg_write(pcf, PCF50633_REG_INT5M, pcf->standby_regs.int5m);
1929 +
1930 +       __reg_write(pcf, PCF50633_REG_OOCTIM2, pcf->standby_regs.ooctim2);
1931 +       __reg_write(pcf, PCF50633_REG_AUTOOUT, pcf->standby_regs.autoout);
1932 +       __reg_write(pcf, PCF50633_REG_AUTOMXC, pcf->standby_regs.automxc);
1933 +       __reg_write(pcf, PCF50633_REG_DOWN1OUT, pcf->standby_regs.down1out);
1934 +       __reg_write(pcf, PCF50633_REG_DOWN1MXC, pcf->standby_regs.down1mxc);
1935 +       __reg_write(pcf, PCF50633_REG_DOWN2OUT, pcf->standby_regs.down2out);
1936 +       __reg_write(pcf, PCF50633_REG_DOWN2ENA, pcf->standby_regs.down2ena);
1937 +       __reg_write(pcf, PCF50633_REG_MEMLDOOUT, pcf->standby_regs.memldoout);
1938 +       __reg_write(pcf, PCF50633_REG_MEMLDOENA, pcf->standby_regs.memldoena);
1939 +       __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
1940 +       __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
1941 +       __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
1942 +       /* FIXME: one big read? */
1943 +       for (i = 0; i < 7; i++) {
1944 +               u_int8_t reg_out = PCF50633_REG_LDO1OUT + 2*i;
1945 +               __reg_write(pcf, reg_out, pcf->standby_regs.ldo[i].out);
1946 +               __reg_write(pcf, reg_out+1, pcf->standby_regs.ldo[i].ena);
1947 +       }
1948 +
1949 +       mutex_unlock(&pcf->lock);
1950 +
1951 +       pcf50633_irq(pcf->irq, pcf);
1952 +
1953 +       return 0;
1954 +}
1955 +#else
1956 +#define pcf50633_suspend NULL
1957 +#define pcf50633_resume NULL
1958 +#endif
1959 +
1960 +static struct i2c_driver pcf50633_driver = {
1961 +       .driver = {
1962 +               .name   = "pcf50633",
1963 +               .suspend= pcf50633_suspend,
1964 +               .resume = pcf50633_resume,
1965 +       },
1966 +       .id             = I2C_DRIVERID_PCF50633,
1967 +       .attach_adapter = pcf50633_attach_adapter,
1968 +       .detach_client  = pcf50633_detach_client,
1969 +};
1970 +
1971 +/* platform driver, since i2c devices don't have platform_data */
1972 +static int __init pcf50633_plat_probe(struct platform_device *pdev)
1973 +{
1974 +       struct pcf50633_platform_data *pdata = pdev->dev.platform_data;
1975 +
1976 +       if (!pdata)
1977 +               return -ENODEV;
1978 +
1979 +       pcf50633_pdev = pdev;
1980 +
1981 +       return 0;
1982 +}
1983 +
1984 +static int pcf50633_plat_remove(struct platform_device *pdev)
1985 +{
1986 +       return 0;
1987 +}
1988 +
1989 +static struct platform_driver pcf50633_plat_driver = {
1990 +       .probe  = pcf50633_plat_probe,
1991 +       .remove = pcf50633_plat_remove,
1992 +       .driver = {
1993 +               .owner  = THIS_MODULE,
1994 +               .name   = "pcf50633",
1995 +       },
1996 +};
1997 +
1998 +static int __init pcf50633_init(void)
1999 +{
2000 +       int rc;
2001 +
2002 +       if (!(rc = platform_driver_register(&pcf50633_plat_driver)))
2003 +               rc = i2c_add_driver(&pcf50633_driver);
2004 +
2005 +       return rc;
2006 +}
2007 +
2008 +static void pcf50633_exit(void)
2009 +{
2010 +       i2c_del_driver(&pcf50633_driver);
2011 +       platform_driver_unregister(&pcf50633_plat_driver);
2012 +}
2013 +
2014 +MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 power management unit");
2015 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
2016 +MODULE_LICENSE("GPL");
2017 +
2018 +module_init(pcf50633_init);
2019 +module_exit(pcf50633_exit);
2020 diff --git a/drivers/i2c/chips/pcf50633.h b/drivers/i2c/chips/pcf50633.h
2021 new file mode 100644
2022 index 0000000..9aad206
2023 --- /dev/null
2024 +++ b/drivers/i2c/chips/pcf50633.h
2025 @@ -0,0 +1,402 @@
2026 +#ifndef _PCF50633_H
2027 +#define _PCF50633_H
2028 +
2029 +/* Philips PCF50633 Power Managemnt Unit (PMU) driver
2030 + * (C) 2006-2007 by OpenMoko, Inc.
2031 + * Author: Harald Welte <laforge@openmoko.org>
2032 + *
2033 + */
2034 +
2035 +enum pfc50633_regs {
2036 +       PCF50633_REG_VERSION    = 0x00,
2037 +       PCF50633_REG_VARIANT    = 0x01,
2038 +       PCF50633_REG_INT1       = 0x02, /* Interrupt Status */
2039 +       PCF50633_REG_INT2       = 0x03, /* Interrupt Status */
2040 +       PCF50633_REG_INT3       = 0x04, /* Interrupt Status */
2041 +       PCF50633_REG_INT4       = 0x05, /* Interrupt Status */
2042 +       PCF50633_REG_INT5       = 0x06, /* Interrupt Status */
2043 +       PCF50633_REG_INT1M      = 0x07, /* Interrupt Mask */
2044 +       PCF50633_REG_INT2M      = 0x08, /* Interrupt Mask */
2045 +       PCF50633_REG_INT3M      = 0x09, /* Interrupt Mask */
2046 +       PCF50633_REG_INT4M      = 0x0a, /* Interrupt Mask */
2047 +       PCF50633_REG_INT5M      = 0x0b, /* Interrupt Mask */
2048 +       PCF50633_REG_OOCSHDWN   = 0x0c,
2049 +       PCF50633_REG_OOCWAKE    = 0x0d,
2050 +       PCF50633_REG_OOCTIM1    = 0x0e,
2051 +       PCF50633_REG_OOCTIM2    = 0x0f,
2052 +       PCF50633_REG_OOCMODE    = 0x10,
2053 +       PCF50633_REG_OOCCTL     = 0x11,
2054 +       PCF50633_REG_OOCSTAT    = 0x12,
2055 +       PCF50633_REG_GPIOCTL    = 0x13,
2056 +       PCF50633_REG_GPIO1CFG   = 0x14,
2057 +       PCF50633_REG_GPIO2CFG   = 0x15,
2058 +       PCF50633_REG_GPIO3CFG   = 0x16,
2059 +       PCF50633_REG_GPOCFG     = 0x17,
2060 +       PCF50633_REG_BVMCTL     = 0x18,
2061 +       PCF50633_REG_SVMCTL     = 0x19,
2062 +       PCF50633_REG_AUTOOUT    = 0x1a,
2063 +       PCF50633_REG_AUTOENA    = 0x1b,
2064 +       PCF50633_REG_AUTOCTL    = 0x1c,
2065 +       PCF50633_REG_AUTOMXC    = 0x1d,
2066 +       PCF50633_REG_DOWN1OUT   = 0x1e,
2067 +       PCF50633_REG_DOWN1ENA   = 0x1f,
2068 +       PCF50633_REG_DOWN1CTL   = 0x20,
2069 +       PCF50633_REG_DOWN1MXC   = 0x21,
2070 +       PCF50633_REG_DOWN2OUT   = 0x22,
2071 +       PCF50633_REG_DOWN2ENA   = 0x23,
2072 +       PCF50633_REG_DOWN2CTL   = 0x24,
2073 +       PCF50633_REG_DOWN2MXC   = 0x25,
2074 +       PCF50633_REG_MEMLDOOUT  = 0x26,
2075 +       PCF50633_REG_MEMLDOENA  = 0x27,
2076 +       PCF50633_REG_LEDOUT     = 0x28,
2077 +       PCF50633_REG_LEDENA     = 0x29,
2078 +       PCF50633_REG_LEDCTL     = 0x2a,
2079 +       PCF50633_REG_LEDDIM     = 0x2b,
2080 +       /* reserved */
2081 +       PCF50633_REG_LDO1OUT    = 0x2d,
2082 +       PCF50633_REG_LDO1ENA    = 0x2e,
2083 +       PCF50633_REG_LDO2OUT    = 0x2f,
2084 +       PCF50633_REG_LDO2ENA    = 0x30,
2085 +       PCF50633_REG_LDO3OUT    = 0x31,
2086 +       PCF50633_REG_LDO3ENA    = 0x32,
2087 +       PCF50633_REG_LDO4OUT    = 0x33,
2088 +       PCF50633_REG_LDO4ENA    = 0x34,
2089 +       PCF50633_REG_LDO5OUT    = 0x35,
2090 +       PCF50633_REG_LDO5ENA    = 0x36,
2091 +       PCF50633_REG_LDO6OUT    = 0x37,
2092 +       PCF50633_REG_LDO6ENA    = 0x38,
2093 +       PCF50633_REG_HCLDOOUT   = 0x39,
2094 +       PCF50633_REG_HCLDOENA   = 0x3a,
2095 +       PCF50633_REG_STBYCTL1   = 0x3b,
2096 +       PCF50633_REG_STBYCTL2   = 0x3c,
2097 +       PCF50633_REG_DEBPF1     = 0x3d,
2098 +       PCF50633_REG_DEBPF2     = 0x3e,
2099 +       PCF50633_REG_DEBPF3     = 0x3f,
2100 +       PCF50633_REG_HCLDOOVL   = 0x40,
2101 +       PCF50633_REG_DCDCSTAT   = 0x41,
2102 +       PCF50633_REG_LDOSTAT    = 0x42,
2103 +       PCF50633_REG_MBCC1      = 0x43,
2104 +       PCF50633_REG_MBCC2      = 0x44,
2105 +       PCF50633_REG_MBCC3      = 0x45,
2106 +       PCF50633_REG_MBCC4      = 0x46,
2107 +       PCF50633_REG_MBCC5      = 0x47,
2108 +       PCF50633_REG_MBCC6      = 0x48,
2109 +       PCF50633_REG_MBCC7      = 0x49,
2110 +       PCF50633_REG_MBCC8      = 0x4a,
2111 +       PCF50633_REG_MBCS1      = 0x4b,
2112 +       PCF50633_REG_MBCS2      = 0x4c,
2113 +       PCF50633_REG_MBCS3      = 0x4d,
2114 +       PCF50633_REG_BBCCTL     = 0x4e,
2115 +       PCF50633_REG_ALMGAIN    = 0x4f,
2116 +       PCF50633_REG_ALMDATA    = 0x50,
2117 +       /* reserved */
2118 +       PCF50633_REG_ADCC3      = 0x52,
2119 +       PCF50633_REG_ADCC2      = 0x53,
2120 +       PCF50633_REG_ADCC1      = 0x54,
2121 +       PCF50633_REG_ADCS1      = 0x55,
2122 +       PCF50633_REG_ADCS2      = 0x56,
2123 +       PCF50633_REG_ADCS3      = 0x57,
2124 +       /* reserved */
2125 +       PCF50633_REG_RTCSC      = 0x59, /* Second */
2126 +       PCF50633_REG_RTCMN      = 0x5a, /* Minute */
2127 +       PCF50633_REG_RTCHR      = 0x5b, /* Hour */
2128 +       PCF50633_REG_RTCWD      = 0x5c, /* Weekday */
2129 +       PCF50633_REG_RTCDT      = 0x5d, /* Day */
2130 +       PCF50633_REG_RTCMT      = 0x5e, /* Month */
2131 +       PCF50633_REG_RTCYR      = 0x5f, /* Year */
2132 +       PCF50633_REG_RTCSCA     = 0x60, /* Alarm Second */
2133 +       PCF50633_REG_RTCMNA     = 0x61, /* Alarm Minute */
2134 +       PCF50633_REG_RTCHRA     = 0x62, /* Alarm Hour */
2135 +       PCF50633_REG_RTCWDA     = 0x63, /* Alarm Weekday */
2136 +       PCF50633_REG_RTCDTA     = 0x64, /* Alarm Day */
2137 +       PCF50633_REG_RTCMTA     = 0x65, /* Alarm Month */
2138 +       PCF50633_REG_RTCYRA     = 0x66, /* Alarm Year */
2139 +
2140 +       PCF50633_REG_MEMBYTE0   = 0x67,
2141 +       PCF50633_REG_MEMBYTE1   = 0x68,
2142 +       PCF50633_REG_MEMBYTE2   = 0x69,
2143 +       PCF50633_REG_MEMBYTE3   = 0x6a,
2144 +       PCF50633_REG_MEMBYTE4   = 0x6b,
2145 +       PCF50633_REG_MEMBYTE5   = 0x6c,
2146 +       PCF50633_REG_MEMBYTE6   = 0x6d,
2147 +       PCF50633_REG_MEMBYTE7   = 0x6e,
2148 +       /* reserved */
2149 +       PCF50633_REG_DCDCPFM    = 0x84,
2150 +       __NUM_PCF50633_REGS
2151 +};
2152 +
2153 +enum pcf50633_reg_int1 {
2154 +       PCF50633_INT1_ADPINS    = 0x01, /* Adapter inserted */
2155 +       PCF50633_INT1_ADPREM    = 0x02, /* Adapter removed */
2156 +       PCF50633_INT1_USBINS    = 0x04, /* USB inserted */
2157 +       PCF50633_INT1_USBREM    = 0x08, /* USB removed */
2158 +       /* reserved */
2159 +       PCF50633_INT1_ALARM     = 0x40, /* RTC alarm time is reached */
2160 +       PCF50633_INT1_SECOND    = 0x80, /* RTC periodic second interrupt */
2161 +};
2162 +
2163 +enum pcf50633_reg_int2 {
2164 +       PCF50633_INT2_ONKEYR    = 0x01, /* ONKEY rising edge */
2165 +       PCF50633_INT2_ONKEYF    = 0x02, /* ONKEY falling edge */
2166 +       PCF50633_INT2_EXTON1R   = 0x04, /* EXTON1 rising edge */
2167 +       PCF50633_INT2_EXTON1F   = 0x08, /* EXTON1 falling edge */
2168 +       PCF50633_INT2_EXTON2R   = 0x10, /* EXTON2 rising edge */
2169 +       PCF50633_INT2_EXTON2F   = 0x20, /* EXTON2 falling edge */
2170 +       PCF50633_INT2_EXTON3R   = 0x40, /* EXTON3 rising edge */
2171 +       PCF50633_INT2_EXTON3F   = 0x80, /* EXTON3 falling edge */
2172 +};
2173 +
2174 +enum pcf50633_reg_int3 {
2175 +       PCF50633_INT3_BATFULL   = 0x01, /* Battery full */
2176 +       PCF50633_INT3_CHGHALT   = 0x02, /* Charger halt */
2177 +       PCF50633_INT3_THLIMON   = 0x04,
2178 +       PCF50633_INT3_THLIMOFF  = 0x08,
2179 +       PCF50633_INT3_USBLIMON  = 0x10,
2180 +       PCF50633_INT3_USBLIMOFF = 0x20,
2181 +       PCF50633_INT3_ADCRDY    = 0x40, /* ADC conversion finished */
2182 +       PCF50633_INT3_ONKEY1S   = 0x80, /* ONKEY pressed 1 second */
2183 +};
2184 +
2185 +enum pcf50633_reg_int4 {
2186 +       PCF50633_INT4_LOWSYS            = 0x01,
2187 +       PCF50633_INT4_LOWBAT            = 0x02,
2188 +       PCF50633_INT4_HIGHTMP           = 0x04,
2189 +       PCF50633_INT4_AUTOPWRFAIL       = 0x08,
2190 +       PCF50633_INT4_DWN1PWRFAIL       = 0x10,
2191 +       PCF50633_INT4_DWN2PWRFAIL       = 0x20,
2192 +       PCF50633_INT4_LEDPWRFAIL        = 0x40,
2193 +       PCF50633_INT4_LEDOVP            = 0x80,
2194 +};
2195 +
2196 +enum pcf50633_reg_int5 {
2197 +       PCF50633_INT5_LDO1PWRFAIL       = 0x01,
2198 +       PCF50633_INT5_LDO2PWRFAIL       = 0x02,
2199 +       PCF50633_INT5_LDO3PWRFAIL       = 0x04,
2200 +       PCF50633_INT5_LDO4PWRFAIL       = 0x08,
2201 +       PCF50633_INT5_LDO5PWRFAIL       = 0x10,
2202 +       PCF50633_INT5_LDO6PWRFAIL       = 0x20,
2203 +       PCF50633_INT5_HCLDOPWRFAIL      = 0x40,
2204 +       PCF50633_INT5_HCLDOOVL          = 0x80,
2205 +};
2206 +
2207 +enum pcf50633_reg_oocshdwn {
2208 +       PCF50633_OOCSHDWN_GOSTDBY       = 0x01,
2209 +       PCF50633_OOCSHDWN_TOTRST        = 0x04,
2210 +       PCF50633_OOCSHDWN_COLDBOOT      = 0x08,
2211 +};
2212 +
2213 +enum pcf50633_reg_oocwake {
2214 +       PCF50633_OOCWAKE_ONKEY          = 0x01,
2215 +       PCF50633_OOCWAKE_EXTON1         = 0x02,
2216 +       PCF50633_OOCWAKE_EXTON2         = 0x04,
2217 +       PCF50633_OOCWAKE_EXTON3         = 0x08,
2218 +       PCF50633_OOCWAKE_RTC            = 0x10,
2219 +       /* reserved */
2220 +       PCF50633_OOCWAKE_USB            = 0x40,
2221 +       PCF50633_OOCWAKE_ADP            = 0x80,
2222 +};
2223 +
2224 +enum pcf50633_reg_mbcc1 {
2225 +       PCF50633_MBCC1_CHGENA           = 0x01, /* Charger enable */
2226 +       PCF50633_MBCC1_AUTOSTOP         = 0x02,
2227 +       PCF50633_MBCC1_AUTORES          = 0x04, /* automatic resume */
2228 +       PCF50633_MBCC1_RESUME           = 0x08, /* explicit resume cmd */
2229 +       PCF50633_MBCC1_RESTART          = 0x10, /* restart charging */
2230 +       PCF50633_MBCC1_PREWDTIME_60M    = 0x20, /* max. precharging time */
2231 +       PCF50633_MBCC1_WDTIME_1H        = 0x00,
2232 +       PCF50633_MBCC1_WDTIME_2H        = 0x40,
2233 +       PCF50633_MBCC1_WDTIME_4H        = 0x80,
2234 +       PCF50633_MBCC1_WDTIME_6H        = 0xc0,
2235 +};
2236 +#define PCF50633_MBCC1_WDTIME_MASK       0xc0
2237 +
2238 +enum pcf50633_reg_mbcc2 {
2239 +       PCF50633_MBCC2_VBATCOND_2V7     = 0x00,
2240 +       PCF50633_MBCC2_VBATCOND_2V85    = 0x01,
2241 +       PCF50633_MBCC2_VBATCOND_3V0     = 0x02,
2242 +       PCF50633_MBCC2_VBATCOND_3V15    = 0x03,
2243 +       PCF50633_MBCC2_VMAX_4V          = 0x00,
2244 +       PCF50633_MBCC2_VMAX_4V20        = 0x28,
2245 +       PCF50633_MBCC2_VRESDEBTIME_64S  = 0x80, /* debounce time (32/64sec) */
2246 +};
2247 +#define        PCF50633_MBCC2_VBATCOND_MASK      0x03
2248 +#define PCF50633_MBCC2_VMAX_MASK         0x3c
2249 +
2250 +enum pcf50633_reg_adcc1 {
2251 +       PCF50633_ADCC1_ADCSTART         = 0x01,
2252 +       PCF50633_ADCC1_RES_10BIT        = 0x02,
2253 +       PCF50633_ADCC1_AVERAGE_NO       = 0x00,
2254 +       PCF50633_ADCC1_AVERAGE_4        = 0x04,
2255 +       PCF50633_ADCC1_AVERAGE_8        = 0x08,
2256 +       PCF50633_ADCC1_AVERAGE_16       = 0x0c,
2257 +
2258 +       PCF50633_ADCC1_MUX_BATSNS_RES   = 0x00,
2259 +       PCF50633_ADCC1_MUX_BATSNS_SUBTR = 0x10,
2260 +       PCF50633_ADCC1_MUX_ADCIN2_RES   = 0x20,
2261 +       PCF50633_ADCC1_MUX_ADCIN2_SUBTR = 0x30,
2262 +       PCF50633_ADCC1_MUX_BATTEMP      = 0x60,
2263 +       PCF50633_ADCC1_MUX_ADCIN1       = 0x70,
2264 +};
2265 +#define PCF50633_ADCC1_AVERAGE_MASK    0x0c
2266 +#define        PCF50633_ADCC1_ADCMUX_MASK      0xf0
2267 +
2268 +enum pcf50633_reg_adcc2 {
2269 +       PCF50633_ADCC2_RATIO_NONE       = 0x00,
2270 +       PCF50633_ADCC2_RATIO_BATTEMP    = 0x01,
2271 +       PCF50633_ADCC2_RATIO_ADCIN1     = 0x02,
2272 +       PCF50633_ADCC2_RATIO_BOTH       = 0x03,
2273 +       PCF50633_ADCC2_RATIOSETTL_100US = 0x04,
2274 +};
2275 +#define PCF50633_ADCC2_RATIO_MASK      0x03
2276 +
2277 +enum pcf50633_reg_adcc3 {
2278 +       PCF50633_ADCC3_ACCSW_EN         = 0x01,
2279 +       PCF50633_ADCC3_NTCSW_EN         = 0x04,
2280 +       PCF50633_ADCC3_RES_DIV_TWO      = 0x10,
2281 +       PCF50633_ADCC3_RES_DIV_THREE    = 0x00,
2282 +};
2283 +
2284 +enum pcf50633_reg_adcs3 {
2285 +       PCF50633_ADCS3_REF_NTCSW        = 0x00,
2286 +       PCF50633_ADCS3_REF_ACCSW        = 0x10,
2287 +       PCF50633_ADCS3_REF_2V0          = 0x20,
2288 +       PCF50633_ADCS3_REF_VISA         = 0x30,
2289 +       PCF50633_ADCS3_REF_2V0_2        = 0x70,
2290 +       PCF50633_ADCS3_ADCRDY           = 0x80,
2291 +};
2292 +#define PCF50633_ADCS3_ADCDAT1L_MASK   0x03
2293 +#define PCF50633_ADCS3_ADCDAT2L_MASK   0x0c
2294 +#define PCF50633_ADCS3_ADCDAT2L_SHIFT  2
2295 +#define PCF50633_ASCS3_REF_MASK                0x70
2296 +
2297 +enum pcf50633_regulator_enable {
2298 +       PCF50633_REGULATOR_ON           = 0x01,
2299 +       PCF50633_REGULATOR_ON_GPIO1     = 0x02,
2300 +       PCF50633_REGULATOR_ON_GPIO2     = 0x04,
2301 +       PCF50633_REGULATOR_ON_GPIO3     = 0x08,
2302 +};
2303 +#define PCF50633_REGULATOR_ON_MASK     0x0f
2304 +
2305 +enum pcf50633_regulator_phase {
2306 +       PCF50633_REGULATOR_ACTPH1       = 0x00,
2307 +       PCF50633_REGULATOR_ACTPH2       = 0x10,
2308 +       PCF50633_REGULATOR_ACTPH3       = 0x20,
2309 +       PCF50633_REGULATOR_ACTPH4       = 0x30,
2310 +};
2311 +#define PCF50633_REGULATOR_ACTPH_MASK  0x30
2312 +
2313 +enum pcf50633_reg_gpocfg {
2314 +       PCF50633_GPOCFG_GPOSEL_0        = 0x00,
2315 +       PCF50633_GPOCFG_GPOSEL_LED_NFET = 0x01,
2316 +       PCF50633_GPOCFG_GPOSEL_SYSxOK   = 0x02,
2317 +       PCF50633_GPOCFG_GPOSEL_CLK32K   = 0x03,
2318 +       PCF50633_GPOCFG_GPOSEL_ADAPUSB  = 0x04,
2319 +       PCF50633_GPOCFG_GPOSEL_USBxOK   = 0x05,
2320 +       PCF50633_GPOCFG_GPOSEL_ACTPH4   = 0x06,
2321 +       PCF50633_GPOCFG_GPOSEL_1        = 0x07,
2322 +       PCF50633_GPOCFG_GPOSEL_INVERSE  = 0x08,
2323 +};
2324 +#define PCF50633_GPOCFG_GPOSEL_MASK    0x07
2325 +
2326 +#if 0
2327 +enum pcf50633_reg_mbcc1 {
2328 +       PCF50633_MBCC1_CHGENA           = 0x01,
2329 +       PCF50633_MBCC1_AUTOSTOP         = 0x02,
2330 +       PCF50633_MBCC1_AUTORES          = 0x04,
2331 +       PCF50633_MBCC1_RESUME           = 0x08,
2332 +       PCF50633_MBCC1_RESTART          = 0x10,
2333 +       PCF50633_MBCC1_PREWDTIME_30MIN  = 0x00,
2334 +       PCF50633_MBCC1_PREWDTIME_60MIN  = 0x20,
2335 +       PCF50633_MBCC1_WDTIME_2HRS      = 0x40,
2336 +       PCF50633_MBCC1_WDTIME_4HRS      = 0x80,
2337 +       PCF50633_MBCC1_WDTIME_6HRS      = 0xc0,
2338 +};
2339 +
2340 +enum pcf50633_reg_mbcc2 {
2341 +       PCF50633_MBCC2_VBATCOND_2V7     = 0x00,
2342 +       PCF50633_MBCC2_VBATCOND_2V85    = 0x01,
2343 +       PCF50633_MBCC2_VBATCOND_3V0     = 0x02,
2344 +       PCF50633_MBCC2_VBATCOND_3V15    = 0x03,
2345 +       PCF50633_MBCC2_VRESDEBTIME_64S  = 0x80,
2346 +};
2347 +#define PCF50633_MBCC2_VMAX_MASK       0x3c
2348 +#endif
2349 +
2350 +enum pcf50633_reg_mbcc7 {
2351 +       PCF50633_MBCC7_USB_100mA        = 0x00,
2352 +       PCF50633_MBCC7_USB_500mA        = 0x01,
2353 +       PCF50633_MBCC7_USB_1000mA       = 0x02,
2354 +       PCF50633_MBCC7_USB_SUSPEND      = 0x03,
2355 +       PCF50633_MBCC7_BATTEMP_EN       = 0x04,
2356 +       PCF50633_MBCC7_BATSYSIMAX_1A6   = 0x00,
2357 +       PCF50633_MBCC7_BATSYSIMAX_1A8   = 0x40,
2358 +       PCF50633_MBCC7_BATSYSIMAX_2A0   = 0x80,
2359 +       PCF50633_MBCC7_BATSYSIMAX_2A2   = 0xc0,
2360 +};
2361 +#define PCF56033_MBCC7_USB_MASK                0x03
2362 +
2363 +enum pcf50633_reg_mbcc8 {
2364 +       PCF50633_MBCC8_USBENASUS        = 0x10,
2365 +};
2366 +
2367 +enum pcf50633_reg_mbcs1 {
2368 +       PCF50633_MBCS1_USBPRES          = 0x01,
2369 +       PCF50633_MBCS1_USBOK            = 0x02,
2370 +       PCF50633_MBCS1_ADAPTPRES        = 0x04,
2371 +       PCF50633_MBCS1_ADAPTOK          = 0x08,
2372 +       PCF50633_MBCS1_TBAT_OK          = 0x00,
2373 +       PCF50633_MBCS1_TBAT_ABOVE       = 0x10,
2374 +       PCF50633_MBCS1_TBAT_BELOW       = 0x20,
2375 +       PCF50633_MBCS1_TBAT_UNDEF       = 0x30,
2376 +       PCF50633_MBCS1_PREWDTEXP        = 0x40,
2377 +       PCF50633_MBCS1_WDTEXP           = 0x80,
2378 +};
2379 +
2380 +enum pcf50633_reg_mbcs2_mbcmod {
2381 +       PCF50633_MBCS2_MBC_PLAY         = 0x00,
2382 +       PCF50633_MBCS2_MBC_USB_PRE      = 0x01,
2383 +       PCF50633_MBCS2_MBC_USB_PRE_WAIT = 0x02,
2384 +       PCF50633_MBCS2_MBC_USB_FAST     = 0x03,
2385 +       PCF50633_MBCS2_MBC_USB_FAST_WAIT= 0x04,
2386 +       PCF50633_MBCS2_MBC_USB_SUSPEND  = 0x05,
2387 +       PCF50633_MBCS2_MBC_ADP_PRE      = 0x06,
2388 +       PCF50633_MBCS2_MBC_ADP_PRE_WAIT = 0x07,
2389 +       PCF50633_MBCS2_MBC_ADP_FAST     = 0x08,
2390 +       PCF50633_MBCS2_MBC_ADP_FAST_WAIT= 0x09,
2391 +       PCF50633_MBCS2_MBC_BAT_FULL     = 0x0a,
2392 +       PCF50633_MBCS2_MBC_HALT         = 0x0b,
2393 +};
2394 +#define PCF50633_MBCS2_MBC_MASK                0x0f
2395 +enum pcf50633_reg_mbcs2_chgstat {
2396 +       PCF50633_MBCS2_CHGS_NONE        = 0x00,
2397 +       PCF50633_MBCS2_CHGS_ADAPTER     = 0x10,
2398 +       PCF50633_MBCS2_CHGS_USB         = 0x20,
2399 +       PCF50633_MBCS2_CHGS_BOTH        = 0x30,
2400 +};
2401 +#define PCF50633_MBCS2_RESSTAT_AUTO    0x40
2402 +
2403 +enum pcf50633_reg_mbcs3 {
2404 +       PCF50633_MBCS3_USBLIM_PLAY      = 0x01,
2405 +       PCF50633_MBCS3_USBLIM_CGH       = 0x02,
2406 +       PCF50633_MBCS3_TLIM_PLAY        = 0x04,
2407 +       PCF50633_MBCS3_TLIM_CHG         = 0x08,
2408 +       PCF50633_MBCS3_ILIM             = 0x10, /* 1: Ibat > Icutoff */
2409 +       PCF50633_MBCS3_VLIM             = 0x20, /* 1: Vbat == Vmax */
2410 +       PCF50633_MBCS3_VBATSTAT         = 0x40, /* 1: Vbat > Vbatcond */
2411 +       PCF50633_MBCS3_VRES             = 0x80, /* 1: Vbat > Vth(RES) */
2412 +};
2413 +
2414 +/* this is to be provided by the board implementation */
2415 +extern const u_int8_t pcf50633_initial_regs[__NUM_PCF50633_REGS];
2416 +
2417 +void pcf50633_reg_write(u_int8_t reg, u_int8_t val);
2418 +
2419 +u_int8_t pcf50633_reg_read(u_int8_t reg);
2420 +
2421 +void pcf50633_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val);
2422 +void pcf50633_reg_clear_bits(u_int8_t reg, u_int8_t bits);
2423 +
2424 +void pcf50633_charge_autofast(int on);
2425 +
2426 +#endif /* _PCF50606_H */
2427 +
2428 diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
2429 index 2cda699..90f53e1 100644
2430 --- a/include/linux/i2c-id.h
2431 +++ b/include/linux/i2c-id.h
2432 @@ -95,6 +95,7 @@
2433  
2434  #define I2C_DRIVERID_OV7670 1048       /* Omnivision 7670 camera */
2435  #define I2C_DRIVERID_PCF50606 1049
2436 +#define I2C_DRIVERID_PCF50633 1051
2437  
2438  /*
2439   * ---- Adapter types ----------------------------------------------------
2440 diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
2441 new file mode 100644
2442 index 0000000..5f32004
2443 --- /dev/null
2444 +++ b/include/linux/pcf50633.h
2445 @@ -0,0 +1,114 @@
2446 +#ifndef _LINUX_PCF50633_H
2447 +#define _LINUX_PCF50633_H
2448 +
2449 +/* public in-kernel pcf50633 api */
2450 +enum pcf50633_regulator_id {
2451 +       PCF50633_REGULATOR_AUTO,
2452 +       PCF50633_REGULATOR_DOWN1,
2453 +       PCF50633_REGULATOR_DOWN2,
2454 +       PCF50633_REGULATOR_MEMLDO,
2455 +       PCF50633_REGULATOR_LDO1,
2456 +       PCF50633_REGULATOR_LDO2,
2457 +       PCF50633_REGULATOR_LDO3,
2458 +       PCF50633_REGULATOR_LDO4,
2459 +       PCF50633_REGULATOR_LDO5,
2460 +       PCF50633_REGULATOR_LDO6,
2461 +       PCF50633_REGULATOR_HCLDO,
2462 +       __NUM_PCF50633_REGULATORS
2463 +};
2464 +
2465 +struct pcf50633_data;
2466 +extern struct pcf50633_data *pcf50633_global;
2467 +
2468 +extern void
2469 +pcf50633_go_standby(void);
2470 +
2471 +enum pcf50633_gpio {
2472 +       PCF50633_GPIO1 = 1,
2473 +       PCF50633_GPIO2 = 2,
2474 +       PCF50633_GPIO3 = 3,
2475 +       PCF50633_GPO = 4,
2476 +};
2477 +
2478 +extern void
2479 +pcf50633_gpio_set(struct pcf50633_data *pcf, enum pcf50633_gpio gpio, int on);
2480 +
2481 +extern int
2482 +pcf50633_gpio_get(struct pcf50633_data *pcf, enum pcf50633_gpio gpio);
2483 +
2484 +extern int
2485 +pcf50633_voltage_set(struct pcf50633_data *pcf,
2486 +                    enum pcf50633_regulator_id reg,
2487 +                    unsigned int millivolts);
2488 +extern unsigned int
2489 +pcf50633_voltage_get(struct pcf50633_data *pcf,
2490 +                    enum pcf50633_regulator_id reg);
2491 +extern int
2492 +pcf50633_onoff_get(struct pcf50633_data *pcf,
2493 +                  enum pcf50633_regulator_id reg);
2494 +
2495 +extern int
2496 +pcf50633_onoff_set(struct pcf50633_data *pcf,
2497 +                  enum pcf50633_regulator_id reg, int on);
2498 +
2499 +extern void
2500 +pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma);
2501 +
2502 +extern void
2503 +pcf50633_charge_enable(struct pcf50633_data *pcf, int on);
2504 +
2505 +/* FIXME: sharded with pcf50606 */
2506 +#define PMU_VRAIL_F_SUSPEND_ON 0x00000001      /* Remains on during suspend */
2507 +#define PMU_VRAIL_F_UNUSED     0x00000002      /* This rail is not used */
2508 +struct pmu_voltage_rail {
2509 +       char *name;
2510 +       unsigned int flags;
2511 +       struct {
2512 +               unsigned int init;
2513 +               unsigned int max;
2514 +       } voltage;
2515 +};
2516 +
2517 +enum pmu_event {
2518 +       PMU_EVT_NONE,
2519 +       PMU_EVT_INSERT,
2520 +       PMU_EVT_REMOVE,
2521 +       PMU_EVT_USB_INSERT,
2522 +       PMU_EVT_USB_REMOVE,
2523 +       __NUM_PMU_EVTS
2524 +};
2525 +
2526 +typedef int pmu_cb(struct device *dev, unsigned int feature,
2527 +                  enum pmu_event event);
2528 +
2529 +#define PCF50633_FEAT_EXTON    0x00000001      /* not yet supported */
2530 +#define PCF50633_FEAT_MBC      0x00000002
2531 +#define PCF50633_FEAT_BBC      0x00000004      /* not yet supported */
2532 +#define PCF50633_FEAT_RTC      0x00000040
2533 +#define PCF50633_FEAT_CHGCUR   0x00000100
2534 +#define PCF50633_FEAT_BATVOLT  0x00000200
2535 +#define PCF50633_FEAT_BATTEMP  0x00000400
2536 +#define PCF50633_FEAT_PWM_BL   0x00000800
2537 +
2538 +struct pcf50633_platform_data {
2539 +       /* general */
2540 +       unsigned int used_features;
2541 +       unsigned int onkey_seconds_sig_init;
2542 +       unsigned int onkey_seconds_shutdown;
2543 +
2544 +       /* voltage regulator related */
2545 +       struct pmu_voltage_rail rails[__NUM_PCF50633_REGULATORS];
2546 +       unsigned int used_regulators;
2547 +
2548 +       /* charger related */
2549 +       unsigned int r_fix_batt;
2550 +       unsigned int r_fix_batt_par;
2551 +       unsigned int r_sense_milli;
2552 +
2553 +       struct {
2554 +               u_int8_t mbcc3; /* charger voltage / current */
2555 +       } charger;
2556 +       pmu_cb *cb;
2557 +};
2558 +
2559 +#endif /* _PCF50633_H */
2560 -- 
2561 1.5.6.3
2562