Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / mfd / twl4030-power.c
1 /*
2  * linux/drivers/i2c/chips/twl4030-power.c
3  *
4  * Handle TWL4030 Power initialization
5  *
6  * Copyright (C) 2008 Nokia Corporation
7  * Copyright (C) 2006 Texas Instruments, Inc
8  *
9  * Written by   Kalle Jokiniemi
10  *              Peter De Schrijver <peter.de-schrijver@nokia.com>
11  * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com>
12  *
13  * This file is subject to the terms and conditions of the GNU General
14  * Public License. See the file "COPYING" in the main directory of this
15  * archive for more details.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27 #include <linux/module.h>
28 #include <linux/pm.h>
29 #include <linux/i2c/twl.h>
30 #include <linux/platform_device.h>
31 #include <linux/of.h>
32 #include <linux/of_device.h>
33
34 #include <asm/mach-types.h>
35
36 static u8 twl4030_start_script_address = 0x2b;
37
38 /* Register bits for P1, P2 and P3_SW_EVENTS */
39 #define PWR_STOPON_PRWON        BIT(6)
40 #define PWR_STOPON_SYSEN        BIT(5)
41 #define PWR_ENABLE_WARMRESET    BIT(4)
42 #define PWR_LVL_WAKEUP          BIT(3)
43 #define PWR_DEVACT              BIT(2)
44 #define PWR_DEVSLP              BIT(1)
45 #define PWR_DEVOFF              BIT(0)
46
47 /* Register bits for CFG_P1_TRANSITION (also for P2 and P3) */
48 #define STARTON_SWBUG           BIT(7)  /* Start on watchdog */
49 #define STARTON_VBUS            BIT(5)  /* Start on VBUS */
50 #define STARTON_VBAT            BIT(4)  /* Start on battery insert */
51 #define STARTON_RTC             BIT(3)  /* Start on RTC */
52 #define STARTON_USB             BIT(2)  /* Start on USB host */
53 #define STARTON_CHG             BIT(1)  /* Start on charger */
54 #define STARTON_PWON            BIT(0)  /* Start on PWRON button */
55
56 #define SEQ_OFFSYNC             (1 << 0)
57
58 #define PHY_TO_OFF_PM_MASTER(p)         (p - 0x36)
59 #define PHY_TO_OFF_PM_RECEIVER(p)       (p - 0x5b)
60
61 /* resource - hfclk */
62 #define R_HFCLKOUT_DEV_GRP      PHY_TO_OFF_PM_RECEIVER(0xe6)
63
64 /* PM events */
65 #define R_P1_SW_EVENTS          PHY_TO_OFF_PM_MASTER(0x46)
66 #define R_P2_SW_EVENTS          PHY_TO_OFF_PM_MASTER(0x47)
67 #define R_P3_SW_EVENTS          PHY_TO_OFF_PM_MASTER(0x48)
68 #define R_CFG_P1_TRANSITION     PHY_TO_OFF_PM_MASTER(0x36)
69 #define R_CFG_P2_TRANSITION     PHY_TO_OFF_PM_MASTER(0x37)
70 #define R_CFG_P3_TRANSITION     PHY_TO_OFF_PM_MASTER(0x38)
71
72 #define END_OF_SCRIPT           0x3f
73
74 #define R_SEQ_ADD_A2S           PHY_TO_OFF_PM_MASTER(0x55)
75 #define R_SEQ_ADD_S2A12         PHY_TO_OFF_PM_MASTER(0x56)
76 #define R_SEQ_ADD_S2A3          PHY_TO_OFF_PM_MASTER(0x57)
77 #define R_SEQ_ADD_WARM          PHY_TO_OFF_PM_MASTER(0x58)
78 #define R_MEMORY_ADDRESS        PHY_TO_OFF_PM_MASTER(0x59)
79 #define R_MEMORY_DATA           PHY_TO_OFF_PM_MASTER(0x5a)
80
81 /* resource configuration registers
82    <RESOURCE>_DEV_GRP   at address 'n+0'
83    <RESOURCE>_TYPE      at address 'n+1'
84    <RESOURCE>_REMAP     at address 'n+2'
85    <RESOURCE>_DEDICATED at address 'n+3'
86 */
87 #define DEV_GRP_OFFSET          0
88 #define TYPE_OFFSET             1
89 #define REMAP_OFFSET            2
90 #define DEDICATED_OFFSET        3
91
92 /* Bit positions in the registers */
93
94 /* <RESOURCE>_DEV_GRP */
95 #define DEV_GRP_SHIFT           5
96 #define DEV_GRP_MASK            (7 << DEV_GRP_SHIFT)
97
98 /* <RESOURCE>_TYPE */
99 #define TYPE_SHIFT              0
100 #define TYPE_MASK               (7 << TYPE_SHIFT)
101 #define TYPE2_SHIFT             3
102 #define TYPE2_MASK              (3 << TYPE2_SHIFT)
103
104 /* <RESOURCE>_REMAP */
105 #define SLEEP_STATE_SHIFT       0
106 #define SLEEP_STATE_MASK        (0xf << SLEEP_STATE_SHIFT)
107 #define OFF_STATE_SHIFT         4
108 #define OFF_STATE_MASK          (0xf << OFF_STATE_SHIFT)
109
110 static u8 res_config_addrs[] = {
111         [RES_VAUX1]     = 0x17,
112         [RES_VAUX2]     = 0x1b,
113         [RES_VAUX3]     = 0x1f,
114         [RES_VAUX4]     = 0x23,
115         [RES_VMMC1]     = 0x27,
116         [RES_VMMC2]     = 0x2b,
117         [RES_VPLL1]     = 0x2f,
118         [RES_VPLL2]     = 0x33,
119         [RES_VSIM]      = 0x37,
120         [RES_VDAC]      = 0x3b,
121         [RES_VINTANA1]  = 0x3f,
122         [RES_VINTANA2]  = 0x43,
123         [RES_VINTDIG]   = 0x47,
124         [RES_VIO]       = 0x4b,
125         [RES_VDD1]      = 0x55,
126         [RES_VDD2]      = 0x63,
127         [RES_VUSB_1V5]  = 0x71,
128         [RES_VUSB_1V8]  = 0x74,
129         [RES_VUSB_3V1]  = 0x77,
130         [RES_VUSBCP]    = 0x7a,
131         [RES_REGEN]     = 0x7f,
132         [RES_NRES_PWRON] = 0x82,
133         [RES_CLKEN]     = 0x85,
134         [RES_SYSEN]     = 0x88,
135         [RES_HFCLKOUT]  = 0x8b,
136         [RES_32KCLKOUT] = 0x8e,
137         [RES_RESET]     = 0x91,
138         [RES_MAIN_REF]  = 0x94,
139 };
140
141 /*
142  * Usable values for .remap_sleep and .remap_off
143  * Based on table "5.3.3 Resource Operating modes"
144  */
145 enum {
146         TWL_REMAP_OFF = 0,
147         TWL_REMAP_SLEEP = 8,
148         TWL_REMAP_ACTIVE = 9,
149 };
150
151 /*
152  * Macros to configure the PM register states for various resources.
153  * Note that we can make MSG_SINGULAR etc private to this driver once
154  * omap3 has been made DT only.
155  */
156 #define TWL_DFLT_DELAY          2       /* typically 2 32 KiHz cycles */
157 #define TWL_DEV_GRP_P123        (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3)
158 #define TWL_RESOURCE_SET(res, state)                                    \
159         { MSG_SINGULAR(DEV_GRP_NULL, (res), (state)), TWL_DFLT_DELAY }
160 #define TWL_RESOURCE_ON(res)    TWL_RESOURCE_SET(res, RES_STATE_ACTIVE)
161 #define TWL_RESOURCE_OFF(res)   TWL_RESOURCE_SET(res, RES_STATE_OFF)
162 #define TWL_RESOURCE_RESET(res) TWL_RESOURCE_SET(res, RES_STATE_WRST)
163 /*
164  * It seems that type1 and type2 is just the resource init order
165  * number for the type1 and type2 group.
166  */
167 #define TWL_RESOURCE_SET_ACTIVE(res, state)                             \
168         { MSG_SINGULAR(DEV_GRP_NULL, (res), RES_STATE_ACTIVE), (state) }
169 #define TWL_RESOURCE_GROUP_RESET(group, type1, type2)                   \
170         { MSG_BROADCAST(DEV_GRP_NULL, (group), (type1), (type2),        \
171                 RES_STATE_WRST), TWL_DFLT_DELAY }
172 #define TWL_RESOURCE_GROUP_SLEEP(group, type, type2)                    \
173         { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2),         \
174                 RES_STATE_SLEEP), TWL_DFLT_DELAY }
175 #define TWL_RESOURCE_GROUP_ACTIVE(group, type, type2)                   \
176         { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2),         \
177                 RES_STATE_ACTIVE), TWL_DFLT_DELAY }
178 #define TWL_REMAP_SLEEP(res, devgrp, typ, typ2)                         \
179         { .resource = (res), .devgroup = (devgrp),                      \
180           .type = (typ), .type2 = (typ2),                               \
181           .remap_off = TWL_REMAP_OFF,                                   \
182           .remap_sleep = TWL_REMAP_SLEEP, }
183 #define TWL_REMAP_OFF(res, devgrp, typ, typ2)                           \
184         { .resource = (res), .devgroup = (devgrp),                      \
185           .type = (typ), .type2 = (typ2),                               \
186           .remap_off = TWL_REMAP_OFF, .remap_sleep = TWL_REMAP_OFF, }
187
188 static int twl4030_write_script_byte(u8 address, u8 byte)
189 {
190         int err;
191
192         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS);
193         if (err)
194                 goto out;
195         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA);
196 out:
197         return err;
198 }
199
200 static int twl4030_write_script_ins(u8 address, u16 pmb_message,
201                                            u8 delay, u8 next)
202 {
203         int err;
204
205         address *= 4;
206         err = twl4030_write_script_byte(address++, pmb_message >> 8);
207         if (err)
208                 goto out;
209         err = twl4030_write_script_byte(address++, pmb_message & 0xff);
210         if (err)
211                 goto out;
212         err = twl4030_write_script_byte(address++, delay);
213         if (err)
214                 goto out;
215         err = twl4030_write_script_byte(address++, next);
216 out:
217         return err;
218 }
219
220 static int twl4030_write_script(u8 address, struct twl4030_ins *script,
221                                        int len)
222 {
223         int err = -EINVAL;
224
225         for (; len; len--, address++, script++) {
226                 if (len == 1) {
227                         err = twl4030_write_script_ins(address,
228                                                 script->pmb_message,
229                                                 script->delay,
230                                                 END_OF_SCRIPT);
231                         if (err)
232                                 break;
233                 } else {
234                         err = twl4030_write_script_ins(address,
235                                                 script->pmb_message,
236                                                 script->delay,
237                                                 address + 1);
238                         if (err)
239                                 break;
240                 }
241         }
242         return err;
243 }
244
245 static int twl4030_config_wakeup3_sequence(u8 address)
246 {
247         int err;
248         u8 data;
249
250         /* Set SLEEP to ACTIVE SEQ address for P3 */
251         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3);
252         if (err)
253                 goto out;
254
255         /* P3 LVL_WAKEUP should be on LEVEL */
256         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS);
257         if (err)
258                 goto out;
259         data |= PWR_LVL_WAKEUP;
260         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS);
261 out:
262         if (err)
263                 pr_err("TWL4030 wakeup sequence for P3 config error\n");
264         return err;
265 }
266
267 static int twl4030_config_wakeup12_sequence(u8 address)
268 {
269         int err = 0;
270         u8 data;
271
272         /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
273         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
274         if (err)
275                 goto out;
276
277         /* P1/P2 LVL_WAKEUP should be on LEVEL */
278         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
279         if (err)
280                 goto out;
281
282         data |= PWR_LVL_WAKEUP;
283         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
284         if (err)
285                 goto out;
286
287         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
288         if (err)
289                 goto out;
290
291         data |= PWR_LVL_WAKEUP;
292         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
293         if (err)
294                 goto out;
295
296         if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) {
297                 /* Disabling AC charger effect on sleep-active transitions */
298                 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
299                                       R_CFG_P1_TRANSITION);
300                 if (err)
301                         goto out;
302                 data &= ~(1<<1);
303                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
304                                        R_CFG_P1_TRANSITION);
305                 if (err)
306                         goto out;
307         }
308
309 out:
310         if (err)
311                 pr_err("TWL4030 wakeup sequence for P1 and P2" \
312                         "config error\n");
313         return err;
314 }
315
316 static int twl4030_config_sleep_sequence(u8 address)
317 {
318         int err;
319
320         /* Set ACTIVE to SLEEP SEQ address in T2 memory*/
321         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
322
323         if (err)
324                 pr_err("TWL4030 sleep sequence config error\n");
325
326         return err;
327 }
328
329 static int twl4030_config_warmreset_sequence(u8 address)
330 {
331         int err;
332         u8 rd_data;
333
334         /* Set WARM RESET SEQ address for P1 */
335         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
336         if (err)
337                 goto out;
338
339         /* P1/P2/P3 enable WARMRESET */
340         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
341         if (err)
342                 goto out;
343
344         rd_data |= PWR_ENABLE_WARMRESET;
345         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
346         if (err)
347                 goto out;
348
349         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
350         if (err)
351                 goto out;
352
353         rd_data |= PWR_ENABLE_WARMRESET;
354         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
355         if (err)
356                 goto out;
357
358         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
359         if (err)
360                 goto out;
361
362         rd_data |= PWR_ENABLE_WARMRESET;
363         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
364 out:
365         if (err)
366                 pr_err("TWL4030 warmreset seq config error\n");
367         return err;
368 }
369
370 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
371 {
372         int rconfig_addr;
373         int err;
374         u8 type;
375         u8 grp;
376         u8 remap;
377
378         if (rconfig->resource > TOTAL_RESOURCES) {
379                 pr_err("TWL4030 Resource %d does not exist\n",
380                         rconfig->resource);
381                 return -EINVAL;
382         }
383
384         rconfig_addr = res_config_addrs[rconfig->resource];
385
386         /* Set resource group */
387         err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
388                               rconfig_addr + DEV_GRP_OFFSET);
389         if (err) {
390                 pr_err("TWL4030 Resource %d group could not be read\n",
391                         rconfig->resource);
392                 return err;
393         }
394
395         if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
396                 grp &= ~DEV_GRP_MASK;
397                 grp |= rconfig->devgroup << DEV_GRP_SHIFT;
398                 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
399                                        grp, rconfig_addr + DEV_GRP_OFFSET);
400                 if (err < 0) {
401                         pr_err("TWL4030 failed to program devgroup\n");
402                         return err;
403                 }
404         }
405
406         /* Set resource types */
407         err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
408                                 rconfig_addr + TYPE_OFFSET);
409         if (err < 0) {
410                 pr_err("TWL4030 Resource %d type could not be read\n",
411                         rconfig->resource);
412                 return err;
413         }
414
415         if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
416                 type &= ~TYPE_MASK;
417                 type |= rconfig->type << TYPE_SHIFT;
418         }
419
420         if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
421                 type &= ~TYPE2_MASK;
422                 type |= rconfig->type2 << TYPE2_SHIFT;
423         }
424
425         err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
426                                 type, rconfig_addr + TYPE_OFFSET);
427         if (err < 0) {
428                 pr_err("TWL4030 failed to program resource type\n");
429                 return err;
430         }
431
432         /* Set remap states */
433         err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
434                               rconfig_addr + REMAP_OFFSET);
435         if (err < 0) {
436                 pr_err("TWL4030 Resource %d remap could not be read\n",
437                         rconfig->resource);
438                 return err;
439         }
440
441         if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
442                 remap &= ~OFF_STATE_MASK;
443                 remap |= rconfig->remap_off << OFF_STATE_SHIFT;
444         }
445
446         if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
447                 remap &= ~SLEEP_STATE_MASK;
448                 remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
449         }
450
451         err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
452                                remap,
453                                rconfig_addr + REMAP_OFFSET);
454         if (err < 0) {
455                 pr_err("TWL4030 failed to program remap\n");
456                 return err;
457         }
458
459         return 0;
460 }
461
462 static int load_twl4030_script(struct twl4030_script *tscript,
463                u8 address)
464 {
465         int err;
466         static int order;
467
468         /* Make sure the script isn't going beyond last valid address (0x3f) */
469         if ((address + tscript->size) > END_OF_SCRIPT) {
470                 pr_err("TWL4030 scripts too big error\n");
471                 return -EINVAL;
472         }
473
474         err = twl4030_write_script(address, tscript->script, tscript->size);
475         if (err)
476                 goto out;
477
478         if (tscript->flags & TWL4030_WRST_SCRIPT) {
479                 err = twl4030_config_warmreset_sequence(address);
480                 if (err)
481                         goto out;
482         }
483         if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
484                 /* Reset any existing sleep script to avoid hangs on reboot */
485                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
486                                        R_SEQ_ADD_A2S);
487                 if (err)
488                         goto out;
489
490                 err = twl4030_config_wakeup12_sequence(address);
491                 if (err)
492                         goto out;
493                 order = 1;
494         }
495         if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
496                 err = twl4030_config_wakeup3_sequence(address);
497                 if (err)
498                         goto out;
499         }
500         if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
501                 if (!order)
502                         pr_warning("TWL4030: Bad order of scripts (sleep "\
503                                         "script before wakeup) Leads to boot"\
504                                         "failure on some boards\n");
505                 err = twl4030_config_sleep_sequence(address);
506         }
507 out:
508         return err;
509 }
510
511 int twl4030_remove_script(u8 flags)
512 {
513         int err = 0;
514
515         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
516                                TWL4030_PM_MASTER_PROTECT_KEY);
517         if (err) {
518                 pr_err("twl4030: unable to unlock PROTECT_KEY\n");
519                 return err;
520         }
521
522         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
523                                TWL4030_PM_MASTER_PROTECT_KEY);
524         if (err) {
525                 pr_err("twl4030: unable to unlock PROTECT_KEY\n");
526                 return err;
527         }
528
529         if (flags & TWL4030_WRST_SCRIPT) {
530                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
531                                        R_SEQ_ADD_WARM);
532                 if (err)
533                         return err;
534         }
535         if (flags & TWL4030_WAKEUP12_SCRIPT) {
536                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
537                                        R_SEQ_ADD_S2A12);
538                 if (err)
539                         return err;
540         }
541         if (flags & TWL4030_WAKEUP3_SCRIPT) {
542                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
543                                        R_SEQ_ADD_S2A3);
544                 if (err)
545                         return err;
546         }
547         if (flags & TWL4030_SLEEP_SCRIPT) {
548                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
549                                        R_SEQ_ADD_A2S);
550                 if (err)
551                         return err;
552         }
553
554         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
555                                TWL4030_PM_MASTER_PROTECT_KEY);
556         if (err)
557                 pr_err("TWL4030 Unable to relock registers\n");
558
559         return err;
560 }
561
562 static int
563 twl4030_power_configure_scripts(const struct twl4030_power_data *pdata)
564 {
565         int err;
566         int i;
567         u8 address = twl4030_start_script_address;
568
569         for (i = 0; i < pdata->num; i++) {
570                 err = load_twl4030_script(pdata->scripts[i], address);
571                 if (err)
572                         return err;
573                 address += pdata->scripts[i]->size;
574         }
575
576         return 0;
577 }
578
579 static void twl4030_patch_rconfig(struct twl4030_resconfig *common,
580                                   struct twl4030_resconfig *board)
581 {
582         while (common->resource) {
583                 struct twl4030_resconfig *b = board;
584
585                 while (b->resource) {
586                         if (b->resource == common->resource) {
587                                 *common = *b;
588                                 break;
589                         }
590                         b++;
591                 }
592                 common++;
593         }
594 }
595
596 static int
597 twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
598 {
599         struct twl4030_resconfig *resconfig = pdata->resource_config;
600         struct twl4030_resconfig *boardconf = pdata->board_config;
601         int err;
602
603         if (resconfig) {
604                 if (boardconf)
605                         twl4030_patch_rconfig(resconfig, boardconf);
606
607                 while (resconfig->resource) {
608                         err = twl4030_configure_resource(resconfig);
609                         if (err)
610                                 return err;
611                         resconfig++;
612                 }
613         }
614
615         return 0;
616 }
617
618 static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues)
619 {
620         u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION,
621                        TWL4030_PM_MASTER_CFG_P2_TRANSITION,
622                        TWL4030_PM_MASTER_CFG_P3_TRANSITION, };
623         u8 val;
624         int i, err;
625
626         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
627                                TWL4030_PM_MASTER_PROTECT_KEY);
628         if (err)
629                 goto relock;
630         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
631                                TWL4030_PM_MASTER_KEY_CFG2,
632                                TWL4030_PM_MASTER_PROTECT_KEY);
633         if (err)
634                 goto relock;
635
636         for (i = 0; i < sizeof(regs); i++) {
637                 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER,
638                                       &val, regs[i]);
639                 if (err)
640                         break;
641                 val = (~bitmask & val) | (bitmask & bitvalues);
642                 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
643                                        val, regs[i]);
644                 if (err)
645                         break;
646         }
647
648         if (err)
649                 pr_err("TWL4030 Register access failed: %i\n", err);
650
651 relock:
652         return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
653                                 TWL4030_PM_MASTER_PROTECT_KEY);
654 }
655
656 /*
657  * In master mode, start the power off sequence.
658  * After a successful execution, TWL shuts down the power to the SoC
659  * and all peripherals connected to it.
660  */
661 void twl4030_power_off(void)
662 {
663         int err;
664
665         /* Disable start on charger or VBUS as it can break poweroff */
666         err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0);
667         if (err)
668                 pr_err("TWL4030 Unable to configure start-up\n");
669
670         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
671                                TWL4030_PM_MASTER_P1_SW_EVENTS);
672         if (err)
673                 pr_err("TWL4030 Unable to power off\n");
674 }
675
676 static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
677                                         struct device_node *node)
678 {
679         if (pdata && pdata->use_poweroff)
680                 return true;
681
682         if (of_property_read_bool(node, "ti,system-power-controller"))
683                 return true;
684
685         if (of_property_read_bool(node, "ti,use_poweroff"))
686                 return true;
687
688         return false;
689 }
690
691 #ifdef CONFIG_OF
692
693 /* Generic warm reset configuration for omap3 */
694
695 static struct twl4030_ins omap3_wrst_seq[] = {
696         TWL_RESOURCE_OFF(RES_NRES_PWRON),
697         TWL_RESOURCE_OFF(RES_RESET),
698         TWL_RESOURCE_RESET(RES_MAIN_REF),
699         TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
700         TWL_RESOURCE_RESET(RES_VUSB_3V1),
701         TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
702         TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
703         TWL_RESOURCE_ON(RES_RESET),
704         TWL_RESOURCE_ON(RES_NRES_PWRON),
705 };
706
707 static struct twl4030_script omap3_wrst_script = {
708         .script = omap3_wrst_seq,
709         .size   = ARRAY_SIZE(omap3_wrst_seq),
710         .flags  = TWL4030_WRST_SCRIPT,
711 };
712
713 static struct twl4030_script *omap3_reset_scripts[] = {
714         &omap3_wrst_script,
715 };
716
717 static struct twl4030_resconfig omap3_rconfig[] = {
718         TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1),
719         TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1),
720         TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1),
721         { 0, 0 },
722 };
723
724 static struct twl4030_power_data omap3_reset = {
725         .scripts                = omap3_reset_scripts,
726         .num                    = ARRAY_SIZE(omap3_reset_scripts),
727         .resource_config        = omap3_rconfig,
728 };
729
730 /* Recommended generic default idle configuration for off-idle */
731
732 /* Broadcast message to put res to sleep */
733 static struct twl4030_ins omap3_idle_sleep_on_seq[] = {
734         TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
735 };
736
737 static struct twl4030_script omap3_idle_sleep_on_script = {
738         .script = omap3_idle_sleep_on_seq,
739         .size   = ARRAY_SIZE(omap3_idle_sleep_on_seq),
740         .flags  = TWL4030_SLEEP_SCRIPT,
741 };
742
743 /* Broadcast message to put res to active */
744 static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
745         TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
746 };
747
748 static struct twl4030_script omap3_idle_wakeup_p12_script = {
749         .script = omap3_idle_wakeup_p12_seq,
750         .size   = ARRAY_SIZE(omap3_idle_wakeup_p12_seq),
751         .flags  = TWL4030_WAKEUP12_SCRIPT,
752 };
753
754 /* Broadcast message to put res to active */
755 static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = {
756         TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37),
757         TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
758 };
759
760 static struct twl4030_script omap3_idle_wakeup_p3_script = {
761         .script = omap3_idle_wakeup_p3_seq,
762         .size   = ARRAY_SIZE(omap3_idle_wakeup_p3_seq),
763         .flags  = TWL4030_WAKEUP3_SCRIPT,
764 };
765
766 static struct twl4030_script *omap3_idle_scripts[] = {
767         &omap3_idle_wakeup_p12_script,
768         &omap3_idle_wakeup_p3_script,
769         &omap3_wrst_script,
770         &omap3_idle_sleep_on_script,
771 };
772
773 /*
774  * Recommended configuration based on "Recommended Sleep
775  * Sequences for the Zoom Platform":
776  * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf
777  * Note that the type1 and type2 seem to be just the init order number
778  * for type1 and type2 groups as specified in the document mentioned
779  * above.
780  */
781 static struct twl4030_resconfig omap3_idle_rconfig[] = {
782         TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0),
783         TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0),
784         TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0),
785         TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0),
786         TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0),
787         TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0),
788         TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1),
789         TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0),
790         TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0),
791         TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0),
792         TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2),
793         TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2),
794         TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2),
795         TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2),
796         TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1),
797         TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1),
798         TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0),
799         TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0),
800         TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0),
801         /* Resource #20 USB charge pump skipped */
802         TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1),
803         TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1),
804         TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2),
805         TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1),
806         TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2),
807         TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0),
808         TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0),
809         TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0),
810         { /* Terminator */ },
811 };
812
813 static struct twl4030_power_data omap3_idle = {
814         .scripts                = omap3_idle_scripts,
815         .num                    = ARRAY_SIZE(omap3_idle_scripts),
816         .resource_config        = omap3_idle_rconfig,
817 };
818
819 /* Disable 32 KiHz oscillator during idle */
820 static struct twl4030_resconfig osc_off_rconfig[] = {
821         TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2),
822         { /* Terminator */ },
823 };
824
825 static struct twl4030_power_data osc_off_idle = {
826         .scripts                = omap3_idle_scripts,
827         .num                    = ARRAY_SIZE(omap3_idle_scripts),
828         .resource_config        = omap3_idle_rconfig,
829         .board_config           = osc_off_rconfig,
830 };
831
832 static const struct of_device_id twl4030_power_of_match[] = {
833         {
834                 .compatible = "ti,twl4030-power",
835         },
836         {
837                 .compatible = "ti,twl4030-power-reset",
838                 .data = &omap3_reset,
839         },
840         {
841                 .compatible = "ti,twl4030-power-idle",
842                 .data = &omap3_idle,
843         },
844         {
845                 .compatible = "ti,twl4030-power-idle-osc-off",
846                 .data = &osc_off_idle,
847         },
848         { },
849 };
850 MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
851 #endif  /* CONFIG_OF */
852
853 static int twl4030_power_probe(struct platform_device *pdev)
854 {
855         const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
856         struct device_node *node = pdev->dev.of_node;
857         const struct of_device_id *match;
858         int err = 0;
859         int err2 = 0;
860         u8 val;
861
862         if (!pdata && !node) {
863                 dev_err(&pdev->dev, "Platform data is missing\n");
864                 return -EINVAL;
865         }
866
867         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
868                                TWL4030_PM_MASTER_PROTECT_KEY);
869         err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
870                                TWL4030_PM_MASTER_KEY_CFG2,
871                                TWL4030_PM_MASTER_PROTECT_KEY);
872
873         if (err) {
874                 pr_err("TWL4030 Unable to unlock registers\n");
875                 return err;
876         }
877
878         match = of_match_device(of_match_ptr(twl4030_power_of_match),
879                                 &pdev->dev);
880         if (match && match->data)
881                 pdata = match->data;
882
883         if (pdata) {
884                 err = twl4030_power_configure_scripts(pdata);
885                 if (err) {
886                         pr_err("TWL4030 failed to load scripts\n");
887                         goto relock;
888                 }
889                 err = twl4030_power_configure_resources(pdata);
890                 if (err) {
891                         pr_err("TWL4030 failed to configure resource\n");
892                         goto relock;
893                 }
894         }
895
896         /* Board has to be wired properly to use this feature */
897         if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
898                 /* Default for SEQ_OFFSYNC is set, lets ensure this */
899                 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
900                                       TWL4030_PM_MASTER_CFG_P123_TRANSITION);
901                 if (err) {
902                         pr_warning("TWL4030 Unable to read registers\n");
903
904                 } else if (!(val & SEQ_OFFSYNC)) {
905                         val |= SEQ_OFFSYNC;
906                         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
907                                         TWL4030_PM_MASTER_CFG_P123_TRANSITION);
908                         if (err) {
909                                 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
910                                 goto relock;
911                         }
912                 }
913
914                 pm_power_off = twl4030_power_off;
915         }
916
917 relock:
918         err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
919                                TWL4030_PM_MASTER_PROTECT_KEY);
920         if (err2) {
921                 pr_err("TWL4030 Unable to relock registers\n");
922                 return err2;
923         }
924
925         return err;
926 }
927
928 static int twl4030_power_remove(struct platform_device *pdev)
929 {
930         return 0;
931 }
932
933 static struct platform_driver twl4030_power_driver = {
934         .driver = {
935                 .name   = "twl4030_power",
936                 .of_match_table = of_match_ptr(twl4030_power_of_match),
937         },
938         .probe          = twl4030_power_probe,
939         .remove         = twl4030_power_remove,
940 };
941
942 module_platform_driver(twl4030_power_driver);
943
944 MODULE_AUTHOR("Nokia Corporation");
945 MODULE_AUTHOR("Texas Instruments, Inc.");
946 MODULE_DESCRIPTION("Power management for TWL4030");
947 MODULE_LICENSE("GPL");
948 MODULE_ALIAS("platform:twl4030_power");