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/i2c/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_warning("TWL4030: Bad order of scripts (sleep "\
 506                                        "script before wakeup) Leads to boot"\
 507                                        "failure on some boards\n");
 508                err = twl4030_config_sleep_sequence(address);
 509        }
 510out:
 511        return err;
 512}
 513
 514int twl4030_remove_script(u8 flags)
 515{
 516        int err = 0;
 517
 518        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 519                               TWL4030_PM_MASTER_PROTECT_KEY);
 520        if (err) {
 521                pr_err("twl4030: unable to unlock PROTECT_KEY\n");
 522                return err;
 523        }
 524
 525        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
 526                               TWL4030_PM_MASTER_PROTECT_KEY);
 527        if (err) {
 528                pr_err("twl4030: unable to unlock PROTECT_KEY\n");
 529                return err;
 530        }
 531
 532        if (flags & TWL4030_WRST_SCRIPT) {
 533                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 534                                       R_SEQ_ADD_WARM);
 535                if (err)
 536                        return err;
 537        }
 538        if (flags & TWL4030_WAKEUP12_SCRIPT) {
 539                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 540                                       R_SEQ_ADD_S2A12);
 541                if (err)
 542                        return err;
 543        }
 544        if (flags & TWL4030_WAKEUP3_SCRIPT) {
 545                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 546                                       R_SEQ_ADD_S2A3);
 547                if (err)
 548                        return err;
 549        }
 550        if (flags & TWL4030_SLEEP_SCRIPT) {
 551                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
 552                                       R_SEQ_ADD_A2S);
 553                if (err)
 554                        return err;
 555        }
 556
 557        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 558                               TWL4030_PM_MASTER_PROTECT_KEY);
 559        if (err)
 560                pr_err("TWL4030 Unable to relock registers\n");
 561
 562        return err;
 563}
 564
 565static int
 566twl4030_power_configure_scripts(const struct twl4030_power_data *pdata)
 567{
 568        int err;
 569        int i;
 570        u8 address = twl4030_start_script_address;
 571
 572        for (i = 0; i < pdata->num; i++) {
 573                err = load_twl4030_script(pdata, pdata->scripts[i], address);
 574                if (err)
 575                        return err;
 576                address += pdata->scripts[i]->size;
 577        }
 578
 579        return 0;
 580}
 581
 582static void twl4030_patch_rconfig(struct twl4030_resconfig *common,
 583                                  struct twl4030_resconfig *board)
 584{
 585        while (common->resource) {
 586                struct twl4030_resconfig *b = board;
 587
 588                while (b->resource) {
 589                        if (b->resource == common->resource) {
 590                                *common = *b;
 591                                break;
 592                        }
 593                        b++;
 594                }
 595                common++;
 596        }
 597}
 598
 599static int
 600twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
 601{
 602        struct twl4030_resconfig *resconfig = pdata->resource_config;
 603        struct twl4030_resconfig *boardconf = pdata->board_config;
 604        int err;
 605
 606        if (resconfig) {
 607                if (boardconf)
 608                        twl4030_patch_rconfig(resconfig, boardconf);
 609
 610                while (resconfig->resource) {
 611                        err = twl4030_configure_resource(resconfig);
 612                        if (err)
 613                                return err;
 614                        resconfig++;
 615                }
 616        }
 617
 618        return 0;
 619}
 620
 621static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues)
 622{
 623        u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION,
 624                       TWL4030_PM_MASTER_CFG_P2_TRANSITION,
 625                       TWL4030_PM_MASTER_CFG_P3_TRANSITION, };
 626        u8 val;
 627        int i, err;
 628
 629        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 630                               TWL4030_PM_MASTER_PROTECT_KEY);
 631        if (err)
 632                goto relock;
 633        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
 634                               TWL4030_PM_MASTER_KEY_CFG2,
 635                               TWL4030_PM_MASTER_PROTECT_KEY);
 636        if (err)
 637                goto relock;
 638
 639        for (i = 0; i < sizeof(regs); i++) {
 640                err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER,
 641                                      &val, regs[i]);
 642                if (err)
 643                        break;
 644                val = (~bitmask & val) | (bitmask & bitvalues);
 645                err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
 646                                       val, regs[i]);
 647                if (err)
 648                        break;
 649        }
 650
 651        if (err)
 652                pr_err("TWL4030 Register access failed: %i\n", err);
 653
 654relock:
 655        return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 656                                TWL4030_PM_MASTER_PROTECT_KEY);
 657}
 658
 659/*
 660 * In master mode, start the power off sequence.
 661 * After a successful execution, TWL shuts down the power to the SoC
 662 * and all peripherals connected to it.
 663 */
 664void twl4030_power_off(void)
 665{
 666        int err;
 667
 668        /* Disable start on charger or VBUS as it can break poweroff */
 669        err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0);
 670        if (err)
 671                pr_err("TWL4030 Unable to configure start-up\n");
 672
 673        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
 674                               TWL4030_PM_MASTER_P1_SW_EVENTS);
 675        if (err)
 676                pr_err("TWL4030 Unable to power off\n");
 677}
 678
 679static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
 680                                        struct device_node *node)
 681{
 682        if (pdata && pdata->use_poweroff)
 683                return true;
 684
 685        if (of_property_read_bool(node, "ti,system-power-controller"))
 686                return true;
 687
 688        if (of_property_read_bool(node, "ti,use_poweroff"))
 689                return true;
 690
 691        return false;
 692}
 693
 694#ifdef CONFIG_OF
 695
 696/* Generic warm reset configuration for omap3 */
 697
 698static struct twl4030_ins omap3_wrst_seq[] = {
 699        TWL_RESOURCE_OFF(RES_NRES_PWRON),
 700        TWL_RESOURCE_OFF(RES_RESET),
 701        TWL_RESOURCE_RESET(RES_MAIN_REF),
 702        TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
 703        TWL_RESOURCE_RESET(RES_VUSB_3V1),
 704        TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
 705        TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
 706        TWL_RESOURCE_ON(RES_RESET),
 707        TWL_RESOURCE_ON(RES_NRES_PWRON),
 708};
 709
 710static struct twl4030_script omap3_wrst_script = {
 711        .script = omap3_wrst_seq,
 712        .size   = ARRAY_SIZE(omap3_wrst_seq),
 713        .flags  = TWL4030_WRST_SCRIPT,
 714};
 715
 716static struct twl4030_script *omap3_reset_scripts[] = {
 717        &omap3_wrst_script,
 718};
 719
 720static struct twl4030_resconfig omap3_rconfig[] = {
 721        TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1),
 722        TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1),
 723        TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1),
 724        { 0, 0 },
 725};
 726
 727static struct twl4030_power_data omap3_reset = {
 728        .scripts                = omap3_reset_scripts,
 729        .num                    = ARRAY_SIZE(omap3_reset_scripts),
 730        .resource_config        = omap3_rconfig,
 731};
 732
 733/* Recommended generic default idle configuration for off-idle */
 734
 735/* Broadcast message to put res to sleep */
 736static struct twl4030_ins omap3_idle_sleep_on_seq[] = {
 737        TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
 738};
 739
 740static struct twl4030_script omap3_idle_sleep_on_script = {
 741        .script = omap3_idle_sleep_on_seq,
 742        .size   = ARRAY_SIZE(omap3_idle_sleep_on_seq),
 743        .flags  = TWL4030_SLEEP_SCRIPT,
 744};
 745
 746/* Broadcast message to put res to active */
 747static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
 748        TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
 749};
 750
 751static struct twl4030_script omap3_idle_wakeup_p12_script = {
 752        .script = omap3_idle_wakeup_p12_seq,
 753        .size   = ARRAY_SIZE(omap3_idle_wakeup_p12_seq),
 754        .flags  = TWL4030_WAKEUP12_SCRIPT,
 755};
 756
 757/* Broadcast message to put res to active */
 758static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = {
 759        TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37),
 760        TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
 761};
 762
 763static struct twl4030_script omap3_idle_wakeup_p3_script = {
 764        .script = omap3_idle_wakeup_p3_seq,
 765        .size   = ARRAY_SIZE(omap3_idle_wakeup_p3_seq),
 766        .flags  = TWL4030_WAKEUP3_SCRIPT,
 767};
 768
 769static struct twl4030_script *omap3_idle_scripts[] = {
 770        &omap3_idle_wakeup_p12_script,
 771        &omap3_idle_wakeup_p3_script,
 772        &omap3_wrst_script,
 773        &omap3_idle_sleep_on_script,
 774};
 775
 776/*
 777 * Recommended configuration based on "Recommended Sleep
 778 * Sequences for the Zoom Platform":
 779 * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf
 780 * Note that the type1 and type2 seem to be just the init order number
 781 * for type1 and type2 groups as specified in the document mentioned
 782 * above.
 783 */
 784static struct twl4030_resconfig omap3_idle_rconfig[] = {
 785        TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0),
 786        TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0),
 787        TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0),
 788        TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0),
 789        TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0),
 790        TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0),
 791        TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1),
 792        TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0),
 793        TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0),
 794        TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0),
 795        TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2),
 796        TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2),
 797        TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2),
 798        TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2),
 799        TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1),
 800        TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1),
 801        TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0),
 802        TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0),
 803        TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0),
 804        /* Resource #20 USB charge pump skipped */
 805        TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1),
 806        TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1),
 807        TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2),
 808        TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1),
 809        TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2),
 810        TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0),
 811        TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0),
 812        TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0),
 813        { /* Terminator */ },
 814};
 815
 816static struct twl4030_power_data omap3_idle = {
 817        .scripts                = omap3_idle_scripts,
 818        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 819        .resource_config        = omap3_idle_rconfig,
 820};
 821
 822/* Disable 32 KiHz oscillator during idle */
 823static struct twl4030_resconfig osc_off_rconfig[] = {
 824        TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2),
 825        { /* Terminator */ },
 826};
 827
 828static struct twl4030_power_data osc_off_idle = {
 829        .scripts                = omap3_idle_scripts,
 830        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 831        .resource_config        = omap3_idle_rconfig,
 832        .board_config           = osc_off_rconfig,
 833};
 834
 835static struct twl4030_power_data omap3_idle_ac_quirk = {
 836        .scripts                = omap3_idle_scripts,
 837        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 838        .resource_config        = omap3_idle_rconfig,
 839        .ac_charger_quirk       = true,
 840};
 841
 842static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = {
 843        .scripts                = omap3_idle_scripts,
 844        .num                    = ARRAY_SIZE(omap3_idle_scripts),
 845        .resource_config        = omap3_idle_rconfig,
 846        .board_config           = osc_off_rconfig,
 847        .ac_charger_quirk       = true,
 848};
 849
 850static const struct of_device_id twl4030_power_of_match[] = {
 851        {
 852                .compatible = "ti,twl4030-power",
 853        },
 854        {
 855                .compatible = "ti,twl4030-power-reset",
 856                .data = &omap3_reset,
 857        },
 858        {
 859                .compatible = "ti,twl4030-power-idle",
 860                .data = &omap3_idle,
 861        },
 862        {
 863                .compatible = "ti,twl4030-power-idle-osc-off",
 864                .data = &osc_off_idle,
 865        },
 866        {
 867                .compatible = "ti,twl4030-power-omap3-sdp",
 868                .data = &omap3_idle_ac_quirk,
 869        },
 870        {
 871                .compatible = "ti,twl4030-power-omap3-ldp",
 872                .data = &omap3_idle_ac_quirk_osc_off,
 873        },
 874        {
 875                .compatible = "ti,twl4030-power-omap3-evm",
 876                .data = &omap3_idle_ac_quirk,
 877        },
 878        { },
 879};
 880MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
 881#endif  /* CONFIG_OF */
 882
 883static int twl4030_power_probe(struct platform_device *pdev)
 884{
 885        const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
 886        struct device_node *node = pdev->dev.of_node;
 887        const struct of_device_id *match;
 888        int err = 0;
 889        int err2 = 0;
 890        u8 val;
 891
 892        if (!pdata && !node) {
 893                dev_err(&pdev->dev, "Platform data is missing\n");
 894                return -EINVAL;
 895        }
 896
 897        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 898                               TWL4030_PM_MASTER_PROTECT_KEY);
 899        err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
 900                               TWL4030_PM_MASTER_KEY_CFG2,
 901                               TWL4030_PM_MASTER_PROTECT_KEY);
 902
 903        if (err) {
 904                pr_err("TWL4030 Unable to unlock registers\n");
 905                return err;
 906        }
 907
 908        match = of_match_device(of_match_ptr(twl4030_power_of_match),
 909                                &pdev->dev);
 910        if (match && match->data)
 911                pdata = match->data;
 912
 913        if (pdata) {
 914                err = twl4030_power_configure_scripts(pdata);
 915                if (err) {
 916                        pr_err("TWL4030 failed to load scripts\n");
 917                        goto relock;
 918                }
 919                err = twl4030_power_configure_resources(pdata);
 920                if (err) {
 921                        pr_err("TWL4030 failed to configure resource\n");
 922                        goto relock;
 923                }
 924        }
 925
 926        /* Board has to be wired properly to use this feature */
 927        if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
 928                /* Default for SEQ_OFFSYNC is set, lets ensure this */
 929                err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
 930                                      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
 931                if (err) {
 932                        pr_warning("TWL4030 Unable to read registers\n");
 933
 934                } else if (!(val & SEQ_OFFSYNC)) {
 935                        val |= SEQ_OFFSYNC;
 936                        err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
 937                                        TWL4030_PM_MASTER_CFG_P123_TRANSITION);
 938                        if (err) {
 939                                pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
 940                                goto relock;
 941                        }
 942                }
 943
 944                pm_power_off = twl4030_power_off;
 945        }
 946
 947relock:
 948        err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 949                               TWL4030_PM_MASTER_PROTECT_KEY);
 950        if (err2) {
 951                pr_err("TWL4030 Unable to relock registers\n");
 952                return err2;
 953        }
 954
 955        return err;
 956}
 957
 958static int twl4030_power_remove(struct platform_device *pdev)
 959{
 960        return 0;
 961}
 962
 963static struct platform_driver twl4030_power_driver = {
 964        .driver = {
 965                .name   = "twl4030_power",
 966                .of_match_table = of_match_ptr(twl4030_power_of_match),
 967        },
 968        .probe          = twl4030_power_probe,
 969        .remove         = twl4030_power_remove,
 970};
 971
 972module_platform_driver(twl4030_power_driver);
 973
 974MODULE_AUTHOR("Nokia Corporation");
 975MODULE_AUTHOR("Texas Instruments, Inc.");
 976MODULE_DESCRIPTION("Power management for TWL4030");
 977MODULE_LICENSE("GPL");
 978MODULE_ALIAS("platform:twl4030_power");
 979