root/drivers/mfd/twl4030-power.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. twl4030_write_script_byte
  2. twl4030_write_script_ins
  3. twl4030_write_script
  4. twl4030_config_wakeup3_sequence
  5. twl4030_config_wakeup12_sequence
  6. twl4030_config_sleep_sequence
  7. twl4030_config_warmreset_sequence
  8. twl4030_configure_resource
  9. load_twl4030_script
  10. twl4030_remove_script
  11. twl4030_power_configure_scripts
  12. twl4030_patch_rconfig
  13. twl4030_power_configure_resources
  14. twl4030_starton_mask_and_set
  15. twl4030_power_off
  16. twl4030_power_use_poweroff
  17. twl4030_power_probe
  18. twl4030_power_remove

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

/* [<][>][^][v][top][bottom][index][help] */