0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/module.h>
0027 #include <linux/pm.h>
0028 #include <linux/mfd/twl.h>
0029 #include <linux/platform_device.h>
0030 #include <linux/of.h>
0031 #include <linux/of_device.h>
0032
0033 #include <asm/mach-types.h>
0034
0035 static u8 twl4030_start_script_address = 0x2b;
0036
0037
0038 #define PWR_STOPON_PRWON BIT(6)
0039 #define PWR_STOPON_SYSEN BIT(5)
0040 #define PWR_ENABLE_WARMRESET BIT(4)
0041 #define PWR_LVL_WAKEUP BIT(3)
0042 #define PWR_DEVACT BIT(2)
0043 #define PWR_DEVSLP BIT(1)
0044 #define PWR_DEVOFF BIT(0)
0045
0046
0047 #define STARTON_SWBUG BIT(7)
0048 #define STARTON_VBUS BIT(5)
0049 #define STARTON_VBAT BIT(4)
0050 #define STARTON_RTC BIT(3)
0051 #define STARTON_USB BIT(2)
0052 #define STARTON_CHG BIT(1)
0053 #define STARTON_PWON BIT(0)
0054
0055 #define SEQ_OFFSYNC (1 << 0)
0056
0057 #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36)
0058 #define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b)
0059
0060
0061 #define R_HFCLKOUT_DEV_GRP PHY_TO_OFF_PM_RECEIVER(0xe6)
0062
0063
0064 #define R_P1_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x46)
0065 #define R_P2_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x47)
0066 #define R_P3_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x48)
0067 #define R_CFG_P1_TRANSITION PHY_TO_OFF_PM_MASTER(0x36)
0068 #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37)
0069 #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38)
0070
0071 #define END_OF_SCRIPT 0x3f
0072
0073 #define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55)
0074 #define R_SEQ_ADD_S2A12 PHY_TO_OFF_PM_MASTER(0x56)
0075 #define R_SEQ_ADD_S2A3 PHY_TO_OFF_PM_MASTER(0x57)
0076 #define R_SEQ_ADD_WARM PHY_TO_OFF_PM_MASTER(0x58)
0077 #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
0078 #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
0079
0080
0081
0082
0083
0084
0085
0086 #define DEV_GRP_OFFSET 0
0087 #define TYPE_OFFSET 1
0088 #define REMAP_OFFSET 2
0089 #define DEDICATED_OFFSET 3
0090
0091
0092
0093
0094 #define DEV_GRP_SHIFT 5
0095 #define DEV_GRP_MASK (7 << DEV_GRP_SHIFT)
0096
0097
0098 #define TYPE_SHIFT 0
0099 #define TYPE_MASK (7 << TYPE_SHIFT)
0100 #define TYPE2_SHIFT 3
0101 #define TYPE2_MASK (3 << TYPE2_SHIFT)
0102
0103
0104 #define SLEEP_STATE_SHIFT 0
0105 #define SLEEP_STATE_MASK (0xf << SLEEP_STATE_SHIFT)
0106 #define OFF_STATE_SHIFT 4
0107 #define OFF_STATE_MASK (0xf << OFF_STATE_SHIFT)
0108
0109 static u8 res_config_addrs[] = {
0110 [RES_VAUX1] = 0x17,
0111 [RES_VAUX2] = 0x1b,
0112 [RES_VAUX3] = 0x1f,
0113 [RES_VAUX4] = 0x23,
0114 [RES_VMMC1] = 0x27,
0115 [RES_VMMC2] = 0x2b,
0116 [RES_VPLL1] = 0x2f,
0117 [RES_VPLL2] = 0x33,
0118 [RES_VSIM] = 0x37,
0119 [RES_VDAC] = 0x3b,
0120 [RES_VINTANA1] = 0x3f,
0121 [RES_VINTANA2] = 0x43,
0122 [RES_VINTDIG] = 0x47,
0123 [RES_VIO] = 0x4b,
0124 [RES_VDD1] = 0x55,
0125 [RES_VDD2] = 0x63,
0126 [RES_VUSB_1V5] = 0x71,
0127 [RES_VUSB_1V8] = 0x74,
0128 [RES_VUSB_3V1] = 0x77,
0129 [RES_VUSBCP] = 0x7a,
0130 [RES_REGEN] = 0x7f,
0131 [RES_NRES_PWRON] = 0x82,
0132 [RES_CLKEN] = 0x85,
0133 [RES_SYSEN] = 0x88,
0134 [RES_HFCLKOUT] = 0x8b,
0135 [RES_32KCLKOUT] = 0x8e,
0136 [RES_RESET] = 0x91,
0137 [RES_MAIN_REF] = 0x94,
0138 };
0139
0140
0141
0142
0143
0144 enum {
0145 TWL_REMAP_OFF = 0,
0146 TWL_REMAP_SLEEP = 8,
0147 TWL_REMAP_ACTIVE = 9,
0148 };
0149
0150
0151
0152
0153
0154
0155 #define TWL_DFLT_DELAY 2
0156 #define TWL_DEV_GRP_P123 (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3)
0157 #define TWL_RESOURCE_SET(res, state) \
0158 { MSG_SINGULAR(DEV_GRP_NULL, (res), (state)), TWL_DFLT_DELAY }
0159 #define TWL_RESOURCE_ON(res) TWL_RESOURCE_SET(res, RES_STATE_ACTIVE)
0160 #define TWL_RESOURCE_OFF(res) TWL_RESOURCE_SET(res, RES_STATE_OFF)
0161 #define TWL_RESOURCE_RESET(res) TWL_RESOURCE_SET(res, RES_STATE_WRST)
0162
0163
0164
0165
0166 #define TWL_RESOURCE_SET_ACTIVE(res, state) \
0167 { MSG_SINGULAR(DEV_GRP_NULL, (res), RES_STATE_ACTIVE), (state) }
0168 #define TWL_RESOURCE_GROUP_RESET(group, type1, type2) \
0169 { MSG_BROADCAST(DEV_GRP_NULL, (group), (type1), (type2), \
0170 RES_STATE_WRST), TWL_DFLT_DELAY }
0171 #define TWL_RESOURCE_GROUP_SLEEP(group, type, type2) \
0172 { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \
0173 RES_STATE_SLEEP), TWL_DFLT_DELAY }
0174 #define TWL_RESOURCE_GROUP_ACTIVE(group, type, type2) \
0175 { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \
0176 RES_STATE_ACTIVE), TWL_DFLT_DELAY }
0177 #define TWL_REMAP_SLEEP(res, devgrp, typ, typ2) \
0178 { .resource = (res), .devgroup = (devgrp), \
0179 .type = (typ), .type2 = (typ2), \
0180 .remap_off = TWL_REMAP_OFF, \
0181 .remap_sleep = TWL_REMAP_SLEEP, }
0182 #define TWL_REMAP_OFF(res, devgrp, typ, typ2) \
0183 { .resource = (res), .devgroup = (devgrp), \
0184 .type = (typ), .type2 = (typ2), \
0185 .remap_off = TWL_REMAP_OFF, .remap_sleep = TWL_REMAP_OFF, }
0186
0187 static int twl4030_write_script_byte(u8 address, u8 byte)
0188 {
0189 int err;
0190
0191 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS);
0192 if (err)
0193 goto out;
0194 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA);
0195 out:
0196 return err;
0197 }
0198
0199 static int twl4030_write_script_ins(u8 address, u16 pmb_message,
0200 u8 delay, u8 next)
0201 {
0202 int err;
0203
0204 address *= 4;
0205 err = twl4030_write_script_byte(address++, pmb_message >> 8);
0206 if (err)
0207 goto out;
0208 err = twl4030_write_script_byte(address++, pmb_message & 0xff);
0209 if (err)
0210 goto out;
0211 err = twl4030_write_script_byte(address++, delay);
0212 if (err)
0213 goto out;
0214 err = twl4030_write_script_byte(address++, next);
0215 out:
0216 return err;
0217 }
0218
0219 static int twl4030_write_script(u8 address, struct twl4030_ins *script,
0220 int len)
0221 {
0222 int err = -EINVAL;
0223
0224 for (; len; len--, address++, script++) {
0225 if (len == 1) {
0226 err = twl4030_write_script_ins(address,
0227 script->pmb_message,
0228 script->delay,
0229 END_OF_SCRIPT);
0230 if (err)
0231 break;
0232 } else {
0233 err = twl4030_write_script_ins(address,
0234 script->pmb_message,
0235 script->delay,
0236 address + 1);
0237 if (err)
0238 break;
0239 }
0240 }
0241 return err;
0242 }
0243
0244 static int twl4030_config_wakeup3_sequence(u8 address)
0245 {
0246 int err;
0247 u8 data;
0248
0249
0250 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3);
0251 if (err)
0252 goto out;
0253
0254
0255 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS);
0256 if (err)
0257 goto out;
0258 data |= PWR_LVL_WAKEUP;
0259 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS);
0260 out:
0261 if (err)
0262 pr_err("TWL4030 wakeup sequence for P3 config error\n");
0263 return err;
0264 }
0265
0266 static int
0267 twl4030_config_wakeup12_sequence(const struct twl4030_power_data *pdata,
0268 u8 address)
0269 {
0270 int err = 0;
0271 u8 data;
0272
0273
0274 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
0275 if (err)
0276 goto out;
0277
0278
0279 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
0280 if (err)
0281 goto out;
0282
0283 data |= PWR_LVL_WAKEUP;
0284 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
0285 if (err)
0286 goto out;
0287
0288 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
0289 if (err)
0290 goto out;
0291
0292 data |= PWR_LVL_WAKEUP;
0293 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
0294 if (err)
0295 goto out;
0296
0297 if (pdata->ac_charger_quirk || machine_is_omap_3430sdp() ||
0298 machine_is_omap_ldp()) {
0299
0300 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
0301 R_CFG_P1_TRANSITION);
0302 if (err)
0303 goto out;
0304 data &= ~STARTON_CHG;
0305 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
0306 R_CFG_P1_TRANSITION);
0307 if (err)
0308 goto out;
0309 }
0310
0311 out:
0312 if (err)
0313 pr_err("TWL4030 wakeup sequence for P1 and P2" \
0314 "config error\n");
0315 return err;
0316 }
0317
0318 static int twl4030_config_sleep_sequence(u8 address)
0319 {
0320 int err;
0321
0322
0323 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
0324
0325 if (err)
0326 pr_err("TWL4030 sleep sequence config error\n");
0327
0328 return err;
0329 }
0330
0331 static int twl4030_config_warmreset_sequence(u8 address)
0332 {
0333 int err;
0334 u8 rd_data;
0335
0336
0337 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
0338 if (err)
0339 goto out;
0340
0341
0342 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
0343 if (err)
0344 goto out;
0345
0346 rd_data |= PWR_ENABLE_WARMRESET;
0347 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
0348 if (err)
0349 goto out;
0350
0351 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
0352 if (err)
0353 goto out;
0354
0355 rd_data |= PWR_ENABLE_WARMRESET;
0356 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
0357 if (err)
0358 goto out;
0359
0360 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
0361 if (err)
0362 goto out;
0363
0364 rd_data |= PWR_ENABLE_WARMRESET;
0365 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
0366 out:
0367 if (err)
0368 pr_err("TWL4030 warmreset seq config error\n");
0369 return err;
0370 }
0371
0372 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
0373 {
0374 int rconfig_addr;
0375 int err;
0376 u8 type;
0377 u8 grp;
0378 u8 remap;
0379
0380 if (rconfig->resource > TOTAL_RESOURCES) {
0381 pr_err("TWL4030 Resource %d does not exist\n",
0382 rconfig->resource);
0383 return -EINVAL;
0384 }
0385
0386 rconfig_addr = res_config_addrs[rconfig->resource];
0387
0388
0389 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
0390 rconfig_addr + DEV_GRP_OFFSET);
0391 if (err) {
0392 pr_err("TWL4030 Resource %d group could not be read\n",
0393 rconfig->resource);
0394 return err;
0395 }
0396
0397 if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
0398 grp &= ~DEV_GRP_MASK;
0399 grp |= rconfig->devgroup << DEV_GRP_SHIFT;
0400 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
0401 grp, rconfig_addr + DEV_GRP_OFFSET);
0402 if (err < 0) {
0403 pr_err("TWL4030 failed to program devgroup\n");
0404 return err;
0405 }
0406 }
0407
0408
0409 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
0410 rconfig_addr + TYPE_OFFSET);
0411 if (err < 0) {
0412 pr_err("TWL4030 Resource %d type could not be read\n",
0413 rconfig->resource);
0414 return err;
0415 }
0416
0417 if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
0418 type &= ~TYPE_MASK;
0419 type |= rconfig->type << TYPE_SHIFT;
0420 }
0421
0422 if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
0423 type &= ~TYPE2_MASK;
0424 type |= rconfig->type2 << TYPE2_SHIFT;
0425 }
0426
0427 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
0428 type, rconfig_addr + TYPE_OFFSET);
0429 if (err < 0) {
0430 pr_err("TWL4030 failed to program resource type\n");
0431 return err;
0432 }
0433
0434
0435 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
0436 rconfig_addr + REMAP_OFFSET);
0437 if (err < 0) {
0438 pr_err("TWL4030 Resource %d remap could not be read\n",
0439 rconfig->resource);
0440 return err;
0441 }
0442
0443 if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
0444 remap &= ~OFF_STATE_MASK;
0445 remap |= rconfig->remap_off << OFF_STATE_SHIFT;
0446 }
0447
0448 if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
0449 remap &= ~SLEEP_STATE_MASK;
0450 remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
0451 }
0452
0453 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
0454 remap,
0455 rconfig_addr + REMAP_OFFSET);
0456 if (err < 0) {
0457 pr_err("TWL4030 failed to program remap\n");
0458 return err;
0459 }
0460
0461 return 0;
0462 }
0463
0464 static int load_twl4030_script(const struct twl4030_power_data *pdata,
0465 struct twl4030_script *tscript,
0466 u8 address)
0467 {
0468 int err;
0469 static int order;
0470
0471
0472 if ((address + tscript->size) > END_OF_SCRIPT) {
0473 pr_err("TWL4030 scripts too big error\n");
0474 return -EINVAL;
0475 }
0476
0477 err = twl4030_write_script(address, tscript->script, tscript->size);
0478 if (err)
0479 goto out;
0480
0481 if (tscript->flags & TWL4030_WRST_SCRIPT) {
0482 err = twl4030_config_warmreset_sequence(address);
0483 if (err)
0484 goto out;
0485 }
0486 if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
0487
0488 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0489 R_SEQ_ADD_A2S);
0490 if (err)
0491 goto out;
0492
0493 err = twl4030_config_wakeup12_sequence(pdata, address);
0494 if (err)
0495 goto out;
0496 order = 1;
0497 }
0498 if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
0499 err = twl4030_config_wakeup3_sequence(address);
0500 if (err)
0501 goto out;
0502 }
0503 if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
0504 if (!order)
0505 pr_warn("TWL4030: Bad order of scripts (sleep script before wakeup) Leads to boot failure on some boards\n");
0506 err = twl4030_config_sleep_sequence(address);
0507 }
0508 out:
0509 return err;
0510 }
0511
0512 int twl4030_remove_script(u8 flags)
0513 {
0514 int err = 0;
0515
0516 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
0517 TWL4030_PM_MASTER_PROTECT_KEY);
0518 if (err) {
0519 pr_err("twl4030: unable to unlock PROTECT_KEY\n");
0520 return err;
0521 }
0522
0523 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
0524 TWL4030_PM_MASTER_PROTECT_KEY);
0525 if (err) {
0526 pr_err("twl4030: unable to unlock PROTECT_KEY\n");
0527 return err;
0528 }
0529
0530 if (flags & TWL4030_WRST_SCRIPT) {
0531 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0532 R_SEQ_ADD_WARM);
0533 if (err)
0534 return err;
0535 }
0536 if (flags & TWL4030_WAKEUP12_SCRIPT) {
0537 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0538 R_SEQ_ADD_S2A12);
0539 if (err)
0540 return err;
0541 }
0542 if (flags & TWL4030_WAKEUP3_SCRIPT) {
0543 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0544 R_SEQ_ADD_S2A3);
0545 if (err)
0546 return err;
0547 }
0548 if (flags & TWL4030_SLEEP_SCRIPT) {
0549 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0550 R_SEQ_ADD_A2S);
0551 if (err)
0552 return err;
0553 }
0554
0555 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
0556 TWL4030_PM_MASTER_PROTECT_KEY);
0557 if (err)
0558 pr_err("TWL4030 Unable to relock registers\n");
0559
0560 return err;
0561 }
0562
0563 static int
0564 twl4030_power_configure_scripts(const struct twl4030_power_data *pdata)
0565 {
0566 int err;
0567 int i;
0568 u8 address = twl4030_start_script_address;
0569
0570 for (i = 0; i < pdata->num; i++) {
0571 err = load_twl4030_script(pdata, pdata->scripts[i], address);
0572 if (err)
0573 return err;
0574 address += pdata->scripts[i]->size;
0575 }
0576
0577 return 0;
0578 }
0579
0580 static void twl4030_patch_rconfig(struct twl4030_resconfig *common,
0581 struct twl4030_resconfig *board)
0582 {
0583 while (common->resource) {
0584 struct twl4030_resconfig *b = board;
0585
0586 while (b->resource) {
0587 if (b->resource == common->resource) {
0588 *common = *b;
0589 break;
0590 }
0591 b++;
0592 }
0593 common++;
0594 }
0595 }
0596
0597 static int
0598 twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
0599 {
0600 struct twl4030_resconfig *resconfig = pdata->resource_config;
0601 struct twl4030_resconfig *boardconf = pdata->board_config;
0602 int err;
0603
0604 if (resconfig) {
0605 if (boardconf)
0606 twl4030_patch_rconfig(resconfig, boardconf);
0607
0608 while (resconfig->resource) {
0609 err = twl4030_configure_resource(resconfig);
0610 if (err)
0611 return err;
0612 resconfig++;
0613 }
0614 }
0615
0616 return 0;
0617 }
0618
0619 static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues)
0620 {
0621 u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION,
0622 TWL4030_PM_MASTER_CFG_P2_TRANSITION,
0623 TWL4030_PM_MASTER_CFG_P3_TRANSITION, };
0624 u8 val;
0625 int i, err;
0626
0627 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
0628 TWL4030_PM_MASTER_PROTECT_KEY);
0629 if (err)
0630 goto relock;
0631 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
0632 TWL4030_PM_MASTER_KEY_CFG2,
0633 TWL4030_PM_MASTER_PROTECT_KEY);
0634 if (err)
0635 goto relock;
0636
0637 for (i = 0; i < sizeof(regs); i++) {
0638 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER,
0639 &val, regs[i]);
0640 if (err)
0641 break;
0642 val = (~bitmask & val) | (bitmask & bitvalues);
0643 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
0644 val, regs[i]);
0645 if (err)
0646 break;
0647 }
0648
0649 if (err)
0650 pr_err("TWL4030 Register access failed: %i\n", err);
0651
0652 relock:
0653 return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
0654 TWL4030_PM_MASTER_PROTECT_KEY);
0655 }
0656
0657
0658
0659
0660
0661
0662 void twl4030_power_off(void)
0663 {
0664 int err;
0665
0666
0667 err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0);
0668 if (err)
0669 pr_err("TWL4030 Unable to configure start-up\n");
0670
0671 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
0672 TWL4030_PM_MASTER_P1_SW_EVENTS);
0673 if (err)
0674 pr_err("TWL4030 Unable to power off\n");
0675 }
0676
0677 static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
0678 struct device_node *node)
0679 {
0680 if (pdata && pdata->use_poweroff)
0681 return true;
0682
0683 if (of_property_read_bool(node, "ti,system-power-controller"))
0684 return true;
0685
0686 if (of_property_read_bool(node, "ti,use_poweroff"))
0687 return true;
0688
0689 return false;
0690 }
0691
0692 #ifdef CONFIG_OF
0693
0694
0695
0696 static struct twl4030_ins omap3_wrst_seq[] = {
0697 TWL_RESOURCE_OFF(RES_NRES_PWRON),
0698 TWL_RESOURCE_OFF(RES_RESET),
0699 TWL_RESOURCE_RESET(RES_MAIN_REF),
0700 TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
0701 TWL_RESOURCE_RESET(RES_VUSB_3V1),
0702 TWL_RESOURCE_RESET(RES_VMMC1),
0703 TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
0704 TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
0705 TWL_RESOURCE_ON(RES_RESET),
0706 TWL_RESOURCE_ON(RES_NRES_PWRON),
0707 };
0708
0709 static struct twl4030_script omap3_wrst_script = {
0710 .script = omap3_wrst_seq,
0711 .size = ARRAY_SIZE(omap3_wrst_seq),
0712 .flags = TWL4030_WRST_SCRIPT,
0713 };
0714
0715 static struct twl4030_script *omap3_reset_scripts[] = {
0716 &omap3_wrst_script,
0717 };
0718
0719 static struct twl4030_resconfig omap3_rconfig[] = {
0720 TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1),
0721 TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1),
0722 TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1),
0723 { 0, 0 },
0724 };
0725
0726 static struct twl4030_power_data omap3_reset = {
0727 .scripts = omap3_reset_scripts,
0728 .num = ARRAY_SIZE(omap3_reset_scripts),
0729 .resource_config = omap3_rconfig,
0730 };
0731
0732
0733
0734
0735 static struct twl4030_ins omap3_idle_sleep_on_seq[] = {
0736 TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
0737 };
0738
0739 static struct twl4030_script omap3_idle_sleep_on_script = {
0740 .script = omap3_idle_sleep_on_seq,
0741 .size = ARRAY_SIZE(omap3_idle_sleep_on_seq),
0742 .flags = TWL4030_SLEEP_SCRIPT,
0743 };
0744
0745
0746 static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
0747 TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
0748 };
0749
0750 static struct twl4030_script omap3_idle_wakeup_p12_script = {
0751 .script = omap3_idle_wakeup_p12_seq,
0752 .size = ARRAY_SIZE(omap3_idle_wakeup_p12_seq),
0753 .flags = TWL4030_WAKEUP12_SCRIPT,
0754 };
0755
0756
0757 static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = {
0758 TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37),
0759 TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
0760 };
0761
0762 static struct twl4030_script omap3_idle_wakeup_p3_script = {
0763 .script = omap3_idle_wakeup_p3_seq,
0764 .size = ARRAY_SIZE(omap3_idle_wakeup_p3_seq),
0765 .flags = TWL4030_WAKEUP3_SCRIPT,
0766 };
0767
0768 static struct twl4030_script *omap3_idle_scripts[] = {
0769 &omap3_idle_wakeup_p12_script,
0770 &omap3_idle_wakeup_p3_script,
0771 &omap3_wrst_script,
0772 &omap3_idle_sleep_on_script,
0773 };
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 static struct twl4030_resconfig omap3_idle_rconfig[] = {
0784 TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0),
0785 TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0),
0786 TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0),
0787 TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0),
0788 TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0),
0789 TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0),
0790 TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1),
0791 TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0),
0792 TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0),
0793 TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0),
0794 TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2),
0795 TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2),
0796 TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2),
0797 TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2),
0798 TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1),
0799 TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1),
0800 TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0),
0801 TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0),
0802 TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0),
0803
0804 TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1),
0805 TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1),
0806 TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2),
0807 TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1),
0808 TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2),
0809 TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0),
0810 TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0),
0811 TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0),
0812 { },
0813 };
0814
0815 static struct twl4030_power_data omap3_idle = {
0816 .scripts = omap3_idle_scripts,
0817 .num = ARRAY_SIZE(omap3_idle_scripts),
0818 .resource_config = omap3_idle_rconfig,
0819 };
0820
0821
0822 static struct twl4030_resconfig osc_off_rconfig[] = {
0823 TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2),
0824 { },
0825 };
0826
0827 static struct twl4030_power_data osc_off_idle = {
0828 .scripts = omap3_idle_scripts,
0829 .num = ARRAY_SIZE(omap3_idle_scripts),
0830 .resource_config = omap3_idle_rconfig,
0831 .board_config = osc_off_rconfig,
0832 };
0833
0834 static struct twl4030_power_data omap3_idle_ac_quirk = {
0835 .scripts = omap3_idle_scripts,
0836 .num = ARRAY_SIZE(omap3_idle_scripts),
0837 .resource_config = omap3_idle_rconfig,
0838 .ac_charger_quirk = true,
0839 };
0840
0841 static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = {
0842 .scripts = omap3_idle_scripts,
0843 .num = ARRAY_SIZE(omap3_idle_scripts),
0844 .resource_config = omap3_idle_rconfig,
0845 .board_config = osc_off_rconfig,
0846 .ac_charger_quirk = true,
0847 };
0848
0849 static const struct of_device_id twl4030_power_of_match[] = {
0850 {
0851 .compatible = "ti,twl4030-power",
0852 },
0853 {
0854 .compatible = "ti,twl4030-power-reset",
0855 .data = &omap3_reset,
0856 },
0857 {
0858 .compatible = "ti,twl4030-power-idle",
0859 .data = &omap3_idle,
0860 },
0861 {
0862 .compatible = "ti,twl4030-power-idle-osc-off",
0863 .data = &osc_off_idle,
0864 },
0865 {
0866 .compatible = "ti,twl4030-power-omap3-sdp",
0867 .data = &omap3_idle_ac_quirk,
0868 },
0869 {
0870 .compatible = "ti,twl4030-power-omap3-ldp",
0871 .data = &omap3_idle_ac_quirk_osc_off,
0872 },
0873 {
0874 .compatible = "ti,twl4030-power-omap3-evm",
0875 .data = &omap3_idle_ac_quirk,
0876 },
0877 { },
0878 };
0879 MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
0880 #endif
0881
0882 static int twl4030_power_probe(struct platform_device *pdev)
0883 {
0884 const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
0885 struct device_node *node = pdev->dev.of_node;
0886 const struct of_device_id *match;
0887 int err = 0;
0888 int err2 = 0;
0889 u8 val;
0890
0891 if (!pdata && !node) {
0892 dev_err(&pdev->dev, "Platform data is missing\n");
0893 return -EINVAL;
0894 }
0895
0896 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
0897 TWL4030_PM_MASTER_PROTECT_KEY);
0898 err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
0899 TWL4030_PM_MASTER_KEY_CFG2,
0900 TWL4030_PM_MASTER_PROTECT_KEY);
0901
0902 if (err) {
0903 pr_err("TWL4030 Unable to unlock registers\n");
0904 return err;
0905 }
0906
0907 match = of_match_device(of_match_ptr(twl4030_power_of_match),
0908 &pdev->dev);
0909 if (match && match->data)
0910 pdata = match->data;
0911
0912 if (pdata) {
0913 err = twl4030_power_configure_scripts(pdata);
0914 if (err) {
0915 pr_err("TWL4030 failed to load scripts\n");
0916 goto relock;
0917 }
0918 err = twl4030_power_configure_resources(pdata);
0919 if (err) {
0920 pr_err("TWL4030 failed to configure resource\n");
0921 goto relock;
0922 }
0923 }
0924
0925
0926 if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
0927
0928 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
0929 TWL4030_PM_MASTER_CFG_P123_TRANSITION);
0930 if (err) {
0931 pr_warn("TWL4030 Unable to read registers\n");
0932 } else if (!(val & SEQ_OFFSYNC)) {
0933 val |= SEQ_OFFSYNC;
0934 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
0935 TWL4030_PM_MASTER_CFG_P123_TRANSITION);
0936 if (err) {
0937 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
0938 goto relock;
0939 }
0940 }
0941
0942 pm_power_off = twl4030_power_off;
0943 }
0944
0945 relock:
0946 err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
0947 TWL4030_PM_MASTER_PROTECT_KEY);
0948 if (err2) {
0949 pr_err("TWL4030 Unable to relock registers\n");
0950 return err2;
0951 }
0952
0953 return err;
0954 }
0955
0956 static int twl4030_power_remove(struct platform_device *pdev)
0957 {
0958 return 0;
0959 }
0960
0961 static struct platform_driver twl4030_power_driver = {
0962 .driver = {
0963 .name = "twl4030_power",
0964 .of_match_table = of_match_ptr(twl4030_power_of_match),
0965 },
0966 .probe = twl4030_power_probe,
0967 .remove = twl4030_power_remove,
0968 };
0969
0970 module_platform_driver(twl4030_power_driver);
0971
0972 MODULE_AUTHOR("Nokia Corporation");
0973 MODULE_AUTHOR("Texas Instruments, Inc.");
0974 MODULE_DESCRIPTION("Power management for TWL4030");
0975 MODULE_LICENSE("GPL");
0976 MODULE_ALIAS("platform:twl4030_power");