linux/drivers/mfd/twl4030-power.c
<<
>>
Prefs
   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
  35static 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
 109static 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 */
 144enum {
 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
 187static 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);
 195out:
 196        return err;
 197}
 198
 199static 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);
 215out:
 216        return err;
 217}
 218
 219static 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
 244static 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);
 260out:
 261        if (err)
 262                pr_err("TWL4030 wakeup sequence for P3 config error\n");
 263        return err;
 264}
 265
 266static int
 267twl4030_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
 311out:
 312        if (err)
 313                pr_err("TWL4030 wakeup sequence for P1 and P2" \
 314                        "config error\n");
 315        return err;
 316}
 317
 318static 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
 331static 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);
 366out:
 367        if (err)
 368                pr_err("TWL4030 warmreset seq config error\n");
 369        return err;
 370}
 371
 372static 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
 464static 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        }
 508out:
 509        return err;
 510}
 511
 512int 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
 563static int
 564twl4030_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
 580static 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
 597static int
 598twl4030_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
 619static 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
 652relock:
 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 */
 662void 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
 677static 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
 696static 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
 709static 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
 715static struct twl4030_script *omap3_reset_scripts[] = {
 716        &omap3_wrst_script,
 717};
 718
 719static 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
 726static 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 */
 735static struct twl4030_ins omap3_idle_sleep_on_seq[] = {
 736        TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
 737};
 738
 739static 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 */
 746static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
 747        TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
 748};
 749
 750static 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 */
 757static 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
 762static 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
 768static 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 */
 783static 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
 815static 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 */
 822static struct twl4030_resconfig osc_off_rconfig[] = {
 823        TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2),
 824        { /* Terminator */ },
 825};
 826
 827static 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
 834static 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
 841static 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
 849static 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};
 879MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
 880#endif  /* CONFIG_OF */
 881
 882static 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
 945relock:
 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
 956static int twl4030_power_remove(struct platform_device *pdev)
 957{
 958        return 0;
 959}
 960
 961static 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
 970module_platform_driver(twl4030_power_driver);
 971
 972MODULE_AUTHOR("Nokia Corporation");
 973MODULE_AUTHOR("Texas Instruments, Inc.");
 974MODULE_DESCRIPTION("Power management for TWL4030");
 975MODULE_LICENSE("GPL");
 976MODULE_ALIAS("platform:twl4030_power");
 977