disable IMQ on 2.6.28 as well -- people should use IFB..
[openwrt.git] / target / linux / s3c24xx / patches / 0006-gta01-pcf50606.patch.patch
1 From cb7ab7ce6ad690be5f71bde73a9369d3640985e8 Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Wed, 16 Jul 2008 14:44:11 +0100
4 Subject: [PATCH] gta01-pcf50606.patch
5  This is a NXP PCF50606 power management unit driver.
6
7 The PCF50606 is used in the FIC/OpenMoko Neo1973 GTA01 GSM phone.
8
9 Signed-off-by: Harald Welte <laforge@openmoko.org>
10 ---
11  drivers/i2c/chips/Kconfig    |   11 +
12  drivers/i2c/chips/Makefile   |    1 +
13  drivers/i2c/chips/pcf50606.c | 1945 ++++++++++++++++++++++++++++++++++++++++++
14  drivers/i2c/chips/pcf50606.h |  302 +++++++
15  include/linux/i2c-id.h       |    1 +
16  include/linux/pcf50606.h     |  108 +++
17  6 files changed, 2368 insertions(+), 0 deletions(-)
18  create mode 100644 drivers/i2c/chips/pcf50606.c
19  create mode 100644 drivers/i2c/chips/pcf50606.h
20  create mode 100644 include/linux/pcf50606.h
21
22 diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
23 index 2da2edf..e8e64aa 100644
24 --- a/drivers/i2c/chips/Kconfig
25 +++ b/drivers/i2c/chips/Kconfig
26 @@ -25,6 +25,17 @@ config SENSORS_EEPROM
27           This driver can also be built as a module.  If so, the module
28           will be called eeprom.
29  
30 +config SENSORS_PCF50606
31 +       tristate "Philips/NXP PCF50606"
32 +       depends on I2C
33 +       help
34 +         If you say yes here you get support for Philips/NXP PCF50606
35 +         PMU (Power Management Unit) chips.
36 +
37 +         This driver can also be built as a module.  If so, the module
38 +         will be called pcf50606.
39 +
40 +
41  config SENSORS_PCF8574
42         tristate "Philips PCF8574 and PCF8574A"
43         depends on EXPERIMENTAL
44 diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
45 index e47aca0..60d3d5a 100644
46 --- a/drivers/i2c/chips/Makefile
47 +++ b/drivers/i2c/chips/Makefile
48 @@ -13,6 +13,7 @@ obj-$(CONFIG_DS1682)          += ds1682.o
49  obj-$(CONFIG_SENSORS_EEPROM)   += eeprom.o
50  obj-$(CONFIG_SENSORS_MAX6875)  += max6875.o
51  obj-$(CONFIG_SENSORS_PCA9539)  += pca9539.o
52 +obj-$(CONFIG_SENSORS_PCF50606) += pcf50606.o
53  obj-$(CONFIG_SENSORS_PCF8574)  += pcf8574.o
54  obj-$(CONFIG_PCF8575)          += pcf8575.o
55  obj-$(CONFIG_SENSORS_PCF8591)  += pcf8591.o
56 diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
57 new file mode 100644
58 index 0000000..6626c68
59 --- /dev/null
60 +++ b/drivers/i2c/chips/pcf50606.c
61 @@ -0,0 +1,1945 @@
62 +/* Philips/NXP PCF50606 Power Management Unit (PMU) driver
63 + *
64 + * (C) 2006-2007 by OpenMoko, Inc.
65 + * Authors: Harald Welte <laforge@openmoko.org>,
66 + *         Matt Hsu <matt@openmoko.org>
67 + * All rights reserved.
68 + *
69 + * This program is free software; you can redistribute it and/or
70 + * modify it under the terms of the GNU General Public License as
71 + * published by the Free Software Foundation; either version 2 of
72 + * the License, or (at your option) any later version.
73 + *
74 + * This program is distributed in the hope that it will be useful,
75 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
76 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
77 + * GNU General Public License for more details.
78 + *
79 + * You should have received a copy of the GNU General Public License
80 + * along with this program; if not, write to the Free Software
81 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
82 + * MA 02111-1307 USA
83 + *
84 + * This driver is a monster ;) It provides the following features
85 + * - voltage control for a dozen different voltage domains
86 + * - charging control for main and backup battery
87 + * - rtc / alarm
88 + * - watchdog
89 + * - adc driver (hw_sensors like)
90 + * - pwm driver
91 + * - backlight
92 + *
93 + */
94 +
95 +#include <linux/module.h>
96 +#include <linux/init.h>
97 +#include <linux/i2c.h>
98 +#include <linux/types.h>
99 +#include <linux/interrupt.h>
100 +#include <linux/irq.h>
101 +#include <linux/workqueue.h>
102 +#include <linux/rtc.h>
103 +#include <linux/bcd.h>
104 +#include <linux/watchdog.h>
105 +#include <linux/miscdevice.h>
106 +#include <linux/input.h>
107 +#include <linux/fb.h>
108 +#include <linux/backlight.h>
109 +#include <linux/sched.h>
110 +#include <linux/platform_device.h>
111 +#include <linux/pcf50606.h>
112 +#include <linux/apm-emulation.h>
113 +
114 +#include <asm/mach-types.h>
115 +#include <asm/arch/gta01.h>
116 +
117 +#include "pcf50606.h"
118 +
119 +/* we use dev_dbg() throughout the code, but sometimes don't want to
120 + * write an entire line of debug related information.  This DEBUGPC
121 + * macro is a continuation for dev_dbg() */
122 +#ifdef DEBUG
123 +#define DEBUGPC(x, args ...) printk(x, ## args)
124 +#else
125 +#define DEBUGPC(x, args ...)
126 +#endif
127 +
128 +/***********************************************************************
129 + * Static data / structures
130 + ***********************************************************************/
131 +
132 +static unsigned short normal_i2c[] = { 0x08, I2C_CLIENT_END };
133 +
134 +I2C_CLIENT_INSMOD_1(pcf50606);
135 +
136 +#define PCF50606_F_CHG_FAST    0x00000001      /* Charger Fast allowed */
137 +#define PCF50606_F_CHG_PRESENT 0x00000002      /* Charger present */
138 +#define PCF50606_F_CHG_FOK     0x00000004      /* Fast OK for battery */
139 +#define PCF50606_F_CHG_ERR     0x00000008      /* Charger Error */
140 +#define PCF50606_F_CHG_PROT    0x00000010      /* Charger Protection */
141 +#define PCF50606_F_CHG_READY   0x00000020      /* Charging completed */
142 +#define PCF50606_F_CHG_MASK    0x000000fc
143 +
144 +#define PCF50606_F_PWR_PRESSED 0x00000100
145 +#define PCF50606_F_RTC_SECOND  0x00000200
146 +
147 +enum close_state {
148 +       CLOSE_STATE_NOT,
149 +       CLOSE_STATE_ALLOW = 0x2342,
150 +};
151 +
152 +struct pcf50606_data {
153 +       struct i2c_client client;
154 +       struct pcf50606_platform_data *pdata;
155 +       struct backlight_device *backlight;
156 +       struct mutex lock;
157 +       unsigned int flags;
158 +       unsigned int working;
159 +       struct mutex working_lock;
160 +       struct work_struct work;
161 +       struct rtc_device *rtc;
162 +       struct input_dev *input_dev;
163 +       int allow_close;
164 +       int onkey_seconds;
165 +       int irq;
166 +#ifdef CONFIG_PM
167 +       struct {
168 +               u_int8_t dcdc1, dcdc2;
169 +               u_int8_t dcdec1;
170 +               u_int8_t dcudc1;
171 +               u_int8_t ioregc;
172 +               u_int8_t d1regc1;
173 +               u_int8_t d2regc1;
174 +               u_int8_t d3regc1;
175 +               u_int8_t lpregc1;
176 +               u_int8_t adcc1, adcc2;
177 +               u_int8_t pwmc1;
178 +               u_int8_t int1m, int2m, int3m;
179 +       } standby_regs;
180 +#endif
181 +};
182 +
183 +static struct i2c_driver pcf50606_driver;
184 +
185 +/* This is an ugly construct on how to access the (currently single/global)
186 + * pcf50606 handle from other code in the kernel.  I didn't really come up with
187 + * a more decent method of dynamically resolving this */
188 +struct pcf50606_data *pcf50606_global;
189 +EXPORT_SYMBOL_GPL(pcf50606_global);
190 +
191 +static struct platform_device *pcf50606_pdev;
192 +
193 +/* This is a 10k, B=3370 NTC Thermistor -10..79 centigrade */
194 +/* Table entries are offset by +0.5C so a properly rounded value is generated */
195 +static const u_int16_t ntc_table_10k_3370B[] = {
196 +       /* -10 */
197 +       43888, 41819, 39862, 38010, 36257, 34596, 33024, 31534, 30121, 28781,
198 +       27510, 26304, 25159, 24071, 23038, 22056, 21122, 20234, 19390, 18586,
199 +       17821, 17093, 16399, 15738, 15107, 14506, 13933, 13387, 12865, 12367,
200 +       11891, 11437, 11003, 10588, 10192, 9813, 9450, 9103, 8771, 8453,
201 +       8149, 7857, 7578, 7310, 7054, 6808, 6572, 6346, 6129, 5920,
202 +       5720, 5528, 5344, 5167, 4996, 4833, 4675, 4524, 4379, 4239,
203 +       4104, 3975, 3850, 3730, 3614, 3503, 3396, 3292, 3193, 3097,
204 +       3004, 2915, 2829, 2745, 2665, 2588, 2513, 2441, 2371, 2304,
205 +       2239, 2176, 2116, 2057, 2000, 1945, 1892, 1841, 1791, 1743,
206 +};
207 +
208 +
209 +/***********************************************************************
210 + * Low-Level routines
211 + ***********************************************************************/
212 +
213 +static inline int __reg_write(struct pcf50606_data *pcf, u_int8_t reg,
214 +                             u_int8_t val)
215 +{
216 +       return i2c_smbus_write_byte_data(&pcf->client, reg, val);
217 +}
218 +
219 +static int reg_write(struct pcf50606_data *pcf, u_int8_t reg, u_int8_t val)
220 +{
221 +       int ret;
222 +
223 +       mutex_lock(&pcf->lock);
224 +       ret = __reg_write(pcf, reg, val);
225 +       mutex_unlock(&pcf->lock);
226 +
227 +       return ret;
228 +}
229 +
230 +static inline int32_t __reg_read(struct pcf50606_data *pcf, u_int8_t reg)
231 +{
232 +       int32_t ret;
233 +
234 +       ret = i2c_smbus_read_byte_data(&pcf->client, reg);
235 +
236 +       return ret;
237 +}
238 +
239 +static u_int8_t reg_read(struct pcf50606_data *pcf, u_int8_t reg)
240 +{
241 +       int32_t ret;
242 +
243 +       mutex_lock(&pcf->lock);
244 +       ret = __reg_read(pcf, reg);
245 +       mutex_unlock(&pcf->lock);
246 +
247 +       return ret & 0xff;
248 +}
249 +
250 +static int reg_set_bit_mask(struct pcf50606_data *pcf,
251 +                           u_int8_t reg, u_int8_t mask, u_int8_t val)
252 +{
253 +       int ret;
254 +       u_int8_t tmp;
255 +
256 +       val &= mask;
257 +
258 +       mutex_lock(&pcf->lock);
259 +
260 +       tmp = __reg_read(pcf, reg);
261 +       tmp &= ~mask;
262 +       tmp |= val;
263 +       ret = __reg_write(pcf, reg, tmp);
264 +
265 +       mutex_unlock(&pcf->lock);
266 +
267 +       return ret;
268 +}
269 +
270 +static int reg_clear_bits(struct pcf50606_data *pcf, u_int8_t reg, u_int8_t val)
271 +{
272 +       int ret;
273 +       u_int8_t tmp;
274 +
275 +       mutex_lock(&pcf->lock);
276 +
277 +       tmp = __reg_read(pcf, reg);
278 +       tmp &= ~val;
279 +       ret = __reg_write(pcf, reg, tmp);
280 +
281 +       mutex_unlock(&pcf->lock);
282 +
283 +       return ret;
284 +}
285 +
286 +/* synchronously read one ADC channel (busy-wait for result to be complete) */
287 +static u_int16_t adc_read(struct pcf50606_data *pcf,  int channel,
288 +                         u_int16_t *data2)
289 +{
290 +       u_int8_t adcs2, adcs1;
291 +       u_int16_t ret;
292 +
293 +       dev_dbg(&pcf->client.dev, "entering (pcf=%p, channel=%u, data2=%p)\n",
294 +               pcf, channel, data2);
295 +
296 +       channel &= PCF50606_ADCC2_ADCMUX_MASK;
297 +
298 +       mutex_lock(&pcf->lock);
299 +
300 +       /* start ADC conversion of selected channel */
301 +       __reg_write(pcf, PCF50606_REG_ADCC2, channel |
302 +                   PCF50606_ADCC2_ADCSTART | PCF50606_ADCC2_RES_10BIT);
303 +
304 +       do {
305 +               adcs2 = __reg_read(pcf, PCF50606_REG_ADCS2);
306 +       } while (!(adcs2 & PCF50606_ADCS2_ADCRDY));
307 +
308 +       adcs1 = __reg_read(pcf, PCF50606_REG_ADCS1);
309 +       ret = (adcs1 << 2) | (adcs2 & 0x03);
310 +
311 +       if (data2) {
312 +               adcs1 = __reg_read(pcf, PCF50606_REG_ADCS3);
313 +               *data2 = (adcs1 << 2) | ((adcs2 & 0x0c) >> 2);
314 +       }
315 +
316 +       mutex_unlock(&pcf->lock);
317 +
318 +       dev_dbg(&pcf->client.dev, "returning %u %u\n", ret,
319 +               data2 ? *data2 : 0);
320 +
321 +       return ret;
322 +}
323 +
324 +/***********************************************************************
325 + * Voltage / ADC
326 + ***********************************************************************/
327 +
328 +static u_int8_t dcudc_voltage(unsigned int millivolts)
329 +{
330 +       if (millivolts < 900)
331 +               return 0;
332 +       if (millivolts > 5500)
333 +               return 0x1f;
334 +       if (millivolts <= 3300) {
335 +               millivolts -= 900;
336 +               return millivolts/300;
337 +       }
338 +       if (millivolts < 4000)
339 +               return 0x0f;
340 +       else {
341 +               millivolts -= 4000;
342 +               return millivolts/100;
343 +       }
344 +}
345 +
346 +static unsigned int dcudc_2voltage(u_int8_t bits)
347 +{
348 +       bits &= 0x1f;
349 +       if (bits < 0x08)
350 +               return 900 + bits * 300;
351 +       else if (bits < 0x10)
352 +               return 3300;
353 +       else
354 +               return 4000 + bits * 100;
355 +}
356 +
357 +static u_int8_t dcdec_voltage(unsigned int millivolts)
358 +{
359 +       if (millivolts < 900)
360 +               return 0;
361 +       else if (millivolts > 3300)
362 +               return 0x0f;
363 +
364 +       millivolts -= 900;
365 +       return millivolts/300;
366 +}
367 +
368 +static unsigned int dcdec_2voltage(u_int8_t bits)
369 +{
370 +       bits &= 0x0f;
371 +       return 900 + bits*300;
372 +}
373 +
374 +static u_int8_t dcdc_voltage(unsigned int millivolts)
375 +{
376 +       if (millivolts < 900)
377 +               return 0;
378 +       else if (millivolts > 3600)
379 +               return 0x1f;
380 +
381 +       if (millivolts < 1500) {
382 +               millivolts -= 900;
383 +               return millivolts/25;
384 +       } else {
385 +               millivolts -= 1500;
386 +               return 0x18 + millivolts/300;
387 +       }
388 +}
389 +
390 +static unsigned int dcdc_2voltage(u_int8_t bits)
391 +{
392 +       bits &= 0x1f;
393 +       if ((bits & 0x18) == 0x18)
394 +               return 1500 + ((bits & 0x7) * 300);
395 +       else
396 +               return 900 + (bits * 25);
397 +}
398 +
399 +static u_int8_t dx_voltage(unsigned int millivolts)
400 +{
401 +       if (millivolts < 900)
402 +               return 0;
403 +       else if (millivolts > 3300)
404 +               return 0x18;
405 +
406 +       millivolts -= 900;
407 +       return millivolts/100;
408 +}
409 +
410 +static unsigned int dx_2voltage(u_int8_t bits)
411 +{
412 +       bits &= 0x1f;
413 +       return 900 + (bits * 100);
414 +}
415 +
416 +static const u_int8_t regulator_registers[__NUM_PCF50606_REGULATORS] = {
417 +       [PCF50606_REGULATOR_DCD]        = PCF50606_REG_DCDC1,
418 +       [PCF50606_REGULATOR_DCDE]       = PCF50606_REG_DCDEC1,
419 +       [PCF50606_REGULATOR_DCUD]       = PCF50606_REG_DCUDC1,
420 +       [PCF50606_REGULATOR_D1REG]      = PCF50606_REG_D1REGC1,
421 +       [PCF50606_REGULATOR_D2REG]      = PCF50606_REG_D2REGC1,
422 +       [PCF50606_REGULATOR_D3REG]      = PCF50606_REG_D3REGC1,
423 +       [PCF50606_REGULATOR_LPREG]      = PCF50606_REG_LPREGC1,
424 +       [PCF50606_REGULATOR_IOREG]      = PCF50606_REG_IOREGC,
425 +};
426 +
427 +int pcf50606_onoff_set(struct pcf50606_data *pcf,
428 +                      enum pcf50606_regulator_id reg, int on)
429 +{
430 +       u_int8_t addr;
431 +
432 +       if (reg >= __NUM_PCF50606_REGULATORS)
433 +               return -EINVAL;
434 +
435 +       /* IOREG cannot be powered off since it powers the PMU I2C */
436 +       if (reg == PCF50606_REGULATOR_IOREG)
437 +               return -EIO;
438 +
439 +       addr = regulator_registers[reg];
440 +
441 +       if (on == 0)
442 +               reg_set_bit_mask(pcf, addr, 0xe0, 0x00);
443 +       else
444 +               reg_set_bit_mask(pcf, addr, 0xe0, 0xe0);
445 +
446 +       return 0;
447 +}
448 +EXPORT_SYMBOL_GPL(pcf50606_onoff_set);
449 +
450 +int pcf50606_onoff_get(struct pcf50606_data *pcf,
451 +                      enum pcf50606_regulator_id reg)
452 +{
453 +       u_int8_t val, addr;
454 +
455 +       if (reg >= __NUM_PCF50606_REGULATORS)
456 +               return -EINVAL;
457 +
458 +       addr = regulator_registers[reg];
459 +       val = (reg_read(pcf, addr) & 0xe0) >> 5;
460 +
461 +       /* PWREN1 = 1, PWREN2 = 1, see table 16 of datasheet */
462 +       switch (val) {
463 +       case 0:
464 +       case 5:
465 +               return 0;
466 +       default:
467 +               return 1;
468 +       }
469 +}
470 +EXPORT_SYMBOL_GPL(pcf50606_onoff_get);
471 +
472 +int pcf50606_voltage_set(struct pcf50606_data *pcf,
473 +                        enum pcf50606_regulator_id reg,
474 +                        unsigned int millivolts)
475 +{
476 +       u_int8_t volt_bits;
477 +       u_int8_t regnr;
478 +       int rc;
479 +
480 +       dev_dbg(&pcf->client.dev, "pcf=%p, reg=%d, mvolts=%d\n", pcf, reg,
481 +               millivolts);
482 +
483 +       if (reg >= __NUM_PCF50606_REGULATORS)
484 +               return -EINVAL;
485 +
486 +       if (millivolts > pcf->pdata->rails[reg].voltage.max)
487 +               return -EINVAL;
488 +
489 +       switch (reg) {
490 +       case PCF50606_REGULATOR_DCD:
491 +               volt_bits = dcdc_voltage(millivolts);
492 +               rc = reg_set_bit_mask(pcf, PCF50606_REG_DCDC1, 0x1f,
493 +                                     volt_bits);
494 +               break;
495 +       case PCF50606_REGULATOR_DCDE:
496 +               volt_bits = dcdec_voltage(millivolts);
497 +               rc = reg_set_bit_mask(pcf, PCF50606_REG_DCDEC1, 0x0f,
498 +                                     volt_bits);
499 +               break;
500 +       case PCF50606_REGULATOR_DCUD:
501 +               volt_bits = dcudc_voltage(millivolts);
502 +               rc = reg_set_bit_mask(pcf, PCF50606_REG_DCUDC1, 0x1f,
503 +                                     volt_bits);
504 +               break;
505 +       case PCF50606_REGULATOR_D1REG:
506 +       case PCF50606_REGULATOR_D2REG:
507 +       case PCF50606_REGULATOR_D3REG:
508 +               regnr = PCF50606_REG_D1REGC1 + (reg - PCF50606_REGULATOR_D1REG);
509 +               volt_bits = dx_voltage(millivolts);
510 +               rc = reg_set_bit_mask(pcf, regnr, 0x1f, volt_bits);
511 +               break;
512 +       case PCF50606_REGULATOR_LPREG:
513 +               volt_bits = dx_voltage(millivolts);
514 +               rc = reg_set_bit_mask(pcf, PCF50606_REG_LPREGC1, 0x1f,
515 +                                     volt_bits);
516 +               break;
517 +       case PCF50606_REGULATOR_IOREG:
518 +               if (millivolts < 1800)
519 +                       return -EINVAL;
520 +               volt_bits = dx_voltage(millivolts);
521 +               rc = reg_set_bit_mask(pcf, PCF50606_REG_IOREGC, 0x1f,
522 +                                     volt_bits);
523 +               break;
524 +       default:
525 +               return -EINVAL;
526 +       }
527 +
528 +       return rc;
529 +}
530 +EXPORT_SYMBOL_GPL(pcf50606_voltage_set);
531 +
532 +unsigned int pcf50606_voltage_get(struct pcf50606_data *pcf,
533 +                        enum pcf50606_regulator_id reg)
534 +{
535 +       u_int8_t volt_bits;
536 +       u_int8_t regnr;
537 +       unsigned int rc = 0;
538 +
539 +       if (reg >= __NUM_PCF50606_REGULATORS)
540 +               return -EINVAL;
541 +
542 +       switch (reg) {
543 +       case PCF50606_REGULATOR_DCD:
544 +               volt_bits = reg_read(pcf, PCF50606_REG_DCDC1) & 0x1f;
545 +               rc = dcdc_2voltage(volt_bits);
546 +               break;
547 +       case PCF50606_REGULATOR_DCDE:
548 +               volt_bits = reg_read(pcf, PCF50606_REG_DCDEC1) & 0x0f;
549 +               rc = dcdec_2voltage(volt_bits);
550 +               break;
551 +       case PCF50606_REGULATOR_DCUD:
552 +               volt_bits = reg_read(pcf, PCF50606_REG_DCUDC1) & 0x1f;
553 +               rc = dcudc_2voltage(volt_bits);
554 +               break;
555 +       case PCF50606_REGULATOR_D1REG:
556 +       case PCF50606_REGULATOR_D2REG:
557 +       case PCF50606_REGULATOR_D3REG:
558 +               regnr = PCF50606_REG_D1REGC1 + (reg - PCF50606_REGULATOR_D1REG);
559 +               volt_bits = reg_read(pcf, regnr) & 0x1f;
560 +               if (volt_bits > 0x18)
561 +                       volt_bits = 0x18;
562 +               rc = dx_2voltage(volt_bits);
563 +               break;
564 +       case PCF50606_REGULATOR_LPREG:
565 +               volt_bits = reg_read(pcf, PCF50606_REG_LPREGC1) & 0x1f;
566 +               if (volt_bits > 0x18)
567 +                       volt_bits = 0x18;
568 +               rc = dx_2voltage(volt_bits);
569 +               break;
570 +       case PCF50606_REGULATOR_IOREG:
571 +               volt_bits = reg_read(pcf, PCF50606_REG_IOREGC) & 0x1f;
572 +               if (volt_bits > 0x18)
573 +                       volt_bits = 0x18;
574 +               rc = dx_2voltage(volt_bits);
575 +               break;
576 +       default:
577 +               return -EINVAL;
578 +       }
579 +
580 +       return rc;
581 +}
582 +EXPORT_SYMBOL_GPL(pcf50606_voltage_get);
583 +
584 +/* go into 'STANDBY' mode, i.e. power off the main CPU and peripherals */
585 +void pcf50606_go_standby(void)
586 +{
587 +       reg_write(pcf50606_global, PCF50606_REG_OOCC1,
588 +                 PCF50606_OOCC1_GOSTDBY);
589 +}
590 +EXPORT_SYMBOL_GPL(pcf50606_go_standby);
591 +
592 +void pcf50606_gpo0_set(struct pcf50606_data *pcf, int on)
593 +{
594 +       u_int8_t val;
595 +
596 +       if (on)
597 +               val = 0x07;
598 +       else
599 +               val = 0x0f;
600 +
601 +       reg_set_bit_mask(pcf, PCF50606_REG_GPOC1, 0x0f, val);
602 +}
603 +EXPORT_SYMBOL_GPL(pcf50606_gpo0_set);
604 +
605 +int pcf50606_gpo0_get(struct pcf50606_data *pcf)
606 +{
607 +       u_int8_t reg = reg_read(pcf, PCF50606_REG_GPOC1) & 0x0f;
608 +
609 +       if (reg == 0x07 || reg == 0x08)
610 +               return 1;
611 +
612 +       return 0;
613 +}
614 +EXPORT_SYMBOL_GPL(pcf50606_gpo0_get);
615 +
616 +static void pcf50606_work(struct work_struct *work)
617 +{
618 +       struct pcf50606_data *pcf =
619 +                       container_of(work, struct pcf50606_data, work);
620 +       u_int8_t pcfirq[3];
621 +       int ret;
622 +
623 +       mutex_lock(&pcf->working_lock);
624 +       pcf->working = 1;
625 +       /*
626 +        * p35 pcf50606 datasheet rev 2.2:
627 +        * ''The system controller shall read all interrupt registers in
628 +        *   one I2C read action''
629 +        * because if you don't INT# gets stuck asserted forever after a
630 +        * while
631 +        */
632 +       ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50606_REG_INT1, 3,
633 +                                           pcfirq);
634 +       if (ret != 3)
635 +               DEBUGPC("Oh crap PMU IRQ register read failed %d\n", ret);
636 +
637 +       dev_dbg(&pcf->client.dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x:",
638 +               pcfirq[0], pcfirq[1], pcfirq[2]);
639 +
640 +       if (pcfirq[0] & PCF50606_INT1_ONKEYF) {
641 +               /* ONKEY falling edge (start of button press) */
642 +               DEBUGPC("ONKEYF ");
643 +               pcf->flags |= PCF50606_F_PWR_PRESSED;
644 +               input_report_key(pcf->input_dev, KEY_POWER, 1);
645 +       }
646 +       if (pcfirq[0] & PCF50606_INT1_ONKEY1S) {
647 +               /* ONKEY pressed for more than 1 second */
648 +               pcf->onkey_seconds = 0;
649 +               DEBUGPC("ONKEY1S ");
650 +               /* Tell PMU we are taking care of this */
651 +               reg_set_bit_mask(pcf, PCF50606_REG_OOCC1,
652 +                                PCF50606_OOCC1_TOTRST,
653 +                                PCF50606_OOCC1_TOTRST);
654 +               /* enable SECOND interrupt (hz tick) */
655 +               reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND);
656 +       }
657 +       if (pcfirq[0] & PCF50606_INT1_ONKEYR) {
658 +               /* ONKEY rising edge (end of button press) */
659 +               DEBUGPC("ONKEYR ");
660 +               pcf->flags &= ~PCF50606_F_PWR_PRESSED;
661 +               pcf->onkey_seconds = -1;
662 +               input_report_key(pcf->input_dev, KEY_POWER, 0);
663 +               /* disable SECOND interrupt in case RTC didn't
664 +                * request it */
665 +               if (!(pcf->flags & PCF50606_F_RTC_SECOND))
666 +                       reg_set_bit_mask(pcf, PCF50606_REG_INT1M,
667 +                                        PCF50606_INT1_SECOND,
668 +                                        PCF50606_INT1_SECOND);
669 +       }
670 +       if (pcfirq[0] & PCF50606_INT1_EXTONR) {
671 +               DEBUGPC("EXTONR ");
672 +               input_report_key(pcf->input_dev, KEY_POWER2, 1);
673 +       }
674 +       if (pcfirq[0] & PCF50606_INT1_EXTONF) {
675 +               DEBUGPC("EXTONF ");
676 +               input_report_key(pcf->input_dev, KEY_POWER2, 0);
677 +       }
678 +       if (pcfirq[0] & PCF50606_INT1_SECOND) {
679 +               DEBUGPC("SECOND ");
680 +               if (pcf->flags & PCF50606_F_RTC_SECOND)
681 +                       rtc_update_irq(pcf->rtc, 1,
682 +                                      RTC_PF | RTC_IRQF);
683 +
684 +               if (pcf->onkey_seconds >= 0 &&
685 +                   pcf->flags & PCF50606_F_PWR_PRESSED) {
686 +                       DEBUGPC("ONKEY_SECONDS(%u, OOCC1=0x%02x) ",
687 +                               pcf->onkey_seconds,
688 +                               reg_read(pcf, PCF50606_REG_OOCC1));
689 +                       pcf->onkey_seconds++;
690 +                       if (pcf->onkey_seconds >=
691 +                           pcf->pdata->onkey_seconds_required) {
692 +                               /* Ask init to do 'ctrlaltdel' */
693 +                               DEBUGPC("SIGINT(init) ");
694 +                               kill_proc(1, SIGINT, 1);
695 +                               /* FIXME: what to do if userspace doesn't
696 +                                * shut down? Do we want to force it? */
697 +                       }
698 +               }
699 +       }
700 +       if (pcfirq[0] & PCF50606_INT1_ALARM) {
701 +               DEBUGPC("ALARM ");
702 +               if (pcf->pdata->used_features & PCF50606_FEAT_RTC)
703 +                       rtc_update_irq(pcf->rtc, 1,
704 +                                      RTC_AF | RTC_IRQF);
705 +       }
706 +
707 +       if (pcfirq[1] & PCF50606_INT2_CHGINS) {
708 +               /* Charger inserted */
709 +               DEBUGPC("CHGINS ");
710 +               input_report_key(pcf->input_dev, KEY_BATTERY, 1);
711 +               apm_queue_event(APM_POWER_STATUS_CHANGE);
712 +               pcf->flags |= PCF50606_F_CHG_PRESENT;
713 +               if (pcf->pdata->cb)
714 +                       pcf->pdata->cb(&pcf->client.dev,
715 +                                      PCF50606_FEAT_MBC, PMU_EVT_INSERT);
716 +               /* FIXME: how to signal this to userspace */
717 +       }
718 +       if (pcfirq[1] & PCF50606_INT2_CHGRM) {
719 +               /* Charger removed */
720 +               DEBUGPC("CHGRM ");
721 +               input_report_key(pcf->input_dev, KEY_BATTERY, 0);
722 +               apm_queue_event(APM_POWER_STATUS_CHANGE);
723 +               pcf->flags &= ~(PCF50606_F_CHG_MASK|PCF50606_F_CHG_PRESENT);
724 +               if (pcf->pdata->cb)
725 +                       pcf->pdata->cb(&pcf->client.dev,
726 +                                      PCF50606_FEAT_MBC, PMU_EVT_INSERT);
727 +               /* FIXME: how signal this to userspace */
728 +       }
729 +       if (pcfirq[1] & PCF50606_INT2_CHGFOK) {
730 +               /* Battery ready for fast charging */
731 +               DEBUGPC("CHGFOK ");
732 +               pcf->flags |= PCF50606_F_CHG_FOK;
733 +               /* FIXME: how to signal this to userspace */
734 +       }
735 +       if (pcfirq[1] & PCF50606_INT2_CHGERR) {
736 +               /* Error in charge mode */
737 +               DEBUGPC("CHGERR ");
738 +               pcf->flags |= PCF50606_F_CHG_ERR;
739 +               pcf->flags &= ~(PCF50606_F_CHG_FOK|PCF50606_F_CHG_READY);
740 +               /* FIXME: how to signal this to userspace */
741 +       }
742 +       if (pcfirq[1] & PCF50606_INT2_CHGFRDY) {
743 +               /* Fast charge completed */
744 +               DEBUGPC("CHGFRDY ");
745 +               pcf->flags |= PCF50606_F_CHG_READY;
746 +               pcf->flags &= ~PCF50606_F_CHG_FOK;
747 +               /* FIXME: how to signal this to userspace */
748 +       }
749 +       if (pcfirq[1] & PCF50606_INT2_CHGPROT) {
750 +               /* Charging protection interrupt */
751 +               DEBUGPC("CHGPROT ");
752 +               pcf->flags &= ~(PCF50606_F_CHG_FOK|PCF50606_F_CHG_READY);
753 +               /* FIXME: signal this to userspace */
754 +       }
755 +       if (pcfirq[1] & PCF50606_INT2_CHGWD10S) {
756 +               /* Charger watchdog will expire in 10 seconds */
757 +               DEBUGPC("CHGWD10S ");
758 +               reg_set_bit_mask(pcf, PCF50606_REG_OOCC1,
759 +                                PCF50606_OOCC1_WDTRST,
760 +                                PCF50606_OOCC1_WDTRST);
761 +       }
762 +       if (pcfirq[1] & PCF50606_INT2_CHGWDEXP) {
763 +               /* Charger watchdog expires */
764 +               DEBUGPC("CHGWDEXP ");
765 +               /* FIXME: how to signal this to userspace */
766 +       }
767 +
768 +       if (pcfirq[2] & PCF50606_INT3_ADCRDY) {
769 +               /* ADC result ready */
770 +               DEBUGPC("ADCRDY ");
771 +       }
772 +       if (pcfirq[2] & PCF50606_INT3_ACDINS) {
773 +               /* Accessory insertion detected */
774 +               DEBUGPC("ACDINS ");
775 +               if (pcf->pdata->cb)
776 +                       pcf->pdata->cb(&pcf->client.dev,
777 +                                      PCF50606_FEAT_ACD, PMU_EVT_INSERT);
778 +       }
779 +       if (pcfirq[2] & PCF50606_INT3_ACDREM) {
780 +               /* Accessory removal detected */
781 +               DEBUGPC("ACDREM ");
782 +               if (pcf->pdata->cb)
783 +                       pcf->pdata->cb(&pcf->client.dev,
784 +                                      PCF50606_FEAT_ACD, PMU_EVT_REMOVE);
785 +       }
786 +       /* FIXME: TSCPRES */
787 +       if (pcfirq[2] & PCF50606_INT3_LOWBAT) {
788 +               /* Really low battery voltage, we have 8 seconds left */
789 +               DEBUGPC("LOWBAT ");
790 +               apm_queue_event(APM_LOW_BATTERY);
791 +               DEBUGPC("SIGPWR(init) ");
792 +               kill_proc(1, SIGPWR, 1);
793 +               /* Tell PMU we are taking care of this */
794 +               reg_set_bit_mask(pcf, PCF50606_REG_OOCC1,
795 +                                PCF50606_OOCC1_TOTRST,
796 +                                PCF50606_OOCC1_TOTRST);
797 +       }
798 +       if (pcfirq[2] & PCF50606_INT3_HIGHTMP) {
799 +               /* High temperature */
800 +               DEBUGPC("HIGHTMP ");
801 +               apm_queue_event(APM_CRITICAL_SUSPEND);
802 +       }
803 +
804 +       DEBUGPC("\n");
805 +
806 +       pcf->working = 0;
807 +       input_sync(pcf->input_dev);
808 +       put_device(&pcf->client.dev);
809 +       mutex_unlock(&pcf->working_lock);
810 +}
811 +
812 +static irqreturn_t pcf50606_irq(int irq, void *_pcf)
813 +{
814 +       struct pcf50606_data *pcf = _pcf;
815 +
816 +       dev_dbg(&pcf->client.dev, "entering(irq=%u, pcf=%p): scheduling work\n",
817 +               irq, _pcf);
818 +       get_device(&pcf->client.dev);
819 +       if (!schedule_work(&pcf->work) && !pcf->working)
820 +               dev_dbg(&pcf->client.dev, "work item may be lost\n");
821 +
822 +       return IRQ_HANDLED;
823 +}
824 +
825 +static u_int16_t adc_to_batt_millivolts(u_int16_t adc)
826 +{
827 +       u_int16_t mvolts;
828 +
829 +       mvolts = (adc * 6000) / 1024;
830 +
831 +       return mvolts;
832 +}
833 +
834 +#define BATTVOLT_SCALE_START 2800
835 +#define BATTVOLT_SCALE_END 4200
836 +#define BATTVOLT_SCALE_DIVIDER ((BATTVOLT_SCALE_END - BATTVOLT_SCALE_START)/100)
837 +
838 +static u_int8_t battvolt_scale(u_int16_t battvolt)
839 +{
840 +       /* FIXME: this linear scale is completely bogus */
841 +       u_int16_t battvolt_relative = battvolt - BATTVOLT_SCALE_START;
842 +       unsigned int percent = battvolt_relative / BATTVOLT_SCALE_DIVIDER;
843 +
844 +       return percent;
845 +}
846 +
847 +u_int16_t pcf50606_battvolt(struct pcf50606_data *pcf)
848 +{
849 +       u_int16_t adc;
850 +       adc = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_RES, NULL);
851 +
852 +       return adc_to_batt_millivolts(adc);
853 +}
854 +EXPORT_SYMBOL_GPL(pcf50606_battvolt);
855 +
856 +static ssize_t show_battvolt(struct device *dev, struct device_attribute *attr,
857 +                            char *buf)
858 +{
859 +       struct i2c_client *client = to_i2c_client(dev);
860 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
861 +
862 +       return sprintf(buf, "%u\n", pcf50606_battvolt(pcf));
863 +}
864 +static DEVICE_ATTR(battvolt, S_IRUGO | S_IWUSR, show_battvolt, NULL);
865 +
866 +static int reg_id_by_name(const char *name)
867 +{
868 +       int reg_id;
869 +
870 +       if (!strcmp(name, "voltage_dcd"))
871 +               reg_id = PCF50606_REGULATOR_DCD;
872 +       else if (!strcmp(name, "voltage_dcde"))
873 +               reg_id = PCF50606_REGULATOR_DCDE;
874 +       else if (!strcmp(name, "voltage_dcud"))
875 +               reg_id = PCF50606_REGULATOR_DCUD;
876 +       else if (!strcmp(name, "voltage_d1reg"))
877 +               reg_id = PCF50606_REGULATOR_D1REG;
878 +       else if (!strcmp(name, "voltage_d2reg"))
879 +               reg_id = PCF50606_REGULATOR_D2REG;
880 +       else if (!strcmp(name, "voltage_d3reg"))
881 +               reg_id = PCF50606_REGULATOR_D3REG;
882 +       else if (!strcmp(name, "voltage_lpreg"))
883 +               reg_id = PCF50606_REGULATOR_LPREG;
884 +       else if (!strcmp(name, "voltage_ioreg"))
885 +               reg_id = PCF50606_REGULATOR_IOREG;
886 +       else
887 +               reg_id = -1;
888 +
889 +       return reg_id;
890 +}
891 +
892 +static ssize_t show_vreg(struct device *dev, struct device_attribute *attr,
893 +                        char *buf)
894 +{
895 +       struct i2c_client *client = to_i2c_client(dev);
896 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
897 +       unsigned int reg_id;
898 +
899 +       reg_id = reg_id_by_name(attr->attr.name);
900 +       if (reg_id < 0)
901 +               return 0;
902 +
903 +       if (pcf50606_onoff_get(pcf, reg_id) > 0)
904 +               return sprintf(buf, "%u\n", pcf50606_voltage_get(pcf, reg_id));
905 +       else
906 +               return strlcpy(buf, "0\n", PAGE_SIZE);
907 +}
908 +
909 +static ssize_t set_vreg(struct device *dev, struct device_attribute *attr,
910 +                       const char *buf, size_t count)
911 +{
912 +       struct i2c_client *client = to_i2c_client(dev);
913 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
914 +       unsigned long mvolts = simple_strtoul(buf, NULL, 10);
915 +       unsigned int reg_id;
916 +
917 +       reg_id = reg_id_by_name(attr->attr.name);
918 +       if (reg_id < 0)
919 +               return -EIO;
920 +
921 +       dev_dbg(dev, "attempting to set %s(%d) to %lu mvolts\n",
922 +               attr->attr.name, reg_id, mvolts);
923 +
924 +       if (mvolts == 0) {
925 +               pcf50606_onoff_set(pcf, reg_id, 0);
926 +       } else {
927 +               if (pcf50606_voltage_set(pcf, reg_id, mvolts) < 0) {
928 +                       dev_warn(dev, "refusing to set %s(%d) to %lu mvolts "
929 +                                "(max=%u)\n", attr->attr.name, reg_id, mvolts,
930 +                                pcf->pdata->rails[reg_id].voltage.max);
931 +                       return -EINVAL;
932 +               }
933 +               pcf50606_onoff_set(pcf, reg_id, 1);
934 +       }
935 +
936 +       return count;
937 +}
938 +
939 +static DEVICE_ATTR(voltage_dcd, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
940 +static DEVICE_ATTR(voltage_dcde, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
941 +static DEVICE_ATTR(voltage_dcud, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
942 +static DEVICE_ATTR(voltage_d1reg, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
943 +static DEVICE_ATTR(voltage_d2reg, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
944 +static DEVICE_ATTR(voltage_d3reg, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
945 +static DEVICE_ATTR(voltage_lpreg, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
946 +static DEVICE_ATTR(voltage_ioreg, S_IRUGO | S_IWUSR, show_vreg, set_vreg);
947 +
948 +/***********************************************************************
949 + * Charger Control
950 + ***********************************************************************/
951 +
952 +/* Enable/disable fast charging (500mA in the GTA01) */
953 +void pcf50606_charge_fast(struct pcf50606_data *pcf, int on)
954 +{
955 +       if (!(pcf->pdata->used_features & PCF50606_FEAT_MBC))
956 +               return;
957 +
958 +       if (on) {
959 +               /* We can allow PCF to automatically charge
960 +                * using Ifast */
961 +               pcf->flags |= PCF50606_F_CHG_FAST;
962 +               reg_set_bit_mask(pcf, PCF50606_REG_MBCC1,
963 +                                PCF50606_MBCC1_AUTOFST,
964 +                                PCF50606_MBCC1_AUTOFST);
965 +       } else {
966 +               pcf->flags &= ~PCF50606_F_CHG_FAST;
967 +               /* disable automatic fast-charge */
968 +               reg_clear_bits(pcf, PCF50606_REG_MBCC1,
969 +                               PCF50606_MBCC1_AUTOFST);
970 +               /* switch to idle mode to abort existing charge
971 +                * process */
972 +               reg_set_bit_mask(pcf, PCF50606_REG_MBCC1,
973 +                                PCF50606_MBCC1_CHGMOD_MASK,
974 +                                PCF50606_MBCC1_CHGMOD_IDLE);
975 +       }
976 +}
977 +EXPORT_SYMBOL_GPL(pcf50606_charge_fast);
978 +
979 +static inline u_int16_t adc_to_rntc(struct pcf50606_data *pcf, u_int16_t adc)
980 +{
981 +       u_int32_t r_ntc = (adc * (u_int32_t)pcf->pdata->r_fix_batt) / (1023 - adc);
982 +
983 +       return r_ntc;
984 +}
985 +
986 +static inline int16_t rntc_to_temp(u_int16_t rntc)
987 +{
988 +       int i;
989 +
990 +       for (i = 0; i < ARRAY_SIZE(ntc_table_10k_3370B); i++) {
991 +               if (rntc > ntc_table_10k_3370B[i])
992 +                       return i - 10;  /* First element is -10 */
993 +       }
994 +       return -99;     /* Below our range */
995 +}
996 +
997 +static ssize_t show_battemp(struct device *dev, struct device_attribute *attr,
998 +                           char *buf)
999 +{
1000 +       struct i2c_client *client = to_i2c_client(dev);
1001 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1002 +       u_int16_t adc;
1003 +
1004 +       adc = adc_read(pcf, PCF50606_ADCMUX_BATTEMP, NULL);
1005 +
1006 +       return sprintf(buf, "%d\n", rntc_to_temp(adc_to_rntc(pcf, adc)));
1007 +}
1008 +static DEVICE_ATTR(battemp, S_IRUGO | S_IWUSR, show_battemp, NULL);
1009 +
1010 +static inline int16_t adc_to_chg_milliamps(struct pcf50606_data *pcf,
1011 +                                            u_int16_t adc_adcin1,
1012 +                                            u_int16_t adc_batvolt)
1013 +{
1014 +       int32_t res = (adc_adcin1 - adc_batvolt) * 2400;
1015 +       return (res * 1000) / (pcf->pdata->r_sense_milli * 1024);
1016 +}
1017 +
1018 +static ssize_t show_chgcur(struct device *dev, struct device_attribute *attr,
1019 +                          char *buf)
1020 +{
1021 +       struct i2c_client *client = to_i2c_client(dev);
1022 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1023 +       u_int16_t adc_batvolt, adc_adcin1;
1024 +       int16_t ma;
1025 +
1026 +       adc_batvolt = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_ADCIN1,
1027 +                              &adc_adcin1);
1028 +       ma = adc_to_chg_milliamps(pcf, adc_adcin1, adc_batvolt);
1029 +
1030 +       return sprintf(buf, "%d\n", ma);
1031 +}
1032 +static DEVICE_ATTR(chgcur, S_IRUGO | S_IWUSR, show_chgcur, NULL);
1033 +
1034 +static const char *chgmode_names[] = {
1035 +       [PCF50606_MBCC1_CHGMOD_QUAL]            = "qualification",
1036 +       [PCF50606_MBCC1_CHGMOD_PRE]             = "pre",
1037 +       [PCF50606_MBCC1_CHGMOD_TRICKLE]         = "trickle",
1038 +       [PCF50606_MBCC1_CHGMOD_FAST_CCCV]       = "fast_cccv",
1039 +       [PCF50606_MBCC1_CHGMOD_FAST_NOCC]       = "fast_nocc",
1040 +       [PCF50606_MBCC1_CHGMOD_FAST_NOCV]       = "fast_nocv",
1041 +       [PCF50606_MBCC1_CHGMOD_FAST_SW]         = "fast_switch",
1042 +       [PCF50606_MBCC1_CHGMOD_IDLE]            = "idle",
1043 +};
1044 +
1045 +static ssize_t show_chgmode(struct device *dev, struct device_attribute *attr,
1046 +                           char *buf)
1047 +{
1048 +       struct i2c_client *client = to_i2c_client(dev);
1049 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1050 +       u_int8_t mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1);
1051 +       u_int8_t chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK);
1052 +
1053 +       return sprintf(buf, "%s\n", chgmode_names[chgmod]);
1054 +}
1055 +
1056 +static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr,
1057 +                          const char *buf, size_t count)
1058 +{
1059 +       struct i2c_client *client = to_i2c_client(dev);
1060 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1061 +       u_int8_t mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1);
1062 +
1063 +       mbcc1 &= ~PCF50606_MBCC1_CHGMOD_MASK;
1064 +
1065 +       if (!strcmp(buf, "qualification"))
1066 +               mbcc1 |= PCF50606_MBCC1_CHGMOD_QUAL;
1067 +       else if (!strcmp(buf, "pre"))
1068 +               mbcc1 |= PCF50606_MBCC1_CHGMOD_PRE;
1069 +       else if (!strcmp(buf, "trickle"))
1070 +               mbcc1 |= PCF50606_MBCC1_CHGMOD_TRICKLE;
1071 +       else if (!strcmp(buf, "fast_cccv"))
1072 +               mbcc1 |= PCF50606_MBCC1_CHGMOD_FAST_CCCV;
1073 +       /* We don't allow the other fast modes for security reasons */
1074 +       else if (!strcmp(buf, "idle"))
1075 +               mbcc1 |= PCF50606_MBCC1_CHGMOD_IDLE;
1076 +       else
1077 +               return -EINVAL;
1078 +
1079 +       reg_write(pcf, PCF50606_REG_MBCC1, mbcc1);
1080 +
1081 +       return count;
1082 +}
1083 +
1084 +static DEVICE_ATTR(chgmode, S_IRUGO | S_IWUSR, show_chgmode, set_chgmode);
1085 +
1086 +static const char *chgstate_names[] = {
1087 +       [PCF50606_F_CHG_FAST]                   = "fast_enabled",
1088 +       [PCF50606_F_CHG_PRESENT]                = "present",
1089 +       [PCF50606_F_CHG_FOK]                    = "fast_ok",
1090 +       [PCF50606_F_CHG_ERR]                    = "error",
1091 +       [PCF50606_F_CHG_PROT]                   = "protection",
1092 +       [PCF50606_F_CHG_READY]                  = "ready",
1093 +};
1094 +
1095 +static ssize_t show_chgstate(struct device *dev, struct device_attribute *attr,
1096 +                           char *buf)
1097 +{
1098 +       struct i2c_client *client = to_i2c_client(dev);
1099 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1100 +       char *b = buf;
1101 +       int i;
1102 +
1103 +       for (i = 0; i < 32; i++)
1104 +               if (pcf->flags & (1 << i) && i < ARRAY_SIZE(chgstate_names))
1105 +                       b += sprintf(b, "%s ", chgstate_names[i]);
1106 +
1107 +       if (b > buf)
1108 +               b += sprintf(b, "\n");
1109 +
1110 +       return b - buf;
1111 +}
1112 +static DEVICE_ATTR(chgstate, S_IRUGO | S_IWUSR, show_chgstate, NULL);
1113 +
1114 +/***********************************************************************
1115 + * APM emulation
1116 + ***********************************************************************/
1117 +
1118 +static void pcf50606_get_power_status(struct apm_power_info *info)
1119 +{
1120 +       struct pcf50606_data *pcf = pcf50606_global;
1121 +       u_int8_t mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1);
1122 +       u_int8_t chgmod = mbcc1 & PCF50606_MBCC1_CHGMOD_MASK;
1123 +       u_int16_t battvolt = pcf50606_battvolt(pcf);
1124 +
1125 +       if (reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON)
1126 +               info->ac_line_status = APM_AC_ONLINE;
1127 +       else
1128 +               info->ac_line_status = APM_AC_OFFLINE;
1129 +
1130 +       switch (chgmod) {
1131 +       case PCF50606_MBCC1_CHGMOD_QUAL:
1132 +       case PCF50606_MBCC1_CHGMOD_PRE:
1133 +       case PCF50606_MBCC1_CHGMOD_IDLE:
1134 +               info->battery_life = battvolt_scale(battvolt);
1135 +               break;
1136 +       default:
1137 +               info->battery_status = APM_BATTERY_STATUS_CHARGING;
1138 +               info->battery_flag = APM_BATTERY_FLAG_CHARGING;
1139 +               break;
1140 +       }
1141 +}
1142 +
1143 +/***********************************************************************
1144 + * RTC
1145 + ***********************************************************************/
1146 +
1147 +struct pcf50606_time {
1148 +       u_int8_t sec;
1149 +       u_int8_t min;
1150 +       u_int8_t hour;
1151 +       u_int8_t wkday;
1152 +       u_int8_t day;
1153 +       u_int8_t month;
1154 +       u_int8_t year;
1155 +};
1156 +
1157 +static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50606_time *pcf)
1158 +{
1159 +       rtc->tm_sec = BCD2BIN(pcf->sec);
1160 +       rtc->tm_min = BCD2BIN(pcf->min);
1161 +       rtc->tm_hour = BCD2BIN(pcf->hour);
1162 +       rtc->tm_wday = BCD2BIN(pcf->wkday);
1163 +       rtc->tm_mday = BCD2BIN(pcf->day);
1164 +       rtc->tm_mon = BCD2BIN(pcf->month);
1165 +       rtc->tm_year = BCD2BIN(pcf->year) + 100;
1166 +}
1167 +
1168 +static void rtc2pcf_time(struct pcf50606_time *pcf, struct rtc_time *rtc)
1169 +{
1170 +       pcf->sec = BIN2BCD(rtc->tm_sec);
1171 +       pcf->min = BIN2BCD(rtc->tm_min);
1172 +       pcf->hour = BIN2BCD(rtc->tm_hour);
1173 +       pcf->wkday = BIN2BCD(rtc->tm_wday);
1174 +       pcf->day = BIN2BCD(rtc->tm_mday);
1175 +       pcf->month = BIN2BCD(rtc->tm_mon);
1176 +       pcf->year = BIN2BCD(rtc->tm_year - 100);
1177 +}
1178 +
1179 +static int pcf50606_rtc_ioctl(struct device *dev, unsigned int cmd,
1180 +                             unsigned long arg)
1181 +{
1182 +       struct i2c_client *client = to_i2c_client(dev);
1183 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1184 +       switch (cmd) {
1185 +       case RTC_PIE_OFF:
1186 +               /* disable periodic interrupt (hz tick) */
1187 +               pcf->flags &= ~PCF50606_F_RTC_SECOND;
1188 +               reg_set_bit_mask(pcf, PCF50606_REG_INT1M,
1189 +                                PCF50606_INT1_SECOND, PCF50606_INT1_SECOND);
1190 +               return 0;
1191 +       case RTC_PIE_ON:
1192 +               /* ensable periodic interrupt (hz tick) */
1193 +               pcf->flags |= PCF50606_F_RTC_SECOND;
1194 +               reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND);
1195 +               return 0;
1196 +       }
1197 +       return -ENOIOCTLCMD;
1198 +}
1199 +
1200 +static int pcf50606_rtc_read_time(struct device *dev, struct rtc_time *tm)
1201 +{
1202 +       struct i2c_client *client = to_i2c_client(dev);
1203 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1204 +       struct pcf50606_time pcf_tm;
1205 +
1206 +       mutex_lock(&pcf->lock);
1207 +       pcf_tm.sec = __reg_read(pcf, PCF50606_REG_RTCSC);
1208 +       pcf_tm.min = __reg_read(pcf, PCF50606_REG_RTCMN);
1209 +       pcf_tm.hour = __reg_read(pcf, PCF50606_REG_RTCHR);
1210 +       pcf_tm.wkday = __reg_read(pcf, PCF50606_REG_RTCWD);
1211 +       pcf_tm.day = __reg_read(pcf, PCF50606_REG_RTCDT);
1212 +       pcf_tm.month = __reg_read(pcf, PCF50606_REG_RTCMT);
1213 +       pcf_tm.year = __reg_read(pcf, PCF50606_REG_RTCYR);
1214 +       mutex_unlock(&pcf->lock);
1215 +
1216 +       dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
1217 +               pcf_tm.day, pcf_tm.month, pcf_tm.year,
1218 +               pcf_tm.hour, pcf_tm.min, pcf_tm.sec);
1219 +
1220 +       pcf2rtc_time(tm, &pcf_tm);
1221 +
1222 +       dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
1223 +               tm->tm_mday, tm->tm_mon, tm->tm_year,
1224 +               tm->tm_hour, tm->tm_min, tm->tm_sec);
1225 +
1226 +       return 0;
1227 +}
1228 +
1229 +static int pcf50606_rtc_set_time(struct device *dev, struct rtc_time *tm)
1230 +{
1231 +       struct i2c_client *client = to_i2c_client(dev);
1232 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1233 +       struct pcf50606_time pcf_tm;
1234 +       u_int8_t int1m;
1235 +
1236 +       dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
1237 +               tm->tm_mday, tm->tm_mon, tm->tm_year,
1238 +               tm->tm_hour, tm->tm_min, tm->tm_sec);
1239 +       rtc2pcf_time(&pcf_tm, tm);
1240 +       dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
1241 +               pcf_tm.day, pcf_tm.month, pcf_tm.year,
1242 +               pcf_tm.hour, pcf_tm.min, pcf_tm.sec);
1243 +
1244 +       mutex_lock(&pcf->lock);
1245 +
1246 +       /* disable SECOND interrupt */
1247 +       int1m = __reg_read(pcf, PCF50606_REG_INT1M);
1248 +       __reg_write(pcf, PCF50606_REG_INT1M, int1m | PCF50606_INT1_SECOND);
1249 +
1250 +       __reg_write(pcf, PCF50606_REG_RTCSC, pcf_tm.sec);
1251 +       __reg_write(pcf, PCF50606_REG_RTCMN, pcf_tm.min);
1252 +       __reg_write(pcf, PCF50606_REG_RTCHR, pcf_tm.hour);
1253 +       __reg_write(pcf, PCF50606_REG_RTCWD, pcf_tm.wkday);
1254 +       __reg_write(pcf, PCF50606_REG_RTCDT, pcf_tm.day);
1255 +       __reg_write(pcf, PCF50606_REG_RTCMT, pcf_tm.month);
1256 +       __reg_write(pcf, PCF50606_REG_RTCYR, pcf_tm.year);
1257 +
1258 +       /* restore INT1M, potentially re-enable SECOND interrupt */
1259 +       __reg_write(pcf, PCF50606_REG_INT1M, int1m);
1260 +
1261 +       mutex_unlock(&pcf->lock);
1262 +
1263 +       return 0;
1264 +}
1265 +
1266 +static int pcf50606_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
1267 +{
1268 +       struct i2c_client *client = to_i2c_client(dev);
1269 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1270 +       struct pcf50606_time pcf_tm;
1271 +
1272 +       mutex_lock(&pcf->lock);
1273 +       alrm->enabled = 
1274 +             __reg_read(pcf, PCF50606_REG_INT1M) & PCF50606_INT1_ALARM ? 0 : 1;
1275 +       pcf_tm.sec = __reg_read(pcf, PCF50606_REG_RTCSCA);
1276 +       pcf_tm.min = __reg_read(pcf, PCF50606_REG_RTCMNA);
1277 +       pcf_tm.hour = __reg_read(pcf, PCF50606_REG_RTCHRA);
1278 +       pcf_tm.wkday = __reg_read(pcf, PCF50606_REG_RTCWDA);
1279 +       pcf_tm.day = __reg_read(pcf, PCF50606_REG_RTCDTA);
1280 +       pcf_tm.month = __reg_read(pcf, PCF50606_REG_RTCMTA);
1281 +       pcf_tm.year = __reg_read(pcf, PCF50606_REG_RTCYRA);
1282 +       mutex_unlock(&pcf->lock);
1283 +
1284 +       pcf2rtc_time(&alrm->time, &pcf_tm);
1285 +
1286 +       return 0;
1287 +}
1288 +
1289 +static int pcf50606_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
1290 +{
1291 +       struct i2c_client *client = to_i2c_client(dev);
1292 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1293 +       struct pcf50606_time pcf_tm;
1294 +       u_int8_t irqmask;
1295 +
1296 +       rtc2pcf_time(&pcf_tm, &alrm->time);
1297 +
1298 +       mutex_lock(&pcf->lock);
1299 +
1300 +       /* disable alarm interrupt */
1301 +       irqmask = __reg_read(pcf, PCF50606_REG_INT1M);
1302 +       irqmask |= PCF50606_INT1_ALARM;
1303 +       __reg_write(pcf, PCF50606_REG_INT1M, irqmask);
1304 +
1305 +       __reg_write(pcf, PCF50606_REG_RTCSCA, pcf_tm.sec);
1306 +       __reg_write(pcf, PCF50606_REG_RTCMNA, pcf_tm.min);
1307 +       __reg_write(pcf, PCF50606_REG_RTCHRA, pcf_tm.hour);
1308 +       __reg_write(pcf, PCF50606_REG_RTCWDA, pcf_tm.wkday);
1309 +       __reg_write(pcf, PCF50606_REG_RTCDTA, pcf_tm.day);
1310 +       __reg_write(pcf, PCF50606_REG_RTCMTA, pcf_tm.month);
1311 +       __reg_write(pcf, PCF50606_REG_RTCYRA, pcf_tm.year);
1312 +
1313 +       if (alrm->enabled) {
1314 +               /* (re-)enaable alarm interrupt */
1315 +               irqmask = __reg_read(pcf, PCF50606_REG_INT1M);
1316 +               irqmask &= ~PCF50606_INT1_ALARM;
1317 +               __reg_write(pcf, PCF50606_REG_INT1M, irqmask);
1318 +       }
1319 +
1320 +       mutex_unlock(&pcf->lock);
1321 +
1322 +       /* FIXME */
1323 +       return 0;
1324 +}
1325 +
1326 +static struct rtc_class_ops pcf50606_rtc_ops = {
1327 +       .ioctl          = pcf50606_rtc_ioctl,
1328 +       .read_time      = pcf50606_rtc_read_time,
1329 +       .set_time       = pcf50606_rtc_set_time,
1330 +       .read_alarm     = pcf50606_rtc_read_alarm,
1331 +       .set_alarm      = pcf50606_rtc_set_alarm,
1332 +};
1333 +
1334 +/***********************************************************************
1335 + * Watchdog
1336 + ***********************************************************************/
1337 +
1338 +static void pcf50606_wdt_start(struct pcf50606_data *pcf)
1339 +{
1340 +       reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, PCF50606_OOCC1_WDTRST,
1341 +                        PCF50606_OOCC1_WDTRST);
1342 +}
1343 +
1344 +static void pcf50606_wdt_stop(struct pcf50606_data *pcf)
1345 +{
1346 +       reg_clear_bits(pcf, PCF50606_REG_OOCS, PCF50606_OOCS_WDTEXP);
1347 +}
1348 +
1349 +static void pcf50606_wdt_keepalive(struct pcf50606_data *pcf)
1350 +{
1351 +       pcf50606_wdt_start(pcf);
1352 +}
1353 +
1354 +static int pcf50606_wdt_open(struct inode *inode, struct file *file)
1355 +{
1356 +       struct pcf50606_data *pcf = pcf50606_global;
1357 +
1358 +       file->private_data = pcf;
1359 +
1360 +       /* start the timer */
1361 +       pcf50606_wdt_start(pcf);
1362 +
1363 +       return nonseekable_open(inode, file);
1364 +}
1365 +
1366 +static int pcf50606_wdt_release(struct inode *inode, struct file *file)
1367 +{
1368 +       struct pcf50606_data *pcf = file->private_data;
1369 +
1370 +       if (pcf->allow_close == CLOSE_STATE_ALLOW)
1371 +               pcf50606_wdt_stop(pcf);
1372 +       else {
1373 +               printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n");
1374 +               pcf50606_wdt_keepalive(pcf);
1375 +       }
1376 +
1377 +       pcf->allow_close = CLOSE_STATE_NOT;
1378 +
1379 +       return 0;
1380 +}
1381 +
1382 +static ssize_t pcf50606_wdt_write(struct file *file, const char __user *data,
1383 +                                 size_t len, loff_t *ppos)
1384 +{
1385 +       struct pcf50606_data *pcf = file->private_data;
1386 +       if (len) {
1387 +               size_t i;
1388 +
1389 +               for (i = 0; i != len; i++) {
1390 +                       char c;
1391 +                       if (get_user(c, data + i))
1392 +                               return -EFAULT;
1393 +                       if (c == 'V')
1394 +                               pcf->allow_close = CLOSE_STATE_ALLOW;
1395 +               }
1396 +               pcf50606_wdt_keepalive(pcf);
1397 +       }
1398 +
1399 +       return len;
1400 +}
1401 +
1402 +static struct watchdog_info pcf50606_wdt_ident = {
1403 +       .options        = WDIOF_MAGICCLOSE,
1404 +       .firmware_version = 0,
1405 +       .identity       = "PCF50606 Watchdog",
1406 +};
1407 +
1408 +static int pcf50606_wdt_ioctl(struct inode *inode, struct file *file,
1409 +                             unsigned int cmd, unsigned long arg)
1410 +{
1411 +       struct pcf50606_data *pcf = file->private_data;
1412 +       void __user *argp = (void __user *)arg;
1413 +       int __user *p = argp;
1414 +
1415 +       switch (cmd) {
1416 +       case WDIOC_GETSUPPORT:
1417 +               return copy_to_user(argp, &pcf50606_wdt_ident,
1418 +                                   sizeof(pcf50606_wdt_ident)) ? -EFAULT : 0;
1419 +               break;
1420 +       case WDIOC_GETSTATUS:
1421 +       case WDIOC_GETBOOTSTATUS:
1422 +               return put_user(0, p);
1423 +       case WDIOC_KEEPALIVE:
1424 +               pcf50606_wdt_keepalive(pcf);
1425 +               return 0;
1426 +       case WDIOC_GETTIMEOUT:
1427 +               return put_user(8, p);
1428 +       default:
1429 +               return -ENOIOCTLCMD;
1430 +       }
1431 +}
1432 +
1433 +static struct file_operations pcf50606_wdt_fops = {
1434 +       .owner          = THIS_MODULE,
1435 +       .llseek         = no_llseek,
1436 +       .write          = &pcf50606_wdt_write,
1437 +       .ioctl          = &pcf50606_wdt_ioctl,
1438 +       .open           = &pcf50606_wdt_open,
1439 +       .release        = &pcf50606_wdt_release,
1440 +};
1441 +
1442 +static struct miscdevice pcf50606_wdt_miscdev = {
1443 +       .minor          = WATCHDOG_MINOR,
1444 +       .name           = "watchdog",
1445 +       .fops           = &pcf50606_wdt_fops,
1446 +};
1447 +
1448 +/***********************************************************************
1449 + * PWM
1450 + ***********************************************************************/
1451 +
1452 +static const char *pwm_dc_table[] = {
1453 +       "0/16", "1/16", "2/16", "3/16",
1454 +       "4/16", "5/16", "6/16", "7/16",
1455 +       "8/16", "9/16", "10/16", "11/16",
1456 +       "12/16", "13/16", "14/16", "15/16",
1457 +};
1458 +
1459 +static ssize_t show_pwm_dc(struct device *dev, struct device_attribute *attr,
1460 +                          char *buf)
1461 +{
1462 +       struct i2c_client *client = to_i2c_client(dev);
1463 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1464 +       u_int8_t val;
1465 +
1466 +       val = reg_read(pcf, PCF50606_REG_PWMC1) >> PCF50606_PWMC1_DC_SHIFT;
1467 +       val &= 0xf;
1468 +
1469 +       return sprintf(buf, "%s\n", pwm_dc_table[val]);
1470 +}
1471 +
1472 +static ssize_t set_pwm_dc(struct device *dev, struct device_attribute *attr,
1473 +                         const char *buf, size_t count)
1474 +{
1475 +       struct i2c_client *client = to_i2c_client(dev);
1476 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1477 +       u_int8_t i;
1478 +
1479 +       for (i = 0; i < ARRAY_SIZE(pwm_dc_table); i++) {
1480 +               if (!strncmp(buf, pwm_dc_table[i], strlen(pwm_dc_table[i]))) {
1481 +                       dev_dbg(dev, "setting pwm dc %s\n\r", pwm_dc_table[i]);
1482 +                       reg_set_bit_mask(pcf, PCF50606_REG_PWMC1, 0x1e,
1483 +                                        (i << PCF50606_PWMC1_DC_SHIFT));
1484 +               }
1485 +       }
1486 +       return count;
1487 +}
1488 +
1489 +static DEVICE_ATTR(pwm_dc, S_IRUGO | S_IWUSR, show_pwm_dc, set_pwm_dc);
1490 +
1491 +static const char *pwm_clk_table[] = {
1492 +       "512", "256", "128", "64",
1493 +       "56300", "28100", "14100", "7000",
1494 +};
1495 +
1496 +static ssize_t show_pwm_clk(struct device *dev, struct device_attribute *attr,
1497 +                           char *buf)
1498 +{
1499 +       struct i2c_client *client = to_i2c_client(dev);
1500 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1501 +       u_int8_t val;
1502 +
1503 +       val = reg_read(pcf, PCF50606_REG_PWMC1) >> PCF50606_PWMC1_CLK_SHIFT;
1504 +       val &= 0x7;
1505 +
1506 +       return sprintf(buf, "%s\n", pwm_clk_table[val]);
1507 +}
1508 +
1509 +static ssize_t set_pwm_clk(struct device *dev, struct device_attribute *attr,
1510 +                          const char *buf, size_t count)
1511 +{
1512 +       struct i2c_client *client = to_i2c_client(dev);
1513 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1514 +       u_int8_t i;
1515 +
1516 +       for (i = 0; i < ARRAY_SIZE(pwm_clk_table); i++) {
1517 +               if (!strncmp(buf, pwm_clk_table[i], strlen(pwm_clk_table[i]))) {
1518 +                       dev_dbg(dev, "setting pwm clk %s\n\r",
1519 +                               pwm_clk_table[i]);
1520 +                       reg_set_bit_mask(pcf, PCF50606_REG_PWMC1, 0xe0,
1521 +                                        (i << PCF50606_PWMC1_CLK_SHIFT));
1522 +               }
1523 +       }
1524 +       return count;
1525 +}
1526 +
1527 +static DEVICE_ATTR(pwm_clk, S_IRUGO | S_IWUSR, show_pwm_clk, set_pwm_clk);
1528 +
1529 +static int pcf50606bl_get_intensity(struct backlight_device *bd)
1530 +{
1531 +       struct pcf50606_data *pcf = bl_get_data(bd);
1532 +       int intensity = reg_read(pcf, PCF50606_REG_PWMC1);
1533 +       intensity = (intensity >> PCF50606_PWMC1_DC_SHIFT);
1534 +
1535 +       return intensity & 0xf;
1536 +}
1537 +
1538 +static int pcf50606bl_set_intensity(struct backlight_device *bd)
1539 +{
1540 +       struct pcf50606_data *pcf = bl_get_data(bd);
1541 +       int intensity = bd->props.brightness;
1542 +
1543 +       if (bd->props.power != FB_BLANK_UNBLANK)
1544 +               intensity = 0;
1545 +       if (bd->props.fb_blank != FB_BLANK_UNBLANK)
1546 +               intensity = 0;
1547 +
1548 +       return reg_set_bit_mask(pcf, PCF50606_REG_PWMC1, 0x1e,
1549 +                               (intensity << PCF50606_PWMC1_DC_SHIFT));
1550 +}
1551 +
1552 +static struct backlight_ops pcf50606bl_ops = {
1553 +       .get_brightness = pcf50606bl_get_intensity,
1554 +       .update_status  = pcf50606bl_set_intensity,
1555 +};
1556 +
1557 +/***********************************************************************
1558 + * Driver initialization
1559 + ***********************************************************************/
1560 +
1561 +#ifdef CONFIG_MACH_NEO1973_GTA01
1562 +/* We currently place those platform devices here to make sure the device
1563 + * suspend/resume order is correct */
1564 +static struct platform_device gta01_pm_gps_dev = {
1565 +       .name           = "neo1973-pm-gps",
1566 +};
1567 +
1568 +static struct platform_device gta01_pm_bt_dev = {
1569 +       .name           = "neo1973-pm-bt",
1570 +};
1571 +#endif
1572 +
1573 +static struct attribute *pcf_sysfs_entries[16] = {
1574 +       &dev_attr_voltage_dcd.attr,
1575 +       &dev_attr_voltage_dcde.attr,
1576 +       &dev_attr_voltage_dcud.attr,
1577 +       &dev_attr_voltage_d1reg.attr,
1578 +       &dev_attr_voltage_d2reg.attr,
1579 +       &dev_attr_voltage_d3reg.attr,
1580 +       &dev_attr_voltage_lpreg.attr,
1581 +       &dev_attr_voltage_ioreg.attr,
1582 +       NULL
1583 +};
1584 +
1585 +static struct attribute_group pcf_attr_group = {
1586 +       .name   = NULL,                 /* put in device directory */
1587 +       .attrs  = pcf_sysfs_entries,
1588 +};
1589 +
1590 +static void populate_sysfs_group(struct pcf50606_data *pcf)
1591 +{
1592 +       int i = 0;
1593 +       struct attribute **attr;
1594 +
1595 +       for (attr = pcf_sysfs_entries; *attr; attr++)
1596 +               i++;
1597 +
1598 +       if (pcf->pdata->used_features & PCF50606_FEAT_MBC) {
1599 +               pcf_sysfs_entries[i++] = &dev_attr_chgstate.attr;
1600 +               pcf_sysfs_entries[i++] = &dev_attr_chgmode.attr;
1601 +       }
1602 +
1603 +       if (pcf->pdata->used_features & PCF50606_FEAT_CHGCUR)
1604 +               pcf_sysfs_entries[i++] = &dev_attr_chgcur.attr;
1605 +
1606 +       if (pcf->pdata->used_features & PCF50606_FEAT_BATVOLT)
1607 +               pcf_sysfs_entries[i++] = &dev_attr_battvolt.attr;
1608 +
1609 +       if (pcf->pdata->used_features & PCF50606_FEAT_BATTEMP)
1610 +               pcf_sysfs_entries[i++] = &dev_attr_battemp.attr;
1611 +
1612 +       if (pcf->pdata->used_features & PCF50606_FEAT_PWM) {
1613 +               pcf_sysfs_entries[i++] = &dev_attr_pwm_dc.attr;
1614 +               pcf_sysfs_entries[i++] = &dev_attr_pwm_clk.attr;
1615 +       }
1616 +}
1617 +
1618 +static int pcf50606_detect(struct i2c_adapter *adapter, int address, int kind)
1619 +{
1620 +       struct i2c_client *new_client;
1621 +       struct pcf50606_data *data;
1622 +       int err = 0;
1623 +       int irq;
1624 +
1625 +       if (!pcf50606_pdev) {
1626 +               printk(KERN_ERR "pcf50606: driver needs a platform_device!\n");
1627 +               return -EIO;
1628 +       }
1629 +
1630 +       irq = platform_get_irq(pcf50606_pdev, 0);
1631 +       if (irq < 0) {
1632 +               dev_err(&pcf50606_pdev->dev, "no irq in platform resources!\n");
1633 +               return -EIO;
1634 +       }
1635 +
1636 +       /* At the moment, we only support one PCF50606 in a system */
1637 +       if (pcf50606_global) {
1638 +               dev_err(&pcf50606_pdev->dev,
1639 +                       "currently only one chip supported\n");
1640 +               return -EBUSY;
1641 +       }
1642 +
1643 +       data = kzalloc(sizeof(*data), GFP_KERNEL);
1644 +       if (!data)
1645 +               return -ENOMEM;
1646 +
1647 +       mutex_init(&data->lock);
1648 +       mutex_init(&data->working_lock);
1649 +       INIT_WORK(&data->work, pcf50606_work);
1650 +       data->irq = irq;
1651 +       data->working = 0;
1652 +       data->onkey_seconds = -1;
1653 +       data->pdata = pcf50606_pdev->dev.platform_data;
1654 +
1655 +       new_client = &data->client;
1656 +       i2c_set_clientdata(new_client, data);
1657 +       new_client->addr = address;
1658 +       new_client->adapter = adapter;
1659 +       new_client->driver = &pcf50606_driver;
1660 +       new_client->flags = 0;
1661 +       strlcpy(new_client->name, "pcf50606", I2C_NAME_SIZE);
1662 +
1663 +       /* now we try to detect the chip */
1664 +
1665 +       /* register with i2c core */
1666 +       err = i2c_attach_client(new_client);
1667 +       if (err) {
1668 +               dev_err(&new_client->dev,
1669 +                       "error during i2c_attach_client()\n");
1670 +               goto exit_free;
1671 +       }
1672 +
1673 +       populate_sysfs_group(data);
1674 +
1675 +       err = sysfs_create_group(&new_client->dev.kobj, &pcf_attr_group);
1676 +       if (err) {
1677 +               dev_err(&new_client->dev, "error creating sysfs group\n");
1678 +               goto exit_detach;
1679 +       }
1680 +
1681 +       /* create virtual charger 'device' */
1682 +
1683 +       /* input device registration */
1684 +       data->input_dev = input_allocate_device();
1685 +       if (!data->input_dev)
1686 +               goto exit_sysfs;
1687 +
1688 +       data->input_dev->name = "FIC Neo1973 PMU events";
1689 +       data->input_dev->phys = "I2C";
1690 +       data->input_dev->id.bustype = BUS_I2C;
1691 +       data->input_dev->cdev.dev = &new_client->dev;
1692 +
1693 +       data->input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
1694 +       set_bit(KEY_POWER, data->input_dev->keybit);
1695 +       set_bit(KEY_POWER2, data->input_dev->keybit);
1696 +       set_bit(KEY_BATTERY, data->input_dev->keybit);
1697 +
1698 +       err = input_register_device(data->input_dev);
1699 +       if (err)
1700 +               goto exit_sysfs;
1701 +
1702 +       /* register power off handler with core power management */
1703 +       pm_power_off = &pcf50606_go_standby;
1704 +
1705 +       /* configure interrupt mask */
1706 +       reg_write(data, PCF50606_REG_INT1M, PCF50606_INT1_SECOND);
1707 +       reg_write(data, PCF50606_REG_INT2M, 0x00);
1708 +       reg_write(data, PCF50606_REG_INT3M, PCF50606_INT3_TSCPRES);
1709 +
1710 +       err = request_irq(irq, pcf50606_irq, IRQF_TRIGGER_FALLING,
1711 +                         "pcf50606", data);
1712 +       if (err < 0)
1713 +               goto exit_input;
1714 +
1715 +       if (enable_irq_wake(irq) < 0)
1716 +               dev_err(&new_client->dev, "IRQ %u cannot be enabled as wake-up"
1717 +                       "source in this hardware revision!", irq);
1718 +
1719 +       pcf50606_global = data;
1720 +
1721 +       if (data->pdata->used_features & PCF50606_FEAT_RTC) {
1722 +               data->rtc = rtc_device_register("pcf50606", &new_client->dev,
1723 +                                               &pcf50606_rtc_ops, THIS_MODULE);
1724 +               if (IS_ERR(data->rtc)) {
1725 +                       err = PTR_ERR(data->rtc);
1726 +                       goto exit_irq;
1727 +               }
1728 +       }
1729 +
1730 +       if (data->pdata->used_features & PCF50606_FEAT_WDT) {
1731 +               err = misc_register(&pcf50606_wdt_miscdev);
1732 +               if (err) {
1733 +                       dev_err(&new_client->dev, "cannot register miscdev on "
1734 +                              "minor=%d (%d)\n", WATCHDOG_MINOR, err);
1735 +                       goto exit_rtc;
1736 +               }
1737 +       }
1738 +
1739 +       if (data->pdata->used_features & PCF50606_FEAT_PWM) {
1740 +               /* enable PWM controller */
1741 +               reg_set_bit_mask(data, PCF50606_REG_PWMC1,
1742 +                                PCF50606_PWMC1_ACTSET,
1743 +                                PCF50606_PWMC1_ACTSET);
1744 +       }
1745 +
1746 +       if (data->pdata->used_features & PCF50606_FEAT_PWM_BL) {
1747 +               data->backlight = backlight_device_register("pcf50606-bl",
1748 +                                                           &new_client->dev,
1749 +                                                           data,
1750 +                                                           &pcf50606bl_ops);
1751 +               if (!data->backlight)
1752 +                       goto exit_misc;
1753 +               data->backlight->props.max_brightness = 16;
1754 +               data->backlight->props.power = FB_BLANK_UNBLANK;
1755 +               data->backlight->props.brightness =
1756 +                                       data->pdata->init_brightness;
1757 +               backlight_update_status(data->backlight);
1758 +       }
1759 +
1760 +       apm_get_power_status = pcf50606_get_power_status;
1761 +
1762 +#ifdef CONFIG_MACH_NEO1973_GTA01
1763 +       if (machine_is_neo1973_gta01()) {
1764 +               gta01_pm_gps_dev.dev.parent = &new_client->dev;
1765 +               switch (system_rev) {
1766 +               case GTA01Bv2_SYSTEM_REV:
1767 +               case GTA01Bv3_SYSTEM_REV:
1768 +               case GTA01Bv4_SYSTEM_REV:
1769 +                       gta01_pm_bt_dev.dev.parent = &new_client->dev;
1770 +                       platform_device_register(&gta01_pm_bt_dev);
1771 +                       break;
1772 +               }
1773 +               platform_device_register(&gta01_pm_gps_dev);
1774 +               /* a link for gllin compatibility */
1775 +               err = sysfs_create_link(&platform_bus_type.devices.kobj,
1776 +                   &gta01_pm_gps_dev.dev.kobj, "gta01-pm-gps.0");
1777 +               if (err)
1778 +                       printk(KERN_ERR
1779 +                           "sysfs_create_link (gta01-pm-gps.0): %d\n", err);
1780 +       }
1781 +#endif
1782 +
1783 +       if (data->pdata->used_features & PCF50606_FEAT_ACD)
1784 +               reg_set_bit_mask(data, PCF50606_REG_ACDC1,
1785 +                                PCF50606_ACDC1_ACDAPE, PCF50606_ACDC1_ACDAPE);
1786 +       else
1787 +               reg_clear_bits(data, PCF50606_REG_ACDC1,
1788 +                              PCF50606_ACDC1_ACDAPE);
1789 +
1790 +       return 0;
1791 +
1792 +exit_misc:
1793 +       if (data->pdata->used_features & PCF50606_FEAT_WDT)
1794 +               misc_deregister(&pcf50606_wdt_miscdev);
1795 +exit_rtc:
1796 +       if (data->pdata->used_features & PCF50606_FEAT_RTC)
1797 +               rtc_device_unregister(pcf50606_global->rtc);
1798 +exit_irq:
1799 +       free_irq(pcf50606_global->irq, pcf50606_global);
1800 +       pcf50606_global = NULL;
1801 +exit_input:
1802 +       pm_power_off = NULL;
1803 +       input_unregister_device(data->input_dev);
1804 +exit_sysfs:
1805 +       sysfs_remove_group(&new_client->dev.kobj, &pcf_attr_group);
1806 +exit_detach:
1807 +       i2c_detach_client(new_client);
1808 +exit_free:
1809 +       kfree(data);
1810 +       return err;
1811 +}
1812 +
1813 +static int pcf50606_attach_adapter(struct i2c_adapter *adapter)
1814 +{
1815 +       return i2c_probe(adapter, &addr_data, &pcf50606_detect);
1816 +}
1817 +
1818 +static int pcf50606_detach_client(struct i2c_client *client)
1819 +{
1820 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1821 +
1822 +       apm_get_power_status = NULL;
1823 +       input_unregister_device(pcf->input_dev);
1824 +
1825 +       if (pcf->pdata->used_features & PCF50606_FEAT_PWM_BL)
1826 +               backlight_device_unregister(pcf->backlight);
1827 +
1828 +       if (pcf->pdata->used_features & PCF50606_FEAT_WDT)
1829 +               misc_deregister(&pcf50606_wdt_miscdev);
1830 +
1831 +       if (pcf->pdata->used_features & PCF50606_FEAT_RTC)
1832 +               rtc_device_unregister(pcf->rtc);
1833 +
1834 +       free_irq(pcf->irq, pcf);
1835 +
1836 +       sysfs_remove_group(&client->dev.kobj, &pcf_attr_group);
1837 +
1838 +       pm_power_off = NULL;
1839 +
1840 +       kfree(pcf);
1841 +
1842 +       return 0;
1843 +}
1844 +
1845 +#ifdef CONFIG_PM
1846 +#define INT1M_RESUMERS (PCF50606_INT1_ALARM | \
1847 +                        PCF50606_INT1_ONKEYF | \
1848 +                        PCF50606_INT1_EXTONR)
1849 +#define INT2M_RESUMERS (PCF50606_INT2_CHGWD10S | \
1850 +                        PCF50606_INT2_CHGPROT | \
1851 +                        PCF50606_INT2_CHGERR)
1852 +#define INT3M_RESUMERS (PCF50606_INT3_LOWBAT | \
1853 +                        PCF50606_INT3_HIGHTMP | \
1854 +                        PCF50606_INT3_ACDINS)
1855 +static int pcf50606_suspend(struct device *dev, pm_message_t state)
1856 +{
1857 +       struct i2c_client *client = to_i2c_client(dev);
1858 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1859 +       int i;
1860 +
1861 +       /* The general idea is to power down all unused power supplies,
1862 +        * and then mask all PCF50606 interrup sources but EXTONR, ONKEYF
1863 +        * and ALARM */
1864 +
1865 +       mutex_lock(&pcf->lock);
1866 +
1867 +       /* Save all registers that don't "survive" standby state */
1868 +       pcf->standby_regs.dcdc1 = __reg_read(pcf, PCF50606_REG_DCDC1);
1869 +       pcf->standby_regs.dcdc2 = __reg_read(pcf, PCF50606_REG_DCDC2);
1870 +       pcf->standby_regs.dcdec1 = __reg_read(pcf, PCF50606_REG_DCDEC1);
1871 +       pcf->standby_regs.dcudc1 = __reg_read(pcf, PCF50606_REG_DCUDC1);
1872 +       pcf->standby_regs.ioregc = __reg_read(pcf, PCF50606_REG_IOREGC);
1873 +       pcf->standby_regs.d1regc1 = __reg_read(pcf, PCF50606_REG_D1REGC1);
1874 +       pcf->standby_regs.d2regc1 = __reg_read(pcf, PCF50606_REG_D2REGC1);
1875 +       pcf->standby_regs.d3regc1 = __reg_read(pcf, PCF50606_REG_D3REGC1);
1876 +       pcf->standby_regs.lpregc1 = __reg_read(pcf, PCF50606_REG_LPREGC1);
1877 +       pcf->standby_regs.adcc1 = __reg_read(pcf, PCF50606_REG_ADCC1);
1878 +       pcf->standby_regs.adcc2 = __reg_read(pcf, PCF50606_REG_ADCC2);
1879 +       pcf->standby_regs.pwmc1 = __reg_read(pcf, PCF50606_REG_PWMC1);
1880 +
1881 +       /* switch off power supplies that are not needed during suspend */
1882 +       for (i = 0; i < __NUM_PCF50606_REGULATORS; i++) {
1883 +               if (!(pcf->pdata->rails[i].flags & PMU_VRAIL_F_SUSPEND_ON)) {
1884 +                       u_int8_t tmp;
1885 +
1886 +                       /* IOREG powers the I@C interface so we cannot switch
1887 +                        * it off */
1888 +                       if (i == PCF50606_REGULATOR_IOREG)
1889 +                               continue;
1890 +
1891 +                       dev_dbg(dev, "disabling pcf50606 regulator %u\n", i);
1892 +                       /* we cannot use pcf50606_onoff_set() because we're
1893 +                        * already under the mutex */
1894 +                       tmp = __reg_read(pcf, regulator_registers[i]);
1895 +                       tmp &= 0x1f;
1896 +                       __reg_write(pcf, regulator_registers[i], tmp);
1897 +               }
1898 +       }
1899 +
1900 +       pcf->standby_regs.int1m = __reg_read(pcf, PCF50606_REG_INT1M);
1901 +       pcf->standby_regs.int2m = __reg_read(pcf, PCF50606_REG_INT2M);
1902 +       pcf->standby_regs.int3m = __reg_read(pcf, PCF50606_REG_INT3M);
1903 +       __reg_write(pcf, PCF50606_REG_INT1M, ~INT1M_RESUMERS & 0xff);
1904 +       __reg_write(pcf, PCF50606_REG_INT2M, ~INT2M_RESUMERS & 0xff);
1905 +       __reg_write(pcf, PCF50606_REG_INT3M, ~INT3M_RESUMERS & 0xff);
1906 +
1907 +       mutex_unlock(&pcf->lock);
1908 +
1909 +       return 0;
1910 +}
1911 +
1912 +static int pcf50606_resume(struct device *dev)
1913 +{
1914 +       struct i2c_client *client = to_i2c_client(dev);
1915 +       struct pcf50606_data *pcf = i2c_get_clientdata(client);
1916 +
1917 +       mutex_lock(&pcf->lock);
1918 +
1919 +       /* Resume all saved registers that don't "survive" standby state */
1920 +       __reg_write(pcf, PCF50606_REG_INT1M, pcf->standby_regs.int1m);
1921 +       __reg_write(pcf, PCF50606_REG_INT2M, pcf->standby_regs.int2m);
1922 +       __reg_write(pcf, PCF50606_REG_INT3M, pcf->standby_regs.int3m);
1923 +
1924 +       __reg_write(pcf, PCF50606_REG_DCDC1, pcf->standby_regs.dcdc1);
1925 +       __reg_write(pcf, PCF50606_REG_DCDC2, pcf->standby_regs.dcdc2);
1926 +       __reg_write(pcf, PCF50606_REG_DCDEC1, pcf->standby_regs.dcdec1);
1927 +       __reg_write(pcf, PCF50606_REG_DCUDC1, pcf->standby_regs.dcudc1);
1928 +       __reg_write(pcf, PCF50606_REG_IOREGC, pcf->standby_regs.ioregc);
1929 +       __reg_write(pcf, PCF50606_REG_D1REGC1, pcf->standby_regs.d1regc1);
1930 +       __reg_write(pcf, PCF50606_REG_D2REGC1, pcf->standby_regs.d2regc1);
1931 +       __reg_write(pcf, PCF50606_REG_D3REGC1, pcf->standby_regs.d3regc1);
1932 +       __reg_write(pcf, PCF50606_REG_LPREGC1, pcf->standby_regs.lpregc1);
1933 +       __reg_write(pcf, PCF50606_REG_ADCC1, pcf->standby_regs.adcc1);
1934 +       __reg_write(pcf, PCF50606_REG_ADCC2, pcf->standby_regs.adcc2);
1935 +       __reg_write(pcf, PCF50606_REG_PWMC1, pcf->standby_regs.pwmc1);
1936 +
1937 +       mutex_unlock(&pcf->lock);
1938 +
1939 +       return 0;
1940 +}
1941 +#else
1942 +#define pcf50606_suspend NULL
1943 +#define pcf50606_resume NULL
1944 +#endif
1945 +
1946 +static struct i2c_driver pcf50606_driver = {
1947 +       .driver = {
1948 +               .name    = "pcf50606",
1949 +               .suspend = pcf50606_suspend,
1950 +               .resume  = pcf50606_resume,
1951 +       },
1952 +       .id             = I2C_DRIVERID_PCF50606,
1953 +       .attach_adapter = pcf50606_attach_adapter,
1954 +       .detach_client  = pcf50606_detach_client,
1955 +};
1956 +
1957 +/* platform driver, since i2c devices don't have platform_data */
1958 +static int __init pcf50606_plat_probe(struct platform_device *pdev)
1959 +{
1960 +       struct pcf50606_platform_data *pdata = pdev->dev.platform_data;
1961 +
1962 +       if (!pdata)
1963 +               return -ENODEV;
1964 +
1965 +       pcf50606_pdev = pdev;
1966 +
1967 +       return 0;
1968 +}
1969 +
1970 +static int pcf50606_plat_remove(struct platform_device *pdev)
1971 +{
1972 +       return 0;
1973 +}
1974 +
1975 +static struct platform_driver pcf50606_plat_driver = {
1976 +       .probe  = pcf50606_plat_probe,
1977 +       .remove = pcf50606_plat_remove,
1978 +       .driver = {
1979 +               .owner  = THIS_MODULE,
1980 +               .name   = "pcf50606",
1981 +       },
1982 +};
1983 +
1984 +static int __init pcf50606_init(void)
1985 +{
1986 +       int rc;
1987 +
1988 +       rc = platform_driver_register(&pcf50606_plat_driver);
1989 +       if (!rc)
1990 +               rc = i2c_add_driver(&pcf50606_driver);
1991 +
1992 +       return rc;
1993 +}
1994 +
1995 +static void pcf50606_exit(void)
1996 +{
1997 +       i2c_del_driver(&pcf50606_driver);
1998 +       platform_driver_unregister(&pcf50606_plat_driver);
1999 +}
2000 +
2001 +MODULE_DESCRIPTION("I2C chip driver for NXP PCF50606 power management unit");
2002 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
2003 +MODULE_LICENSE("GPL");
2004 +
2005 +module_init(pcf50606_init);
2006 +module_exit(pcf50606_exit);
2007 diff --git a/drivers/i2c/chips/pcf50606.h b/drivers/i2c/chips/pcf50606.h
2008 new file mode 100644
2009 index 0000000..15b350f
2010 --- /dev/null
2011 +++ b/drivers/i2c/chips/pcf50606.h
2012 @@ -0,0 +1,302 @@
2013 +#ifndef _PCF50606_H
2014 +#define _PCF50606_H
2015 +
2016 +/* Philips PCF50606 Power Managemnt Unit (PMU) driver
2017 + * (C) 2006-2007 by OpenMoko, Inc.
2018 + * Author: Harald Welte <laforge@openmoko.org>
2019 + *
2020 + */
2021 +
2022 +enum pfc50606_regs {
2023 +       PCF50606_REG_ID         = 0x00,
2024 +       PCF50606_REG_OOCS       = 0x01,
2025 +       PCF50606_REG_INT1       = 0x02, /* Interrupt Status */
2026 +       PCF50606_REG_INT2       = 0x03, /* Interrupt Status */
2027 +       PCF50606_REG_INT3       = 0x04, /* Interrupt Status */
2028 +       PCF50606_REG_INT1M      = 0x05, /* Interrupt Mask */
2029 +       PCF50606_REG_INT2M      = 0x06, /* Interrupt Mask */
2030 +       PCF50606_REG_INT3M      = 0x07, /* Interrupt Mask */
2031 +       PCF50606_REG_OOCC1      = 0x08,
2032 +       PCF50606_REG_OOCC2      = 0x09,
2033 +       PCF50606_REG_RTCSC      = 0x0a, /* Second */
2034 +       PCF50606_REG_RTCMN      = 0x0b, /* Minute */
2035 +       PCF50606_REG_RTCHR      = 0x0c, /* Hour */
2036 +       PCF50606_REG_RTCWD      = 0x0d, /* Weekday */
2037 +       PCF50606_REG_RTCDT      = 0x0e, /* Day */
2038 +       PCF50606_REG_RTCMT      = 0x0f, /* Month */
2039 +       PCF50606_REG_RTCYR      = 0x10, /* Year */
2040 +       PCF50606_REG_RTCSCA     = 0x11, /* Alarm Second */
2041 +       PCF50606_REG_RTCMNA     = 0x12, /* Alarm Minute */
2042 +       PCF50606_REG_RTCHRA     = 0x13, /* Alarm Hour */
2043 +       PCF50606_REG_RTCWDA     = 0x14, /* Alarm Weekday */
2044 +       PCF50606_REG_RTCDTA     = 0x15, /* Alarm Day */
2045 +       PCF50606_REG_RTCMTA     = 0x16, /* Alarm Month */
2046 +       PCF50606_REG_RTCYRA     = 0x17, /* Alarm Year */
2047 +       PCF50606_REG_PSSC       = 0x18, /* Power sequencing */
2048 +       PCF50606_REG_PWROKM     = 0x19, /* PWROK mask */
2049 +       PCF50606_REG_PWROKS     = 0x1a, /* PWROK status */
2050 +       PCF50606_REG_DCDC1      = 0x1b,
2051 +       PCF50606_REG_DCDC2      = 0x1c,
2052 +       PCF50606_REG_DCDC3      = 0x1d,
2053 +       PCF50606_REG_DCDC4      = 0x1e,
2054 +       PCF50606_REG_DCDEC1     = 0x1f,
2055 +       PCF50606_REG_DCDEC2     = 0x20,
2056 +       PCF50606_REG_DCUDC1     = 0x21,
2057 +       PCF50606_REG_DCUDC2     = 0x22,
2058 +       PCF50606_REG_IOREGC     = 0x23,
2059 +       PCF50606_REG_D1REGC1    = 0x24,
2060 +       PCF50606_REG_D2REGC1    = 0x25,
2061 +       PCF50606_REG_D3REGC1    = 0x26,
2062 +       PCF50606_REG_LPREGC1    = 0x27,
2063 +       PCF50606_REG_LPREGC2    = 0x28,
2064 +       PCF50606_REG_MBCC1      = 0x29,
2065 +       PCF50606_REG_MBCC2      = 0x2a,
2066 +       PCF50606_REG_MBCC3      = 0x2b,
2067 +       PCF50606_REG_MBCS1      = 0x2c,
2068 +       PCF50606_REG_BBCC       = 0x2d,
2069 +       PCF50606_REG_ADCC1      = 0x2e,
2070 +       PCF50606_REG_ADCC2      = 0x2f,
2071 +       PCF50606_REG_ADCS1      = 0x30,
2072 +       PCF50606_REG_ADCS2      = 0x31,
2073 +       PCF50606_REG_ADCS3      = 0x32,
2074 +       PCF50606_REG_ACDC1      = 0x33,
2075 +       PCF50606_REG_BVMC       = 0x34,
2076 +       PCF50606_REG_PWMC1      = 0x35,
2077 +       PCF50606_REG_LEDC1      = 0x36,
2078 +       PCF50606_REG_LEDC2      = 0x37,
2079 +       PCF50606_REG_GPOC1      = 0x38,
2080 +       PCF50606_REG_GPOC2      = 0x39,
2081 +       PCF50606_REG_GPOC3      = 0x3a,
2082 +       PCF50606_REG_GPOC4      = 0x3b,
2083 +       PCF50606_REG_GPOC5      = 0x3c,
2084 +       __NUM_PCF50606_REGS
2085 +};
2086 +
2087 +enum pcf50606_reg_oocs {
2088 +       PFC50606_OOCS_ONKEY     = 0x01,
2089 +       PCF50606_OOCS_EXTON     = 0x02,
2090 +       PCF50606_OOCS_PWROKRST  = 0x04,
2091 +       PCF50606_OOCS_BATOK     = 0x08,
2092 +       PCF50606_OOCS_BACKOK    = 0x10,
2093 +       PCF50606_OOCS_CHGOK     = 0x20,
2094 +       PCF50606_OOCS_TEMPOK    = 0x40,
2095 +       PCF50606_OOCS_WDTEXP    = 0x80,
2096 +};
2097 +
2098 +enum pcf50606_reg_oocc1 {
2099 +       PCF50606_OOCC1_GOSTDBY  = 0x01,
2100 +       PCF50606_OOCC1_TOTRST   = 0x02,
2101 +       PCF50606_OOCC1_CLK32ON  = 0x04,
2102 +       PCF50606_OOCC1_WDTRST   = 0x08,
2103 +       PCF50606_OOCC1_RTCWAK   = 0x10,
2104 +       PCF50606_OOCC1_CHGWAK   = 0x20,
2105 +       PCF50606_OOCC1_EXTONWAK_HIGH    = 0x40,
2106 +       PCF50606_OOCC1_EXTONWAK_LOW     = 0x80,
2107 +};
2108 +
2109 +enum pcf50606_reg_oocc2 {
2110 +       PCF50606_OOCC2_ONKEYDB_NONE     = 0x00,
2111 +       PCF50606_OOCC2_ONKEYDB_14ms     = 0x01,
2112 +       PCF50606_OOCC2_ONKEYDB_62ms     = 0x02,
2113 +       PCF50606_OOCC2_ONKEYDB_500ms    = 0x03,
2114 +       PCF50606_OOCC2_EXTONDB_NONE     = 0x00,
2115 +       PCF50606_OOCC2_EXTONDB_14ms     = 0x04,
2116 +       PCF50606_OOCC2_EXTONDB_62ms     = 0x08,
2117 +       PCF50606_OOCC2_EXTONDB_500ms    = 0x0c,
2118 +};
2119 +
2120 +enum pcf50606_reg_int1 {
2121 +       PCF50606_INT1_ONKEYR    = 0x01, /* ONKEY rising edge */
2122 +       PCF50606_INT1_ONKEYF    = 0x02, /* ONKEY falling edge */
2123 +       PCF50606_INT1_ONKEY1S   = 0x04, /* OMKEY at least 1sec low */
2124 +       PCF50606_INT1_EXTONR    = 0x08, /* EXTON rising edge */
2125 +       PCF50606_INT1_EXTONF    = 0x10, /* EXTON falling edge */
2126 +       PCF50606_INT1_SECOND    = 0x40, /* RTC periodic second interrupt */
2127 +       PCF50606_INT1_ALARM     = 0x80, /* RTC alarm time is reached */
2128 +};
2129 +
2130 +enum pcf50606_reg_int2 {
2131 +       PCF50606_INT2_CHGINS    = 0x01, /* Charger inserted */
2132 +       PCF50606_INT2_CHGRM     = 0x02, /* Charger removed */
2133 +       PCF50606_INT2_CHGFOK    = 0x04, /* Fast charging OK */
2134 +       PCF50606_INT2_CHGERR    = 0x08, /* Error in charging mode */
2135 +       PCF50606_INT2_CHGFRDY   = 0x10, /* Fast charge completed */
2136 +       PCF50606_INT2_CHGPROT   = 0x20, /* Charging protection interrupt */
2137 +       PCF50606_INT2_CHGWD10S  = 0x40, /* Charger watchdig expires in 10s */
2138 +       PCF50606_INT2_CHGWDEXP  = 0x80, /* Charger watchdog expires */
2139 +};
2140 +
2141 +enum pcf50606_reg_int3 {
2142 +       PCF50606_INT3_ADCRDY    = 0x01, /* ADC conversion finished */
2143 +       PCF50606_INT3_ACDINS    = 0x02, /* Accessory inserted */
2144 +       PCF50606_INT3_ACDREM    = 0x04, /* Accessory removed */
2145 +       PCF50606_INT3_TSCPRES   = 0x08, /* Touch screen pressed */
2146 +       PCF50606_INT3_LOWBAT    = 0x40, /* Low battery voltage */
2147 +       PCF50606_INT3_HIGHTMP   = 0x80, /* High temperature */
2148 +};
2149 +
2150 +/* used by PSSC, PWROKM, PWROKS, */
2151 +enum pcf50606_regu {
2152 +       PCF50606_REGU_DCD       = 0x01, /* DCD in phase 2 */
2153 +       PCF50606_REGU_DCDE      = 0x02, /* DCDE in phase 2 */
2154 +       PCF50606_REGU_DCUD      = 0x04, /* DCDU in phase 2 */
2155 +       PCF50606_REGU_IO        = 0x08, /* IO in phase 2 */
2156 +       PCF50606_REGU_D1        = 0x10, /* D1 in phase 2 */
2157 +       PCF50606_REGU_D2        = 0x20, /* D2 in phase 2 */
2158 +       PCF50606_REGU_D3        = 0x40, /* D3 in phase 2 */
2159 +       PCF50606_REGU_LP        = 0x80, /* LP in phase 2 */
2160 +};
2161 +
2162 +enum pcf50606_reg_dcdc4 {
2163 +       PCF50606_DCDC4_MODE_AUTO        = 0x00,
2164 +       PCF50606_DCDC4_MODE_PWM         = 0x01,
2165 +       PCF50606_DCDC4_MODE_PCF         = 0x02,
2166 +       PCF50606_DCDC4_OFF_FLOAT        = 0x00,
2167 +       PCF50606_DCDC4_OFF_BYPASS       = 0x04,
2168 +       PCF50606_DCDC4_OFF_PULLDOWN     = 0x08,
2169 +       PCF50606_DCDC4_CURLIM_500mA     = 0x00,
2170 +       PCF50606_DCDC4_CURLIM_750mA     = 0x10,
2171 +       PCF50606_DCDC4_CURLIM_1000mA    = 0x20,
2172 +       PCF50606_DCDC4_CURLIM_1250mA    = 0x30,
2173 +       PCF50606_DCDC4_TOGGLE           = 0x40,
2174 +       PCF50606_DCDC4_REGSEL_DCDC2     = 0x80,
2175 +};
2176 +
2177 +enum pcf50606_reg_dcdec2 {
2178 +       PCF50606_DCDEC2_MODE_AUTO       = 0x00,
2179 +       PCF50606_DCDEC2_MODE_PWM        = 0x01,
2180 +       PCF50606_DCDEC2_MODE_PCF        = 0x02,
2181 +       PCF50606_DCDEC2_OFF_FLOAT       = 0x00,
2182 +       PCF50606_DCDEC2_OFF_BYPASS      = 0x04,
2183 +};
2184 +
2185 +enum pcf50606_reg_dcudc2 {
2186 +       PCF50606_DCUDC2_MODE_AUTO       = 0x00,
2187 +       PCF50606_DCUDC2_MODE_PWM        = 0x01,
2188 +       PCF50606_DCUDC2_MODE_PCF        = 0x02,
2189 +       PCF50606_DCUDC2_OFF_FLOAT       = 0x00,
2190 +       PCF50606_DCUDC2_OFF_BYPASS      = 0x04,
2191 +};
2192 +
2193 +enum pcf50606_reg_adcc1 {
2194 +       PCF50606_ADCC1_TSCMODACT        = 0x01,
2195 +       PCF50606_ADCC1_TSCMODSTB        = 0x02,
2196 +       PCF50606_ADCC1_TRATSET          = 0x04,
2197 +       PCF50606_ADCC1_NTCSWAPE         = 0x08,
2198 +       PCF50606_ADCC1_NTCSWAOFF        = 0x10,
2199 +       PCF50606_ADCC1_EXTSYNCBREAK     = 0x20,
2200 +       /* reserved */
2201 +       PCF50606_ADCC1_TSCINT           = 0x80,
2202 +};
2203 +
2204 +enum pcf50606_reg_adcc2 {
2205 +       PCF50606_ADCC2_ADCSTART         = 0x01,
2206 +       /* see enum pcf50606_adcc2_adcmux */
2207 +       PCF50606_ADCC2_SYNC_NONE        = 0x00,
2208 +       PCF50606_ADCC2_SYNC_TXON        = 0x20,
2209 +       PCF50606_ADCC2_SYNC_PWREN1      = 0x40,
2210 +       PCF50606_ADCC2_SYNC_PWREN2      = 0x60,
2211 +       PCF50606_ADCC2_RES_10BIT        = 0x00,
2212 +       PCF50606_ADCC2_RES_8BIT         = 0x80,
2213 +};
2214 +
2215 +#define PCF50606_ADCC2_ADCMUX_MASK     (0xf << 1)
2216 +
2217 +#define ADCMUX_SHIFT   1
2218 +enum pcf50606_adcc2_adcmux {
2219 +       PCF50606_ADCMUX_BATVOLT_RES     = 0x0 << ADCMUX_SHIFT,
2220 +       PCF50606_ADCMUX_BATVOLT_SUBTR   = 0x1 << ADCMUX_SHIFT,
2221 +       PCF50606_ADCMUX_ADCIN1_RES      = 0x2 << ADCMUX_SHIFT,
2222 +       PCF50606_ADCMUX_ADCIN1_SUBTR    = 0x3 << ADCMUX_SHIFT,
2223 +       PCF50606_ADCMUX_BATTEMP         = 0x4 << ADCMUX_SHIFT,
2224 +       PCF50606_ADCMUX_ADCIN2          = 0x5 << ADCMUX_SHIFT,
2225 +       PCF50606_ADCMUX_ADCIN3          = 0x6 << ADCMUX_SHIFT,
2226 +       PCF50606_ADCMUX_ADCIN3_RATIO    = 0x7 << ADCMUX_SHIFT,
2227 +       PCF50606_ADCMUX_XPOS            = 0x8 << ADCMUX_SHIFT,
2228 +       PCF50606_ADCMUX_YPOS            = 0x9 << ADCMUX_SHIFT,
2229 +       PCF50606_ADCMUX_P1              = 0xa << ADCMUX_SHIFT,
2230 +       PCF50606_ADCMUX_P2              = 0xb << ADCMUX_SHIFT,
2231 +       PCF50606_ADCMUX_BATVOLT_ADCIN1  = 0xc << ADCMUX_SHIFT,
2232 +       PCF50606_ADCMUX_XY_SEQUENCE     = 0xe << ADCMUX_SHIFT,
2233 +       PCF50606_P1_P2_RESISTANCE       = 0xf << ADCMUX_SHIFT,
2234 +};
2235 +
2236 +enum pcf50606_adcs2 {
2237 +       PCF50606_ADCS2_ADCRDY           = 0x80,
2238 +};
2239 +
2240 +enum pcf50606_reg_mbcc1 {
2241 +       PCF50606_MBCC1_CHGAPE           = 0x01,
2242 +       PCF50606_MBCC1_AUTOFST          = 0x02,
2243 +#define        PCF50606_MBCC1_CHGMOD_MASK        0x1c
2244 +#define        PCF50606_MBCC1_CHGMOD_SHIFT       2
2245 +       PCF50606_MBCC1_CHGMOD_QUAL      = 0x00,
2246 +       PCF50606_MBCC1_CHGMOD_PRE       = 0x04,
2247 +       PCF50606_MBCC1_CHGMOD_TRICKLE   = 0x08,
2248 +       PCF50606_MBCC1_CHGMOD_FAST_CCCV = 0x0c,
2249 +       PCF50606_MBCC1_CHGMOD_FAST_NOCC = 0x10,
2250 +       PCF50606_MBCC1_CHGMOD_FAST_NOCV = 0x14,
2251 +       PCF50606_MBCC1_CHGMOD_FAST_SW   = 0x18,
2252 +       PCF50606_MBCC1_CHGMOD_IDLE      = 0x1c,
2253 +       PCF50606_MBCC1_DETMOD_LOWCHG    = 0x20,
2254 +       PCF50606_MBCC1_DETMOD_WDRST     = 0x40,
2255 +};
2256 +
2257 +enum pcf50606_reg_acdc1 {
2258 +       PCF50606_ACDC1_ACDDET           = 0x01,
2259 +       PCF50606_ACDC1_THRSHLD_1V0      = 0x00,
2260 +       PCF50606_ACDC1_THRSHLD_1V2      = 0x02,
2261 +       PCF50606_ACDC1_THRSHLD_1V4      = 0x04,
2262 +       PCF50606_ACDC1_THRSHLD_1V6      = 0x06,
2263 +       PCF50606_ACDC1_THRSHLD_1V8      = 0x08,
2264 +       PCF50606_ACDC1_THRSHLD_2V0      = 0x0a,
2265 +       PCF50606_ACDC1_THRSHLD_2V2      = 0x0c,
2266 +       PCF50606_ACDC1_THRSHLD_2V4      = 0x0e,
2267 +       PCF50606_ACDC1_DISDB            = 0x10,
2268 +       PCF50606_ACDC1_ACDAPE           = 0x80,
2269 +};
2270 +
2271 +enum pcf50606_reg_bvmc {
2272 +       PCF50606_BVMC_LOWBAT            = 0x01,
2273 +       PCF50606_BVMC_THRSHLD_NULL      = 0x00,
2274 +       PCF50606_BVMC_THRSHLD_2V8       = 0x02,
2275 +       PCF50606_BVMC_THRSHLD_2V9       = 0x04,
2276 +       PCF50606_BVMC_THRSHLD_3V        = 0x08,
2277 +       PCF50606_BVMC_THRSHLD_3V1       = 0x08,
2278 +       PCF50606_BVMC_THRSHLD_3V2       = 0x0a,
2279 +       PCF50606_BVMC_THRSHLD_3V3       = 0x0c,
2280 +       PCF50606_BVMC_THRSHLD_3V4       = 0x0e,
2281 +       PCF50606_BVMC_DISDB             = 0x10,
2282 +};
2283 +
2284 +enum pcf50606_reg_pwmc1 {
2285 +       PCF50606_PWMC1_ACTSET           = 0x01,
2286 +       PCF50606_PWMC1_PWMDC_0_16       = 0x00,
2287 +       PCF50606_PWMC1_PWMDC_1_16       = 0x02,
2288 +       PCF50606_PWMC1_PWMDC_2_16       = 0x04,
2289 +       PCF50606_PWMC1_PWMDC_3_16       = 0x06,
2290 +       PCF50606_PWMC1_PWMDC_4_16       = 0x08,
2291 +       PCF50606_PWMC1_PWMDC_5_16       = 0x0a,
2292 +       PCF50606_PWMC1_PWMDC_6_16       = 0x0c,
2293 +       PCF50606_PWMC1_PWMDC_7_16       = 0x0e,
2294 +       PCF50606_PWMC1_PWMDC_8_16       = 0x10,
2295 +       PCF50606_PWMC1_PWMDC_9_16       = 0x12,
2296 +       PCF50606_PWMC1_PWMDC_10_16      = 0x14,
2297 +       PCF50606_PWMC1_PWMDC_11_16      = 0x16,
2298 +       PCF50606_PWMC1_PWMDC_12_16      = 0x18,
2299 +       PCF50606_PWMC1_PWMDC_13_16      = 0x1a,
2300 +       PCF50606_PWMC1_PWMDC_14_16      = 0x1c,
2301 +       PCF50606_PWMC1_PWMDC_15_16      = 0x1e,
2302 +       PCF50606_PWMC1_PRESC_512Hz      = 0x20,
2303 +       PCF50606_PWMC1_PRESC_256Hz      = 0x40,
2304 +       PCF50606_PWMC1_PRESC_64Hz       = 0x60,
2305 +       PCF50606_PWMC1_PRESC_56kHz      = 0x80,
2306 +       PCF50606_PWMC1_PRESC_28kHz      = 0xa0,
2307 +       PCF50606_PWMC1_PRESC_14kHz      = 0xc0,
2308 +       PCF50606_PWMC1_PRESC_7kHz       = 0xe0,
2309 +};
2310 +#define PCF50606_PWMC1_CLK_SHIFT       5
2311 +#define PCF50606_PWMC1_DC_SHIFT                1
2312 +
2313 +#endif /* _PCF50606_H */
2314 +
2315 diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
2316 index 580acc9..2cda699 100644
2317 --- a/include/linux/i2c-id.h
2318 +++ b/include/linux/i2c-id.h
2319 @@ -94,6 +94,7 @@
2320  #define I2C_DRIVERID_I2CDEV    900
2321  
2322  #define I2C_DRIVERID_OV7670 1048       /* Omnivision 7670 camera */
2323 +#define I2C_DRIVERID_PCF50606 1049
2324  
2325  /*
2326   * ---- Adapter types ----------------------------------------------------
2327 diff --git a/include/linux/pcf50606.h b/include/linux/pcf50606.h
2328 new file mode 100644
2329 index 0000000..bc98e47
2330 --- /dev/null
2331 +++ b/include/linux/pcf50606.h
2332 @@ -0,0 +1,108 @@
2333 +#ifndef _LINUX_PCF50606_H
2334 +#define _LINUX_PCF50606_H
2335 +
2336 +/* public in-kernel pcf50606 api */
2337 +enum pcf50606_regulator_id {
2338 +       PCF50606_REGULATOR_DCD,
2339 +       PCF50606_REGULATOR_DCDE,
2340 +       PCF50606_REGULATOR_DCUD,
2341 +       PCF50606_REGULATOR_D1REG,
2342 +       PCF50606_REGULATOR_D2REG,
2343 +       PCF50606_REGULATOR_D3REG,
2344 +       PCF50606_REGULATOR_LPREG,
2345 +       PCF50606_REGULATOR_IOREG,
2346 +       __NUM_PCF50606_REGULATORS
2347 +};
2348 +
2349 +struct pcf50606_data;
2350 +
2351 +/* This is an ugly construct on how to access the (currently single/global)
2352 + * pcf50606 handle from other code in the kernel.  I didn't really come up with
2353 + * a more decent method of dynamically resolving this */
2354 +extern struct pcf50606_data *pcf50606_global;
2355 +
2356 +extern void
2357 +pcf50606_go_standby(void);
2358 +
2359 +extern void
2360 +pcf50606_gpo0_set(struct pcf50606_data *pcf, int on);
2361 +
2362 +extern int
2363 +pcf50606_gpo0_get(struct pcf50606_data *pcf);
2364 +
2365 +extern int
2366 +pcf50606_voltage_set(struct pcf50606_data *pcf,
2367 +                    enum pcf50606_regulator_id reg,
2368 +                    unsigned int millivolts);
2369 +extern unsigned int
2370 +pcf50606_voltage_get(struct pcf50606_data *pcf,
2371 +                    enum pcf50606_regulator_id reg);
2372 +extern int
2373 +pcf50606_onoff_get(struct pcf50606_data *pcf,
2374 +                  enum pcf50606_regulator_id reg);
2375 +
2376 +extern int
2377 +pcf50606_onoff_set(struct pcf50606_data *pcf,
2378 +                  enum pcf50606_regulator_id reg, int on);
2379 +
2380 +extern void
2381 +pcf50606_charge_fast(struct pcf50606_data *pcf, int on);
2382 +
2383 +#define PMU_VRAIL_F_SUSPEND_ON 0x00000001      /* Remains on during suspend */
2384 +#define PMU_VRAIL_F_UNUSED     0x00000002      /* This rail is not used */
2385 +struct pmu_voltage_rail {
2386 +       char *name;
2387 +       unsigned int flags;
2388 +       struct {
2389 +               unsigned int init;
2390 +               unsigned int max;
2391 +       } voltage;
2392 +};
2393 +
2394 +enum pmu_event {
2395 +       PMU_EVT_NONE,
2396 +       PMU_EVT_INSERT,
2397 +       PMU_EVT_REMOVE,
2398 +       __NUM_PMU_EVTS
2399 +};
2400 +
2401 +typedef int pmu_cb(struct device *dev, unsigned int feature,
2402 +                  enum pmu_event event);
2403 +
2404 +#define PCF50606_FEAT_EXTON    0x00000001      /* not yet supported */
2405 +#define PCF50606_FEAT_MBC      0x00000002
2406 +#define PCF50606_FEAT_BBC      0x00000004      /* not yet supported */
2407 +#define PCF50606_FEAT_TSC      0x00000008      /* not yet supported */
2408 +#define PCF50606_FEAT_WDT      0x00000010
2409 +#define PCF50606_FEAT_ACD      0x00000020
2410 +#define PCF50606_FEAT_RTC      0x00000040
2411 +#define PCF50606_FEAT_PWM      0x00000080
2412 +#define PCF50606_FEAT_CHGCUR   0x00000100
2413 +#define PCF50606_FEAT_BATVOLT  0x00000200
2414 +#define PCF50606_FEAT_BATTEMP  0x00000400
2415 +#define PCF50606_FEAT_PWM_BL   0x00000800
2416 +
2417 +struct pcf50606_platform_data {
2418 +       /* general */
2419 +       unsigned int used_features;
2420 +       unsigned int onkey_seconds_required;
2421 +
2422 +       /* voltage regulator related */
2423 +       struct pmu_voltage_rail rails[__NUM_PCF50606_REGULATORS];
2424 +       unsigned int used_regulators;
2425 +
2426 +       /* charger related */
2427 +       unsigned int r_fix_batt;
2428 +       unsigned int r_fix_batt_par;
2429 +       unsigned int r_sense_milli;
2430 +
2431 +       /* backlight related */
2432 +       unsigned int init_brightness;
2433 +
2434 +       struct {
2435 +               u_int8_t mbcc3; /* charger voltage / current */
2436 +       } charger;
2437 +       pmu_cb *cb;
2438 +};
2439 +
2440 +#endif
2441 -- 
2442 1.5.6.3
2443