linux/drivers/mfd/twl4030-power.c
<<
>>
Prefs
   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
  36static 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
 110static 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 */
 145enum {
 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
 188static 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);
 196out:
 197        return err;
 198}
 199
 200static 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);
 216out:
 217        return err;
 218}
 219
 220static 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
 245static 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);
 261out:
 262        if (err)
 263                pr_err("TWL4030 wakeup sequence for P3 config error\n");
 264        return err;
 265}
 266
 267static int
 268twl4030_config_wakeup12_sequence(const struct twl4030_power_data *pdata,
 269                                 u8 address)
 270{
 271        int err = 0;
 272        u8 data;
 273
 274        /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
 275        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
 276        if (err)
 277                goto out;
 278
 279        /* P1/P2 LVL_WAKEUP should be on LEVEL */
 280        err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
 281        if (err)
 282                goto out;
 283
 284        data |= PWR_LVL_WAKEUP;
 285        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
 286        if (err)
 287                goto out;
 288
 289        err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
 290        if (err)
 291                goto out;
 292
 293        data |= PWR_LVL_WAKEUP;
 294        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
 295        if (err)
 296                goto out;
 297
 298        if (pdata->ac_charger_quirk || machine_is_omap_3430sdp() ||
 299            machine_is_omap_ldp()) {
 300                /* Disabling AC charger effect on sleep-active transitions */
 301                err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
 302                                      R_CFG_P1_TRANSITION);
 303                if (err)
 304                        goto out;
 305                data &= ~STARTON_CHG;
 306                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
 307                                       R_CFG_P1_TRANSITION);
 308                if (err)
 309                        goto out;
 310        }
 311
 312out:
 313        if (err)
 314                pr_err("TWL4030 wakeup sequence for P1 and P2" \
 315                        "config error\n");
 316        return err;
 317}
 318
 319static int twl4030_config_sleep_sequence(u8 address)
 320{
 321        int err;
 322
 323        /* Set ACTIVE to SLEEP SEQ address in T2 memory*/
 324        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
 325
 326        if (err)
 327                pr_err("TWL4030 sleep sequence config error\n");
 328
 329        return err;
 330}
 331
 332static int twl4030_config_warmreset_sequence(u8 address)
 333{
 334        int err;
 335        u8 rd_data;
 336
 337        /* Set WARM RESET SEQ address for P1 */
 338        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
 339        if (err)
 340                goto out;
 341
 342        /* P1/P2/P3 enable WARMRESET */
 343        err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
 344        if (err)
 345                goto out;
 346
 347        rd_data |= PWR_ENABLE_WARMRESET;
 348        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
 349        if (err)
 350                goto out;
 351
 352        err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
 353        if (err)
 354                goto out;
 355
 356        rd_data |= PWR_ENABLE_WARMRESET;
 357        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
 358        if (err)
 359                goto out;
 360
 361        err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
 362        if (err)
 363                goto out;
 364
 365        rd_data |= PWR_ENABLE_WARMRESET;
 366        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
 367out:
 368        if (err)
 369                pr_err("TWL4030 warmreset seq config error\n");
 370        return err;
 371}
 372
 373static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
 374{
 375        int rconfig_addr;
 376        int err;
 377        u8 type;
 378        u8 grp;
 379        u8 remap;
 380
 381        if (rconfig->resource > TOTAL_RESOURCES) {
 382                pr_err("TWL4030 Resource %d does not exist\n",
 383                        rconfig->resource);
 384                return -EINVAL;
 385        }
 386
 387        rconfig_addr = res_config_addrs[rconfig->resource];
 388
 389        /* Set resource group */
 390        err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
 391                              rconfig_addr + DEV_GRP_OFFSET);
 392        if (err) {
 393                pr_err("TWL4030 Resource %d group could not be read\n",
 394                        rconfig->resource);
 395                return err;
 396        }
 397
 398        if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
 399                grp &= ~DEV_GRP_MASK;
 400                grp |= rconfig->devgroup << DEV_GRP_SHIFT;
 401                err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
 402                                       grp, rconfig_addr + DEV_GRP_OFFSET);
 403                if (err < 0) {
 404                        pr_err("TWL4030 failed to program devgroup\n");
 405                        return err;
 406                }
 407        }
 408
 409        /* Set resource types */
 410        err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
 411                                rconfig_addr + TYPE_OFFSET);
 412        if (err < 0) {
 413                pr_err("TWL4030 Resource %d type could not be read\n",
 414                        rconfig->resource);
 415                return err;
 416        }
 417
 418        if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
 419                type &= ~TYPE_MASK;
 420                type |= rconfig->type << TYPE_SHIFT;
 421        }
 422
 423        if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
 424                type &= ~TYPE2_MASK;
 425                type |= rconfig->type2 << TYPE2_SHIFT;
 426        }
 427
 428        err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
 429                                type, rconfig_addr + TYPE_OFFSET);
 430        if (err < 0) {
 431                pr_err("TWL4030 failed to program resource type\n");
 432                return err;
 433        }
 434
 435        /* Set remap states */
 436        err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
 437                              rconfig_addr + REMAP_OFFSET);
 438        if (err < 0) {
 439                pr_err("TWL4030 Resource %d remap could not be read\n",
 440                        rconfig->resource);
 441                return err;
 442        }
 443
 444        if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
 445                remap &= ~OFF_STATE_MASK;
 446                remap |= rconfig->remap_off << OFF_STATE_SHIFT;
 447        }
 448
 449        if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
 450                remap &= ~SLEEP_STATE_MASK;
 451                remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
 452        }
 453
 454        err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
 455                               remap,
 456                               rconfig_addr + REMAP_OFFSET);
 457        if (err < 0) {
 458                pr_err("TWL4030 failed to program remap\n");
 459                return err;
 460        }
 461
 462        return 0;
 463}
 464
 465static int load_twl4030_script(const struct twl4030_power_data *pdata,
 466                               struct twl4030_script *tscript,
 467                               u8 address)
 468{
 469        int err;
 470        static int order;
 471
 472        /* Make sure the script isn't going beyond last valid address (0x3f) */
 473        if ((address + tscript->size) > END_OF_SCRIPT) {
 474                pr_err("TWL4030 scripts too big error\n");
 475                return -EINVAL;
 476        }
 477
 478        err = twl4030_write_script(address, tscript->script, tscript->size);
 479        if (err)
 480                goto out;
 481
 482        if (tscript->flags & TWL4030_WRST_SCRIPT) {
 483                err = twl4030_config_warmreset_sequence(address);
 484                if (err)
 485                        goto out;
 486        }
 487        if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
 488                /* Reset any existing sleep script to avoid hangs on reboot */
 489                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 490                                       R_SEQ_ADD_A2S);
 491                if (err)
 492                        goto out;
 493
 494                err = twl4030_config_wakeup12_sequence(pdata, address);
 495                if (err)
 496                        goto out;
 497                order = 1;
 498        }
 499        if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
 500                err = twl4030_config_wakeup3_sequence(address);
 501                if (err)
 502                        goto out;
 503        }
 504        if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
 505                if (!order)
 506                        pr_warning("TWL4030: Bad order of scripts (sleep "\
 507                                        "script before wakeup) Leads to boot"\
 508                                        "failure on some boards\n");
 509                err = twl4030_config_sleep_sequence(address);
 510        }
 511out:
 512        return err;
 513}
 514
 515int twl4030_remove_script(u8 flags)
 516{
 517        int err = 0;
 518
 519        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 520                               TWL4030_PM_MASTER_PROTECT_KEY);
 521        if (err) {
 522                pr_err("twl4030: unable to unlock PROTECT_KEY\n");
 523                return err;
 524        }
 525
 526        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
 527                               TWL4030_PM_MASTER_PROTECT_KEY);
 528        if (err) {
 529                pr_err("twl4030: unable to unlock PROTECT_KEY\n");
 530                return err;
 531        }
 532
 533        if (flags & TWL4030_WRST_SCRIPT) {
 534                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 535                                       R_SEQ_ADD_WARM);
 536                if (err)
 537                        return err;
 538        }
 539        if (flags & TWL4030_WAKEUP12_SCRIPT) {
 540                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 541                                       R_SEQ_ADD_S2A12);
 542                if (err)
 543                        return err;
 544        }
 545        if (flags & TWL4030_WAKEUP3_SCRIPT) {
 546                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 547                                       R_SEQ_ADD_S2A3);
 548                if (err)
 549                        return err;
 550        }
 551        if (flags & TWL4030_SLEEP_SCRIPT) {
 552                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 553                                       R_SEQ_ADD_A2S);
 554                if (err)
 555                        return err;
 556        }
 557
 558        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 559                               TWL4030_PM_MASTER_PROTECT_KEY);
 560        if (err)
 561                pr_err("TWL4030 Unable to relock registers\n");
 562
 563        return err;
 564}
 565
 566static int
 567twl4030_power_configure_scripts(const struct twl4030_power_data *pdata)
 568{
 569        int err;
 570        int i;
 571        u8 address = twl4030_start_script_address;
 572
 573        for (i = 0; i < pdata->num; i++) {
 574                err = load_twl4030_script(pdata, pdata->scripts[i], address);
 575                if (err)
 576                        return err;
 577                address += pdata->scripts[i]->size;
 578        }
 579
 580        return 0;
 581}
 582
 583static void twl4030_patch_rconfig(struct twl4030_resconfig *common,
 584                                  struct twl4030_resconfig *board)
 585{
 586        while (common->resource) {
 587                struct twl4030_resconfig *b = board;
 588
 589                while (b->resource) {
 590                        if (b->resource == common->resource) {
 591                                *common = *b;
 592                                break;
 593                        }
 594                        b++;
 595                }
 596                common++;
 597        }
 598}
 599
 600static int
 601twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
 602{
 603        struct twl4030_resconfig *resconfig = pdata->resource_config;
 604        struct twl4030_resconfig *boardconf = pdata->board_config;
 605        int err;
 606
 607        if (resconfig) {
 608                if (boardconf)
 609                        twl4030_patch_rconfig(resconfig, boardconf);
 610
 611                while (resconfig->resource) {
 612                        err = twl4030_configure_resource(resconfig);
 613                        if (err)
 614                                return err;
 615                        resconfig++;
 616                }
 617        }
 618
 619        return 0;
 620}
 621
 622static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues)
 623{
 624        u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION,
 625                       TWL4030_PM_MASTER_CFG_P2_TRANSITION,
 626                       TWL4030_PM_MASTER_CFG_P3_TRANSITION, };
 627        u8 val;
 628        int i, err;
 629
 630        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 631                               TWL4030_PM_MASTER_PROTECT_KEY);
 632        if (err)
 633                goto relock;
 634        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
 635                               TWL4030_PM_MASTER_KEY_CFG2,
 636                               TWL4030_PM_MASTER_PROTECT_KEY);
 637        if (err)
 638                goto relock;
 639
 640        for (i = 0; i < sizeof(regs); i++) {
 641                err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER,
 642                                      &val, regs[i]);
 643                if (err)
 644                        break;
 645                val = (~bitmask & val) | (bitmask & bitvalues);
 646                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
 647                                       val, regs[i]);
 648                if (err)
 649                        break;
 650        }
 651
 652        if (err)
 653                pr_err("TWL4030 Register access failed: %i\n", err);
 654
 655relock:
 656        return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 657                                TWL4030_PM_MASTER_PROTECT_KEY);
 658}
 659
 660/*
 661 * In master mode, start the power off sequence.
 662 * After a successful execution, TWL shuts down the power to the SoC
 663 * and all peripherals connected to it.
 664 */
 665void twl4030_power_off(void)
 666{
 667        int err;
 668
 669        /* Disable start on charger or VBUS as it can break poweroff */
 670        err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0);
 671        if (err)
 672                pr_err("TWL4030 Unable to configure start-up\n");
 673
 674        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
 675                               TWL4030_PM_MASTER_P1_SW_EVENTS);
 676        if (err)
 677                pr_err("TWL4030 Unable to power off\n");
 678}
 679
 680static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
 681                                        struct device_node *node)
 682{
 683        if (pdata && pdata->use_poweroff)
 684                return true;
 685
 686        if (of_property_read_bool(node, "ti,system-power-controller"))
 687                return true;
 688
 689        if (of_property_read_bool(node, "ti,use_poweroff"))
 690                return true;
 691
 692        return false;
 693}
 694
 695#ifdef CONFIG_OF
 696
 697/* Generic warm reset configuration for omap3 */
 698
 699static struct twl4030_ins omap3_wrst_seq[] = {
 700        TWL_RESOURCE_OFF(RES_NRES_PWRON),
 701        TWL_RESOURCE_OFF(RES_RESET),
 702        TWL_RESOURCE_RESET(RES_MAIN_REF),
 703        TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
 704        TWL_RESOURCE_RESET(RES_VUSB_3V1),
 705        TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
 706        TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
 707        TWL_RESOURCE_ON(RES_RESET),
 708        TWL_RESOURCE_ON(RES_NRES_PWRON),
 709};
 710
 711static struct twl4030_script omap3_wrst_script = {
 712        .script = omap3_wrst_seq,
 713        .size   = ARRAY_SIZE(omap3_wrst_seq),
 714        .flags  = TWL4030_WRST_SCRIPT,
 715};
 716
 717static struct twl4030_script *omap3_reset_scripts[] = {
 718        &omap3_wrst_script,
 719};
 720
 721static struct twl4030_resconfig omap3_rconfig[] = {
 722        TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1),
 723        TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1),
 724        TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1),
 725        { 0, 0 },
 726};
 727
 728static struct twl4030_power_data omap3_reset = {
 729        .scripts                = omap3_reset_scripts,
 730        .num                    = ARRAY_SIZE(omap3_reset_scripts),
 731        .resource_config        = omap3_rconfig,
 732};
 733
 734/* Recommended generic default idle configuration for off-idle */
 735
 736/* Broadcast message to put res to sleep */
 737static struct twl4030_ins omap3_idle_sleep_on_seq[] = {
 738        TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
 739};
 740
 741static struct twl4030_script omap3_idle_sleep_on_script = {
 742        .script = omap3_idle_sleep_on_seq,
 743        .size   = ARRAY_SIZE(omap3_idle_sleep_on_seq),
 744        .flags  = TWL4030_SLEEP_SCRIPT,
 745};
 746
 747/* Broadcast message to put res to active */
 748static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
 749        TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
 750};
 751
 752static struct twl4030_script omap3_idle_wakeup_p12_script = {
 753        .script = omap3_idle_wakeup_p12_seq,
 754        .size   = ARRAY_SIZE(omap3_idle_wakeup_p12_seq),
 755        .flags  = TWL4030_WAKEUP12_SCRIPT,
 756};
 757
 758/* Broadcast message to put res to active */
 759static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = {
 760        TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37),
 761        TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
 762};
 763
 764static struct twl4030_script omap3_idle_wakeup_p3_script = {
 765        .script = omap3_idle_wakeup_p3_seq,
 766        .size   = ARRAY_SIZE(omap3_idle_wakeup_p3_seq),
 767        .flags  = TWL4030_WAKEUP3_SCRIPT,
 768};
 769
 770static struct twl4030_script *omap3_idle_scripts[] = {
 771        &omap3_idle_wakeup_p12_script,
 772        &omap3_idle_wakeup_p3_script,
 773        &omap3_wrst_script,
 774        &omap3_idle_sleep_on_script,
 775};
 776
 777/*
 778 * Recommended configuration based on "Recommended Sleep
 779 * Sequences for the Zoom Platform":
 780 * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf
 781 * Note that the type1 and type2 seem to be just the init order number
 782 * for type1 and type2 groups as specified in the document mentioned
 783 * above.
 784 */
 785static struct twl4030_resconfig omap3_idle_rconfig[] = {
 786        TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0),
 787        TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0),
 788        TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0),
 789        TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0),
 790        TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0),
 791        TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0),
 792        TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1),
 793        TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0),
 794        TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0),
 795        TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0),
 796        TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2),
 797        TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2),
 798        TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2),
 799        TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2),
 800        TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1),
 801        TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1),
 802        TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0),
 803        TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0),
 804        TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0),
 805        /* Resource #20 USB charge pump skipped */
 806        TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1),
 807        TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1),
 808        TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2),
 809        TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1),
 810        TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2),
 811        TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0),
 812        TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0),
 813        TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0),
 814        { /* Terminator */ },
 815};
 816
 817static struct twl4030_power_data omap3_idle = {
 818        .scripts                = omap3_idle_scripts,
 819        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 820        .resource_config        = omap3_idle_rconfig,
 821};
 822
 823/* Disable 32 KiHz oscillator during idle */
 824static struct twl4030_resconfig osc_off_rconfig[] = {
 825        TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2),
 826        { /* Terminator */ },
 827};
 828
 829static struct twl4030_power_data osc_off_idle = {
 830        .scripts                = omap3_idle_scripts,
 831        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 832        .resource_config        = omap3_idle_rconfig,
 833        .board_config           = osc_off_rconfig,
 834};
 835
 836static struct twl4030_power_data omap3_idle_ac_quirk = {
 837        .scripts                = omap3_idle_scripts,
 838        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 839        .resource_config        = omap3_idle_rconfig,
 840        .ac_charger_quirk       = true,
 841};
 842
 843static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = {
 844        .scripts                = omap3_idle_scripts,
 845        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 846        .resource_config        = omap3_idle_rconfig,
 847        .board_config           = osc_off_rconfig,
 848        .ac_charger_quirk       = true,
 849};
 850
 851static const struct of_device_id twl4030_power_of_match[] = {
 852        {
 853                .compatible = "ti,twl4030-power",
 854        },
 855        {
 856                .compatible = "ti,twl4030-power-reset",
 857                .data = &omap3_reset,
 858        },
 859        {
 860                .compatible = "ti,twl4030-power-idle",
 861                .data = &omap3_idle,
 862        },
 863        {
 864                .compatible = "ti,twl4030-power-idle-osc-off",
 865                .data = &osc_off_idle,
 866        },
 867        {
 868                .compatible = "ti,twl4030-power-omap3-sdp",
 869                .data = &omap3_idle_ac_quirk,
 870        },
 871        {
 872                .compatible = "ti,twl4030-power-omap3-ldp",
 873                .data = &omap3_idle_ac_quirk_osc_off,
 874        },
 875        {
 876                .compatible = "ti,twl4030-power-omap3-evm",
 877                .data = &omap3_idle_ac_quirk,
 878        },
 879        { },
 880};
 881MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
 882#endif  /* CONFIG_OF */
 883
 884static int twl4030_power_probe(struct platform_device *pdev)
 885{
 886        const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
 887        struct device_node *node = pdev->dev.of_node;
 888        const struct of_device_id *match;
 889        int err = 0;
 890        int err2 = 0;
 891        u8 val;
 892
 893        if (!pdata && !node) {
 894                dev_err(&pdev->dev, "Platform data is missing\n");
 895                return -EINVAL;
 896        }
 897
 898        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 899                               TWL4030_PM_MASTER_PROTECT_KEY);
 900        err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
 901                               TWL4030_PM_MASTER_KEY_CFG2,
 902                               TWL4030_PM_MASTER_PROTECT_KEY);
 903
 904        if (err) {
 905                pr_err("TWL4030 Unable to unlock registers\n");
 906                return err;
 907        }
 908
 909        match = of_match_device(of_match_ptr(twl4030_power_of_match),
 910                                &pdev->dev);
 911        if (match && match->data)
 912                pdata = match->data;
 913
 914        if (pdata) {
 915                err = twl4030_power_configure_scripts(pdata);
 916                if (err) {
 917                        pr_err("TWL4030 failed to load scripts\n");
 918                        goto relock;
 919                }
 920                err = twl4030_power_configure_resources(pdata);
 921                if (err) {
 922                        pr_err("TWL4030 failed to configure resource\n");
 923                        goto relock;
 924                }
 925        }
 926
 927        /* Board has to be wired properly to use this feature */
 928        if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
 929                /* Default for SEQ_OFFSYNC is set, lets ensure this */
 930                err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
 931                                      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
 932                if (err) {
 933                        pr_warning("TWL4030 Unable to read registers\n");
 934
 935                } else if (!(val & SEQ_OFFSYNC)) {
 936                        val |= SEQ_OFFSYNC;
 937                        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
 938                                        TWL4030_PM_MASTER_CFG_P123_TRANSITION);
 939                        if (err) {
 940                                pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
 941                                goto relock;
 942                        }
 943                }
 944
 945                pm_power_off = twl4030_power_off;
 946        }
 947
 948relock:
 949        err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 950                               TWL4030_PM_MASTER_PROTECT_KEY);
 951        if (err2) {
 952                pr_err("TWL4030 Unable to relock registers\n");
 953                return err2;
 954        }
 955
 956        return err;
 957}
 958
 959static int twl4030_power_remove(struct platform_device *pdev)
 960{
 961        return 0;
 962}
 963
 964static struct platform_driver twl4030_power_driver = {
 965        .driver = {
 966                .name   = "twl4030_power",
 967                .of_match_table = of_match_ptr(twl4030_power_of_match),
 968        },
 969        .probe          = twl4030_power_probe,
 970        .remove         = twl4030_power_remove,
 971};
 972
 973module_platform_driver(twl4030_power_driver);
 974
 975MODULE_AUTHOR("Nokia Corporation");
 976MODULE_AUTHOR("Texas Instruments, Inc.");
 977MODULE_DESCRIPTION("Power management for TWL4030");
 978MODULE_LICENSE("GPL");
 979MODULE_ALIAS("platform:twl4030_power");
 980