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 32 #include <asm/mach-types.h> 33 34 static u8 twl4030_start_script_address = 0x2b; 35 36 #define PWR_P1_SW_EVENTS 0x10 37 #define PWR_DEVOFF (1 << 0) 38 #define SEQ_OFFSYNC (1 << 0) 39 40 #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) 41 #define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b) 42 43 /* resource - hfclk */ 44 #define R_HFCLKOUT_DEV_GRP PHY_TO_OFF_PM_RECEIVER(0xe6) 45 46 /* PM events */ 47 #define R_P1_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x46) 48 #define R_P2_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x47) 49 #define R_P3_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x48) 50 #define R_CFG_P1_TRANSITION PHY_TO_OFF_PM_MASTER(0x36) 51 #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37) 52 #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38) 53 54 #define LVL_WAKEUP 0x08 55 56 #define ENABLE_WARMRESET (1<<4) 57 58 #define END_OF_SCRIPT 0x3f 59 60 #define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55) 61 #define R_SEQ_ADD_S2A12 PHY_TO_OFF_PM_MASTER(0x56) 62 #define R_SEQ_ADD_S2A3 PHY_TO_OFF_PM_MASTER(0x57) 63 #define R_SEQ_ADD_WARM PHY_TO_OFF_PM_MASTER(0x58) 64 #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59) 65 #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a) 66 67 /* resource configuration registers 68 <RESOURCE>_DEV_GRP at address 'n+0' 69 <RESOURCE>_TYPE at address 'n+1' 70 <RESOURCE>_REMAP at address 'n+2' 71 <RESOURCE>_DEDICATED at address 'n+3' 72 */ 73 #define DEV_GRP_OFFSET 0 74 #define TYPE_OFFSET 1 75 #define REMAP_OFFSET 2 76 #define DEDICATED_OFFSET 3 77 78 /* Bit positions in the registers */ 79 80 /* <RESOURCE>_DEV_GRP */ 81 #define DEV_GRP_SHIFT 5 82 #define DEV_GRP_MASK (7 << DEV_GRP_SHIFT) 83 84 /* <RESOURCE>_TYPE */ 85 #define TYPE_SHIFT 0 86 #define TYPE_MASK (7 << TYPE_SHIFT) 87 #define TYPE2_SHIFT 3 88 #define TYPE2_MASK (3 << TYPE2_SHIFT) 89 90 /* <RESOURCE>_REMAP */ 91 #define SLEEP_STATE_SHIFT 0 92 #define SLEEP_STATE_MASK (0xf << SLEEP_STATE_SHIFT) 93 #define OFF_STATE_SHIFT 4 94 #define OFF_STATE_MASK (0xf << OFF_STATE_SHIFT) 95 96 static u8 res_config_addrs[] = { 97 [RES_VAUX1] = 0x17, 98 [RES_VAUX2] = 0x1b, 99 [RES_VAUX3] = 0x1f, 100 [RES_VAUX4] = 0x23, 101 [RES_VMMC1] = 0x27, 102 [RES_VMMC2] = 0x2b, 103 [RES_VPLL1] = 0x2f, 104 [RES_VPLL2] = 0x33, 105 [RES_VSIM] = 0x37, 106 [RES_VDAC] = 0x3b, 107 [RES_VINTANA1] = 0x3f, 108 [RES_VINTANA2] = 0x43, 109 [RES_VINTDIG] = 0x47, 110 [RES_VIO] = 0x4b, 111 [RES_VDD1] = 0x55, 112 [RES_VDD2] = 0x63, 113 [RES_VUSB_1V5] = 0x71, 114 [RES_VUSB_1V8] = 0x74, 115 [RES_VUSB_3V1] = 0x77, 116 [RES_VUSBCP] = 0x7a, 117 [RES_REGEN] = 0x7f, 118 [RES_NRES_PWRON] = 0x82, 119 [RES_CLKEN] = 0x85, 120 [RES_SYSEN] = 0x88, 121 [RES_HFCLKOUT] = 0x8b, 122 [RES_32KCLKOUT] = 0x8e, 123 [RES_RESET] = 0x91, 124 [RES_MAIN_REF] = 0x94, 125 }; 126 127 static int twl4030_write_script_byte(u8 address, u8 byte) 128 { 129 int err; 130 131 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS); 132 if (err) 133 goto out; 134 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA); 135 out: 136 return err; 137 } 138 139 static int twl4030_write_script_ins(u8 address, u16 pmb_message, 140 u8 delay, u8 next) 141 { 142 int err; 143 144 address *= 4; 145 err = twl4030_write_script_byte(address++, pmb_message >> 8); 146 if (err) 147 goto out; 148 err = twl4030_write_script_byte(address++, pmb_message & 0xff); 149 if (err) 150 goto out; 151 err = twl4030_write_script_byte(address++, delay); 152 if (err) 153 goto out; 154 err = twl4030_write_script_byte(address++, next); 155 out: 156 return err; 157 } 158 159 static int twl4030_write_script(u8 address, struct twl4030_ins *script, 160 int len) 161 { 162 int err; 163 164 for (; len; len--, address++, script++) { 165 if (len == 1) { 166 err = twl4030_write_script_ins(address, 167 script->pmb_message, 168 script->delay, 169 END_OF_SCRIPT); 170 if (err) 171 break; 172 } else { 173 err = twl4030_write_script_ins(address, 174 script->pmb_message, 175 script->delay, 176 address + 1); 177 if (err) 178 break; 179 } 180 } 181 return err; 182 } 183 184 static int twl4030_config_wakeup3_sequence(u8 address) 185 { 186 int err; 187 u8 data; 188 189 /* Set SLEEP to ACTIVE SEQ address for P3 */ 190 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3); 191 if (err) 192 goto out; 193 194 /* P3 LVL_WAKEUP should be on LEVEL */ 195 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS); 196 if (err) 197 goto out; 198 data |= LVL_WAKEUP; 199 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS); 200 out: 201 if (err) 202 pr_err("TWL4030 wakeup sequence for P3 config error\n"); 203 return err; 204 } 205 206 static int twl4030_config_wakeup12_sequence(u8 address) 207 { 208 int err = 0; 209 u8 data; 210 211 /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */ 212 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12); 213 if (err) 214 goto out; 215 216 /* P1/P2 LVL_WAKEUP should be on LEVEL */ 217 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS); 218 if (err) 219 goto out; 220 221 data |= LVL_WAKEUP; 222 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS); 223 if (err) 224 goto out; 225 226 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS); 227 if (err) 228 goto out; 229 230 data |= LVL_WAKEUP; 231 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS); 232 if (err) 233 goto out; 234 235 if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) { 236 /* Disabling AC charger effect on sleep-active transitions */ 237 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, 238 R_CFG_P1_TRANSITION); 239 if (err) 240 goto out; 241 data &= ~(1<<1); 242 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, 243 R_CFG_P1_TRANSITION); 244 if (err) 245 goto out; 246 } 247 248 out: 249 if (err) 250 pr_err("TWL4030 wakeup sequence for P1 and P2" \ 251 "config error\n"); 252 return err; 253 } 254 255 static int twl4030_config_sleep_sequence(u8 address) 256 { 257 int err; 258 259 /* Set ACTIVE to SLEEP SEQ address in T2 memory*/ 260 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S); 261 262 if (err) 263 pr_err("TWL4030 sleep sequence config error\n"); 264 265 return err; 266 } 267 268 static int twl4030_config_warmreset_sequence(u8 address) 269 { 270 int err; 271 u8 rd_data; 272 273 /* Set WARM RESET SEQ address for P1 */ 274 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM); 275 if (err) 276 goto out; 277 278 /* P1/P2/P3 enable WARMRESET */ 279 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS); 280 if (err) 281 goto out; 282 283 rd_data |= ENABLE_WARMRESET; 284 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS); 285 if (err) 286 goto out; 287 288 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS); 289 if (err) 290 goto out; 291 292 rd_data |= ENABLE_WARMRESET; 293 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS); 294 if (err) 295 goto out; 296 297 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS); 298 if (err) 299 goto out; 300 301 rd_data |= ENABLE_WARMRESET; 302 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS); 303 out: 304 if (err) 305 pr_err("TWL4030 warmreset seq config error\n"); 306 return err; 307 } 308 309 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig) 310 { 311 int rconfig_addr; 312 int err; 313 u8 type; 314 u8 grp; 315 u8 remap; 316 317 if (rconfig->resource > TOTAL_RESOURCES) { 318 pr_err("TWL4030 Resource %d does not exist\n", 319 rconfig->resource); 320 return -EINVAL; 321 } 322 323 rconfig_addr = res_config_addrs[rconfig->resource]; 324 325 /* Set resource group */ 326 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp, 327 rconfig_addr + DEV_GRP_OFFSET); 328 if (err) { 329 pr_err("TWL4030 Resource %d group could not be read\n", 330 rconfig->resource); 331 return err; 332 } 333 334 if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) { 335 grp &= ~DEV_GRP_MASK; 336 grp |= rconfig->devgroup << DEV_GRP_SHIFT; 337 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 338 grp, rconfig_addr + DEV_GRP_OFFSET); 339 if (err < 0) { 340 pr_err("TWL4030 failed to program devgroup\n"); 341 return err; 342 } 343 } 344 345 /* Set resource types */ 346 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type, 347 rconfig_addr + TYPE_OFFSET); 348 if (err < 0) { 349 pr_err("TWL4030 Resource %d type could not be read\n", 350 rconfig->resource); 351 return err; 352 } 353 354 if (rconfig->type != TWL4030_RESCONFIG_UNDEF) { 355 type &= ~TYPE_MASK; 356 type |= rconfig->type << TYPE_SHIFT; 357 } 358 359 if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) { 360 type &= ~TYPE2_MASK; 361 type |= rconfig->type2 << TYPE2_SHIFT; 362 } 363 364 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 365 type, rconfig_addr + TYPE_OFFSET); 366 if (err < 0) { 367 pr_err("TWL4030 failed to program resource type\n"); 368 return err; 369 } 370 371 /* Set remap states */ 372 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap, 373 rconfig_addr + REMAP_OFFSET); 374 if (err < 0) { 375 pr_err("TWL4030 Resource %d remap could not be read\n", 376 rconfig->resource); 377 return err; 378 } 379 380 if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) { 381 remap &= ~OFF_STATE_MASK; 382 remap |= rconfig->remap_off << OFF_STATE_SHIFT; 383 } 384 385 if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { 386 remap &= ~SLEEP_STATE_MASK; 387 remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; 388 } 389 390 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 391 remap, 392 rconfig_addr + REMAP_OFFSET); 393 if (err < 0) { 394 pr_err("TWL4030 failed to program remap\n"); 395 return err; 396 } 397 398 return 0; 399 } 400 401 static int load_twl4030_script(struct twl4030_script *tscript, 402 u8 address) 403 { 404 int err; 405 static int order; 406 407 /* Make sure the script isn't going beyond last valid address (0x3f) */ 408 if ((address + tscript->size) > END_OF_SCRIPT) { 409 pr_err("TWL4030 scripts too big error\n"); 410 return -EINVAL; 411 } 412 413 err = twl4030_write_script(address, tscript->script, tscript->size); 414 if (err) 415 goto out; 416 417 if (tscript->flags & TWL4030_WRST_SCRIPT) { 418 err = twl4030_config_warmreset_sequence(address); 419 if (err) 420 goto out; 421 } 422 if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { 423 err = twl4030_config_wakeup12_sequence(address); 424 if (err) 425 goto out; 426 order = 1; 427 } 428 if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) { 429 err = twl4030_config_wakeup3_sequence(address); 430 if (err) 431 goto out; 432 } 433 if (tscript->flags & TWL4030_SLEEP_SCRIPT) { 434 if (!order) 435 pr_warning("TWL4030: Bad order of scripts (sleep "\ 436 "script before wakeup) Leads to boot"\ 437 "failure on some boards\n"); 438 err = twl4030_config_sleep_sequence(address); 439 } 440 out: 441 return err; 442 } 443 444 int twl4030_remove_script(u8 flags) 445 { 446 int err = 0; 447 448 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 449 TWL4030_PM_MASTER_PROTECT_KEY); 450 if (err) { 451 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 452 return err; 453 } 454 455 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, 456 TWL4030_PM_MASTER_PROTECT_KEY); 457 if (err) { 458 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 459 return err; 460 } 461 462 if (flags & TWL4030_WRST_SCRIPT) { 463 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 464 R_SEQ_ADD_WARM); 465 if (err) 466 return err; 467 } 468 if (flags & TWL4030_WAKEUP12_SCRIPT) { 469 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 470 R_SEQ_ADD_S2A12); 471 if (err) 472 return err; 473 } 474 if (flags & TWL4030_WAKEUP3_SCRIPT) { 475 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 476 R_SEQ_ADD_S2A3); 477 if (err) 478 return err; 479 } 480 if (flags & TWL4030_SLEEP_SCRIPT) { 481 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 482 R_SEQ_ADD_A2S); 483 if (err) 484 return err; 485 } 486 487 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 488 TWL4030_PM_MASTER_PROTECT_KEY); 489 if (err) 490 pr_err("TWL4030 Unable to relock registers\n"); 491 492 return err; 493 } 494 495 /* 496 * In master mode, start the power off sequence. 497 * After a successful execution, TWL shuts down the power to the SoC 498 * and all peripherals connected to it. 499 */ 500 void twl4030_power_off(void) 501 { 502 int err; 503 504 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF, 505 TWL4030_PM_MASTER_P1_SW_EVENTS); 506 if (err) 507 pr_err("TWL4030 Unable to power off\n"); 508 } 509 510 void twl4030_power_init(struct twl4030_power_data *twl4030_scripts) 511 { 512 int err = 0; 513 int i; 514 struct twl4030_resconfig *resconfig; 515 u8 val, address = twl4030_start_script_address; 516 517 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 518 TWL4030_PM_MASTER_PROTECT_KEY); 519 if (err) 520 goto unlock; 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 goto unlock; 526 527 for (i = 0; i < twl4030_scripts->num; i++) { 528 err = load_twl4030_script(twl4030_scripts->scripts[i], address); 529 if (err) 530 goto load; 531 address += twl4030_scripts->scripts[i]->size; 532 } 533 534 resconfig = twl4030_scripts->resource_config; 535 if (resconfig) { 536 while (resconfig->resource) { 537 err = twl4030_configure_resource(resconfig); 538 if (err) 539 goto resource; 540 resconfig++; 541 542 } 543 } 544 545 /* Board has to be wired properly to use this feature */ 546 if (twl4030_scripts->use_poweroff && !pm_power_off) { 547 /* Default for SEQ_OFFSYNC is set, lets ensure this */ 548 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, 549 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 550 if (err) { 551 pr_warning("TWL4030 Unable to read registers\n"); 552 553 } else if (!(val & SEQ_OFFSYNC)) { 554 val |= SEQ_OFFSYNC; 555 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, 556 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 557 if (err) { 558 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); 559 goto relock; 560 } 561 } 562 563 pm_power_off = twl4030_power_off; 564 } 565 566 relock: 567 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 568 TWL4030_PM_MASTER_PROTECT_KEY); 569 if (err) 570 pr_err("TWL4030 Unable to relock registers\n"); 571 return; 572 573 unlock: 574 if (err) 575 pr_err("TWL4030 Unable to unlock registers\n"); 576 return; 577 load: 578 if (err) 579 pr_err("TWL4030 failed to load scripts\n"); 580 return; 581 resource: 582 if (err) 583 pr_err("TWL4030 failed to configure resource\n"); 584 return; 585 } 586