Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *
0003  * Handle TWL4030 Power initialization
0004  *
0005  * Copyright (C) 2008 Nokia Corporation
0006  * Copyright (C) 2006 Texas Instruments, Inc
0007  *
0008  * Written by   Kalle Jokiniemi
0009  *      Peter De Schrijver <peter.de-schrijver@nokia.com>
0010  * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com>
0011  *
0012  * This file is subject to the terms and conditions of the GNU General
0013  * Public License. See the file "COPYING" in the main directory of this
0014  * archive for more details.
0015  *
0016  * This program is distributed in the hope that it will be useful,
0017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0019  * GNU General Public License for more details.
0020  *
0021  * You should have received a copy of the GNU General Public License
0022  * along with this program; if not, write to the Free Software
0023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0024  */
0025 
0026 #include <linux/module.h>
0027 #include <linux/pm.h>
0028 #include <linux/mfd/twl.h>
0029 #include <linux/platform_device.h>
0030 #include <linux/of.h>
0031 #include <linux/of_device.h>
0032 
0033 #include <asm/mach-types.h>
0034 
0035 static u8 twl4030_start_script_address = 0x2b;
0036 
0037 /* Register bits for P1, P2 and P3_SW_EVENTS */
0038 #define PWR_STOPON_PRWON    BIT(6)
0039 #define PWR_STOPON_SYSEN    BIT(5)
0040 #define PWR_ENABLE_WARMRESET    BIT(4)
0041 #define PWR_LVL_WAKEUP      BIT(3)
0042 #define PWR_DEVACT      BIT(2)
0043 #define PWR_DEVSLP      BIT(1)
0044 #define PWR_DEVOFF      BIT(0)
0045 
0046 /* Register bits for CFG_P1_TRANSITION (also for P2 and P3) */
0047 #define STARTON_SWBUG       BIT(7)  /* Start on watchdog */
0048 #define STARTON_VBUS        BIT(5)  /* Start on VBUS */
0049 #define STARTON_VBAT        BIT(4)  /* Start on battery insert */
0050 #define STARTON_RTC     BIT(3)  /* Start on RTC */
0051 #define STARTON_USB     BIT(2)  /* Start on USB host */
0052 #define STARTON_CHG     BIT(1)  /* Start on charger */
0053 #define STARTON_PWON        BIT(0)  /* Start on PWRON button */
0054 
0055 #define SEQ_OFFSYNC     (1 << 0)
0056 
0057 #define PHY_TO_OFF_PM_MASTER(p)     (p - 0x36)
0058 #define PHY_TO_OFF_PM_RECEIVER(p)   (p - 0x5b)
0059 
0060 /* resource - hfclk */
0061 #define R_HFCLKOUT_DEV_GRP  PHY_TO_OFF_PM_RECEIVER(0xe6)
0062 
0063 /* PM events */
0064 #define R_P1_SW_EVENTS      PHY_TO_OFF_PM_MASTER(0x46)
0065 #define R_P2_SW_EVENTS      PHY_TO_OFF_PM_MASTER(0x47)
0066 #define R_P3_SW_EVENTS      PHY_TO_OFF_PM_MASTER(0x48)
0067 #define R_CFG_P1_TRANSITION PHY_TO_OFF_PM_MASTER(0x36)
0068 #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37)
0069 #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38)
0070 
0071 #define END_OF_SCRIPT       0x3f
0072 
0073 #define R_SEQ_ADD_A2S       PHY_TO_OFF_PM_MASTER(0x55)
0074 #define R_SEQ_ADD_S2A12     PHY_TO_OFF_PM_MASTER(0x56)
0075 #define R_SEQ_ADD_S2A3      PHY_TO_OFF_PM_MASTER(0x57)
0076 #define R_SEQ_ADD_WARM      PHY_TO_OFF_PM_MASTER(0x58)
0077 #define R_MEMORY_ADDRESS    PHY_TO_OFF_PM_MASTER(0x59)
0078 #define R_MEMORY_DATA       PHY_TO_OFF_PM_MASTER(0x5a)
0079 
0080 /* resource configuration registers
0081    <RESOURCE>_DEV_GRP   at address 'n+0'
0082    <RESOURCE>_TYPE      at address 'n+1'
0083    <RESOURCE>_REMAP     at address 'n+2'
0084    <RESOURCE>_DEDICATED at address 'n+3'
0085 */
0086 #define DEV_GRP_OFFSET      0
0087 #define TYPE_OFFSET     1
0088 #define REMAP_OFFSET        2
0089 #define DEDICATED_OFFSET    3
0090 
0091 /* Bit positions in the registers */
0092 
0093 /* <RESOURCE>_DEV_GRP */
0094 #define DEV_GRP_SHIFT       5
0095 #define DEV_GRP_MASK        (7 << DEV_GRP_SHIFT)
0096 
0097 /* <RESOURCE>_TYPE */
0098 #define TYPE_SHIFT      0
0099 #define TYPE_MASK       (7 << TYPE_SHIFT)
0100 #define TYPE2_SHIFT     3
0101 #define TYPE2_MASK      (3 << TYPE2_SHIFT)
0102 
0103 /* <RESOURCE>_REMAP */
0104 #define SLEEP_STATE_SHIFT   0
0105 #define SLEEP_STATE_MASK    (0xf << SLEEP_STATE_SHIFT)
0106 #define OFF_STATE_SHIFT     4
0107 #define OFF_STATE_MASK      (0xf << OFF_STATE_SHIFT)
0108 
0109 static u8 res_config_addrs[] = {
0110     [RES_VAUX1] = 0x17,
0111     [RES_VAUX2] = 0x1b,
0112     [RES_VAUX3] = 0x1f,
0113     [RES_VAUX4] = 0x23,
0114     [RES_VMMC1] = 0x27,
0115     [RES_VMMC2] = 0x2b,
0116     [RES_VPLL1] = 0x2f,
0117     [RES_VPLL2] = 0x33,
0118     [RES_VSIM]  = 0x37,
0119     [RES_VDAC]  = 0x3b,
0120     [RES_VINTANA1]  = 0x3f,
0121     [RES_VINTANA2]  = 0x43,
0122     [RES_VINTDIG]   = 0x47,
0123     [RES_VIO]   = 0x4b,
0124     [RES_VDD1]  = 0x55,
0125     [RES_VDD2]  = 0x63,
0126     [RES_VUSB_1V5]  = 0x71,
0127     [RES_VUSB_1V8]  = 0x74,
0128     [RES_VUSB_3V1]  = 0x77,
0129     [RES_VUSBCP]    = 0x7a,
0130     [RES_REGEN] = 0x7f,
0131     [RES_NRES_PWRON] = 0x82,
0132     [RES_CLKEN] = 0x85,
0133     [RES_SYSEN] = 0x88,
0134     [RES_HFCLKOUT]  = 0x8b,
0135     [RES_32KCLKOUT] = 0x8e,
0136     [RES_RESET] = 0x91,
0137     [RES_MAIN_REF]  = 0x94,
0138 };
0139 
0140 /*
0141  * Usable values for .remap_sleep and .remap_off
0142  * Based on table "5.3.3 Resource Operating modes"
0143  */
0144 enum {
0145     TWL_REMAP_OFF = 0,
0146     TWL_REMAP_SLEEP = 8,
0147     TWL_REMAP_ACTIVE = 9,
0148 };
0149 
0150 /*
0151  * Macros to configure the PM register states for various resources.
0152  * Note that we can make MSG_SINGULAR etc private to this driver once
0153  * omap3 has been made DT only.
0154  */
0155 #define TWL_DFLT_DELAY      2   /* typically 2 32 KiHz cycles */
0156 #define TWL_DEV_GRP_P123    (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3)
0157 #define TWL_RESOURCE_SET(res, state)                    \
0158     { MSG_SINGULAR(DEV_GRP_NULL, (res), (state)), TWL_DFLT_DELAY }
0159 #define TWL_RESOURCE_ON(res)    TWL_RESOURCE_SET(res, RES_STATE_ACTIVE)
0160 #define TWL_RESOURCE_OFF(res)   TWL_RESOURCE_SET(res, RES_STATE_OFF)
0161 #define TWL_RESOURCE_RESET(res) TWL_RESOURCE_SET(res, RES_STATE_WRST)
0162 /*
0163  * It seems that type1 and type2 is just the resource init order
0164  * number for the type1 and type2 group.
0165  */
0166 #define TWL_RESOURCE_SET_ACTIVE(res, state)                 \
0167     { MSG_SINGULAR(DEV_GRP_NULL, (res), RES_STATE_ACTIVE), (state) }
0168 #define TWL_RESOURCE_GROUP_RESET(group, type1, type2)           \
0169     { MSG_BROADCAST(DEV_GRP_NULL, (group), (type1), (type2),    \
0170         RES_STATE_WRST), TWL_DFLT_DELAY }
0171 #define TWL_RESOURCE_GROUP_SLEEP(group, type, type2)            \
0172     { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2),     \
0173         RES_STATE_SLEEP), TWL_DFLT_DELAY }
0174 #define TWL_RESOURCE_GROUP_ACTIVE(group, type, type2)           \
0175     { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2),     \
0176         RES_STATE_ACTIVE), TWL_DFLT_DELAY }
0177 #define TWL_REMAP_SLEEP(res, devgrp, typ, typ2)             \
0178     { .resource = (res), .devgroup = (devgrp),          \
0179       .type = (typ), .type2 = (typ2),               \
0180       .remap_off = TWL_REMAP_OFF,                   \
0181       .remap_sleep = TWL_REMAP_SLEEP, }
0182 #define TWL_REMAP_OFF(res, devgrp, typ, typ2)               \
0183     { .resource = (res), .devgroup = (devgrp),          \
0184       .type = (typ), .type2 = (typ2),               \
0185       .remap_off = TWL_REMAP_OFF, .remap_sleep = TWL_REMAP_OFF, }
0186 
0187 static int twl4030_write_script_byte(u8 address, u8 byte)
0188 {
0189     int err;
0190 
0191     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS);
0192     if (err)
0193         goto out;
0194     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA);
0195 out:
0196     return err;
0197 }
0198 
0199 static int twl4030_write_script_ins(u8 address, u16 pmb_message,
0200                        u8 delay, u8 next)
0201 {
0202     int err;
0203 
0204     address *= 4;
0205     err = twl4030_write_script_byte(address++, pmb_message >> 8);
0206     if (err)
0207         goto out;
0208     err = twl4030_write_script_byte(address++, pmb_message & 0xff);
0209     if (err)
0210         goto out;
0211     err = twl4030_write_script_byte(address++, delay);
0212     if (err)
0213         goto out;
0214     err = twl4030_write_script_byte(address++, next);
0215 out:
0216     return err;
0217 }
0218 
0219 static int twl4030_write_script(u8 address, struct twl4030_ins *script,
0220                        int len)
0221 {
0222     int err = -EINVAL;
0223 
0224     for (; len; len--, address++, script++) {
0225         if (len == 1) {
0226             err = twl4030_write_script_ins(address,
0227                         script->pmb_message,
0228                         script->delay,
0229                         END_OF_SCRIPT);
0230             if (err)
0231                 break;
0232         } else {
0233             err = twl4030_write_script_ins(address,
0234                         script->pmb_message,
0235                         script->delay,
0236                         address + 1);
0237             if (err)
0238                 break;
0239         }
0240     }
0241     return err;
0242 }
0243 
0244 static int twl4030_config_wakeup3_sequence(u8 address)
0245 {
0246     int err;
0247     u8 data;
0248 
0249     /* Set SLEEP to ACTIVE SEQ address for P3 */
0250     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3);
0251     if (err)
0252         goto out;
0253 
0254     /* P3 LVL_WAKEUP should be on LEVEL */
0255     err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS);
0256     if (err)
0257         goto out;
0258     data |= PWR_LVL_WAKEUP;
0259     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS);
0260 out:
0261     if (err)
0262         pr_err("TWL4030 wakeup sequence for P3 config error\n");
0263     return err;
0264 }
0265 
0266 static int
0267 twl4030_config_wakeup12_sequence(const struct twl4030_power_data *pdata,
0268                  u8 address)
0269 {
0270     int err = 0;
0271     u8 data;
0272 
0273     /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
0274     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
0275     if (err)
0276         goto out;
0277 
0278     /* P1/P2 LVL_WAKEUP should be on LEVEL */
0279     err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
0280     if (err)
0281         goto out;
0282 
0283     data |= PWR_LVL_WAKEUP;
0284     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
0285     if (err)
0286         goto out;
0287 
0288     err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
0289     if (err)
0290         goto out;
0291 
0292     data |= PWR_LVL_WAKEUP;
0293     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
0294     if (err)
0295         goto out;
0296 
0297     if (pdata->ac_charger_quirk || machine_is_omap_3430sdp() ||
0298         machine_is_omap_ldp()) {
0299         /* Disabling AC charger effect on sleep-active transitions */
0300         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
0301                       R_CFG_P1_TRANSITION);
0302         if (err)
0303             goto out;
0304         data &= ~STARTON_CHG;
0305         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
0306                        R_CFG_P1_TRANSITION);
0307         if (err)
0308             goto out;
0309     }
0310 
0311 out:
0312     if (err)
0313         pr_err("TWL4030 wakeup sequence for P1 and P2" \
0314             "config error\n");
0315     return err;
0316 }
0317 
0318 static int twl4030_config_sleep_sequence(u8 address)
0319 {
0320     int err;
0321 
0322     /* Set ACTIVE to SLEEP SEQ address in T2 memory*/
0323     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
0324 
0325     if (err)
0326         pr_err("TWL4030 sleep sequence config error\n");
0327 
0328     return err;
0329 }
0330 
0331 static int twl4030_config_warmreset_sequence(u8 address)
0332 {
0333     int err;
0334     u8 rd_data;
0335 
0336     /* Set WARM RESET SEQ address for P1 */
0337     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
0338     if (err)
0339         goto out;
0340 
0341     /* P1/P2/P3 enable WARMRESET */
0342     err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
0343     if (err)
0344         goto out;
0345 
0346     rd_data |= PWR_ENABLE_WARMRESET;
0347     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
0348     if (err)
0349         goto out;
0350 
0351     err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
0352     if (err)
0353         goto out;
0354 
0355     rd_data |= PWR_ENABLE_WARMRESET;
0356     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
0357     if (err)
0358         goto out;
0359 
0360     err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
0361     if (err)
0362         goto out;
0363 
0364     rd_data |= PWR_ENABLE_WARMRESET;
0365     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
0366 out:
0367     if (err)
0368         pr_err("TWL4030 warmreset seq config error\n");
0369     return err;
0370 }
0371 
0372 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
0373 {
0374     int rconfig_addr;
0375     int err;
0376     u8 type;
0377     u8 grp;
0378     u8 remap;
0379 
0380     if (rconfig->resource > TOTAL_RESOURCES) {
0381         pr_err("TWL4030 Resource %d does not exist\n",
0382             rconfig->resource);
0383         return -EINVAL;
0384     }
0385 
0386     rconfig_addr = res_config_addrs[rconfig->resource];
0387 
0388     /* Set resource group */
0389     err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
0390                   rconfig_addr + DEV_GRP_OFFSET);
0391     if (err) {
0392         pr_err("TWL4030 Resource %d group could not be read\n",
0393             rconfig->resource);
0394         return err;
0395     }
0396 
0397     if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
0398         grp &= ~DEV_GRP_MASK;
0399         grp |= rconfig->devgroup << DEV_GRP_SHIFT;
0400         err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
0401                        grp, rconfig_addr + DEV_GRP_OFFSET);
0402         if (err < 0) {
0403             pr_err("TWL4030 failed to program devgroup\n");
0404             return err;
0405         }
0406     }
0407 
0408     /* Set resource types */
0409     err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
0410                 rconfig_addr + TYPE_OFFSET);
0411     if (err < 0) {
0412         pr_err("TWL4030 Resource %d type could not be read\n",
0413             rconfig->resource);
0414         return err;
0415     }
0416 
0417     if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
0418         type &= ~TYPE_MASK;
0419         type |= rconfig->type << TYPE_SHIFT;
0420     }
0421 
0422     if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
0423         type &= ~TYPE2_MASK;
0424         type |= rconfig->type2 << TYPE2_SHIFT;
0425     }
0426 
0427     err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
0428                 type, rconfig_addr + TYPE_OFFSET);
0429     if (err < 0) {
0430         pr_err("TWL4030 failed to program resource type\n");
0431         return err;
0432     }
0433 
0434     /* Set remap states */
0435     err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
0436                   rconfig_addr + REMAP_OFFSET);
0437     if (err < 0) {
0438         pr_err("TWL4030 Resource %d remap could not be read\n",
0439             rconfig->resource);
0440         return err;
0441     }
0442 
0443     if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
0444         remap &= ~OFF_STATE_MASK;
0445         remap |= rconfig->remap_off << OFF_STATE_SHIFT;
0446     }
0447 
0448     if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
0449         remap &= ~SLEEP_STATE_MASK;
0450         remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
0451     }
0452 
0453     err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
0454                    remap,
0455                    rconfig_addr + REMAP_OFFSET);
0456     if (err < 0) {
0457         pr_err("TWL4030 failed to program remap\n");
0458         return err;
0459     }
0460 
0461     return 0;
0462 }
0463 
0464 static int load_twl4030_script(const struct twl4030_power_data *pdata,
0465                    struct twl4030_script *tscript,
0466                    u8 address)
0467 {
0468     int err;
0469     static int order;
0470 
0471     /* Make sure the script isn't going beyond last valid address (0x3f) */
0472     if ((address + tscript->size) > END_OF_SCRIPT) {
0473         pr_err("TWL4030 scripts too big error\n");
0474         return -EINVAL;
0475     }
0476 
0477     err = twl4030_write_script(address, tscript->script, tscript->size);
0478     if (err)
0479         goto out;
0480 
0481     if (tscript->flags & TWL4030_WRST_SCRIPT) {
0482         err = twl4030_config_warmreset_sequence(address);
0483         if (err)
0484             goto out;
0485     }
0486     if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
0487         /* Reset any existing sleep script to avoid hangs on reboot */
0488         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0489                        R_SEQ_ADD_A2S);
0490         if (err)
0491             goto out;
0492 
0493         err = twl4030_config_wakeup12_sequence(pdata, address);
0494         if (err)
0495             goto out;
0496         order = 1;
0497     }
0498     if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
0499         err = twl4030_config_wakeup3_sequence(address);
0500         if (err)
0501             goto out;
0502     }
0503     if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
0504         if (!order)
0505             pr_warn("TWL4030: Bad order of scripts (sleep script before wakeup) Leads to boot failure on some boards\n");
0506         err = twl4030_config_sleep_sequence(address);
0507     }
0508 out:
0509     return err;
0510 }
0511 
0512 int twl4030_remove_script(u8 flags)
0513 {
0514     int err = 0;
0515 
0516     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
0517                    TWL4030_PM_MASTER_PROTECT_KEY);
0518     if (err) {
0519         pr_err("twl4030: unable to unlock PROTECT_KEY\n");
0520         return err;
0521     }
0522 
0523     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
0524                    TWL4030_PM_MASTER_PROTECT_KEY);
0525     if (err) {
0526         pr_err("twl4030: unable to unlock PROTECT_KEY\n");
0527         return err;
0528     }
0529 
0530     if (flags & TWL4030_WRST_SCRIPT) {
0531         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0532                        R_SEQ_ADD_WARM);
0533         if (err)
0534             return err;
0535     }
0536     if (flags & TWL4030_WAKEUP12_SCRIPT) {
0537         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0538                        R_SEQ_ADD_S2A12);
0539         if (err)
0540             return err;
0541     }
0542     if (flags & TWL4030_WAKEUP3_SCRIPT) {
0543         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0544                        R_SEQ_ADD_S2A3);
0545         if (err)
0546             return err;
0547     }
0548     if (flags & TWL4030_SLEEP_SCRIPT) {
0549         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
0550                        R_SEQ_ADD_A2S);
0551         if (err)
0552             return err;
0553     }
0554 
0555     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
0556                    TWL4030_PM_MASTER_PROTECT_KEY);
0557     if (err)
0558         pr_err("TWL4030 Unable to relock registers\n");
0559 
0560     return err;
0561 }
0562 
0563 static int
0564 twl4030_power_configure_scripts(const struct twl4030_power_data *pdata)
0565 {
0566     int err;
0567     int i;
0568     u8 address = twl4030_start_script_address;
0569 
0570     for (i = 0; i < pdata->num; i++) {
0571         err = load_twl4030_script(pdata, pdata->scripts[i], address);
0572         if (err)
0573             return err;
0574         address += pdata->scripts[i]->size;
0575     }
0576 
0577     return 0;
0578 }
0579 
0580 static void twl4030_patch_rconfig(struct twl4030_resconfig *common,
0581                   struct twl4030_resconfig *board)
0582 {
0583     while (common->resource) {
0584         struct twl4030_resconfig *b = board;
0585 
0586         while (b->resource) {
0587             if (b->resource == common->resource) {
0588                 *common = *b;
0589                 break;
0590             }
0591             b++;
0592         }
0593         common++;
0594     }
0595 }
0596 
0597 static int
0598 twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
0599 {
0600     struct twl4030_resconfig *resconfig = pdata->resource_config;
0601     struct twl4030_resconfig *boardconf = pdata->board_config;
0602     int err;
0603 
0604     if (resconfig) {
0605         if (boardconf)
0606             twl4030_patch_rconfig(resconfig, boardconf);
0607 
0608         while (resconfig->resource) {
0609             err = twl4030_configure_resource(resconfig);
0610             if (err)
0611                 return err;
0612             resconfig++;
0613         }
0614     }
0615 
0616     return 0;
0617 }
0618 
0619 static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues)
0620 {
0621     u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION,
0622                TWL4030_PM_MASTER_CFG_P2_TRANSITION,
0623                TWL4030_PM_MASTER_CFG_P3_TRANSITION, };
0624     u8 val;
0625     int i, err;
0626 
0627     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
0628                    TWL4030_PM_MASTER_PROTECT_KEY);
0629     if (err)
0630         goto relock;
0631     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
0632                    TWL4030_PM_MASTER_KEY_CFG2,
0633                    TWL4030_PM_MASTER_PROTECT_KEY);
0634     if (err)
0635         goto relock;
0636 
0637     for (i = 0; i < sizeof(regs); i++) {
0638         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER,
0639                       &val, regs[i]);
0640         if (err)
0641             break;
0642         val = (~bitmask & val) | (bitmask & bitvalues);
0643         err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
0644                        val, regs[i]);
0645         if (err)
0646             break;
0647     }
0648 
0649     if (err)
0650         pr_err("TWL4030 Register access failed: %i\n", err);
0651 
0652 relock:
0653     return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
0654                 TWL4030_PM_MASTER_PROTECT_KEY);
0655 }
0656 
0657 /*
0658  * In master mode, start the power off sequence.
0659  * After a successful execution, TWL shuts down the power to the SoC
0660  * and all peripherals connected to it.
0661  */
0662 void twl4030_power_off(void)
0663 {
0664     int err;
0665 
0666     /* Disable start on charger or VBUS as it can break poweroff */
0667     err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0);
0668     if (err)
0669         pr_err("TWL4030 Unable to configure start-up\n");
0670 
0671     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
0672                    TWL4030_PM_MASTER_P1_SW_EVENTS);
0673     if (err)
0674         pr_err("TWL4030 Unable to power off\n");
0675 }
0676 
0677 static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
0678                     struct device_node *node)
0679 {
0680     if (pdata && pdata->use_poweroff)
0681         return true;
0682 
0683     if (of_property_read_bool(node, "ti,system-power-controller"))
0684         return true;
0685 
0686     if (of_property_read_bool(node, "ti,use_poweroff"))
0687         return true;
0688 
0689     return false;
0690 }
0691 
0692 #ifdef CONFIG_OF
0693 
0694 /* Generic warm reset configuration for omap3 */
0695 
0696 static struct twl4030_ins omap3_wrst_seq[] = {
0697     TWL_RESOURCE_OFF(RES_NRES_PWRON),
0698     TWL_RESOURCE_OFF(RES_RESET),
0699     TWL_RESOURCE_RESET(RES_MAIN_REF),
0700     TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
0701     TWL_RESOURCE_RESET(RES_VUSB_3V1),
0702     TWL_RESOURCE_RESET(RES_VMMC1),
0703     TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
0704     TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
0705     TWL_RESOURCE_ON(RES_RESET),
0706     TWL_RESOURCE_ON(RES_NRES_PWRON),
0707 };
0708 
0709 static struct twl4030_script omap3_wrst_script = {
0710     .script = omap3_wrst_seq,
0711     .size   = ARRAY_SIZE(omap3_wrst_seq),
0712     .flags  = TWL4030_WRST_SCRIPT,
0713 };
0714 
0715 static struct twl4030_script *omap3_reset_scripts[] = {
0716     &omap3_wrst_script,
0717 };
0718 
0719 static struct twl4030_resconfig omap3_rconfig[] = {
0720     TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1),
0721     TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1),
0722     TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1),
0723     { 0, 0 },
0724 };
0725 
0726 static struct twl4030_power_data omap3_reset = {
0727     .scripts        = omap3_reset_scripts,
0728     .num            = ARRAY_SIZE(omap3_reset_scripts),
0729     .resource_config    = omap3_rconfig,
0730 };
0731 
0732 /* Recommended generic default idle configuration for off-idle */
0733 
0734 /* Broadcast message to put res to sleep */
0735 static struct twl4030_ins omap3_idle_sleep_on_seq[] = {
0736     TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
0737 };
0738 
0739 static struct twl4030_script omap3_idle_sleep_on_script = {
0740     .script = omap3_idle_sleep_on_seq,
0741     .size   = ARRAY_SIZE(omap3_idle_sleep_on_seq),
0742     .flags  = TWL4030_SLEEP_SCRIPT,
0743 };
0744 
0745 /* Broadcast message to put res to active */
0746 static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
0747     TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
0748 };
0749 
0750 static struct twl4030_script omap3_idle_wakeup_p12_script = {
0751     .script = omap3_idle_wakeup_p12_seq,
0752     .size   = ARRAY_SIZE(omap3_idle_wakeup_p12_seq),
0753     .flags  = TWL4030_WAKEUP12_SCRIPT,
0754 };
0755 
0756 /* Broadcast message to put res to active */
0757 static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = {
0758     TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37),
0759     TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
0760 };
0761 
0762 static struct twl4030_script omap3_idle_wakeup_p3_script = {
0763     .script = omap3_idle_wakeup_p3_seq,
0764     .size   = ARRAY_SIZE(omap3_idle_wakeup_p3_seq),
0765     .flags  = TWL4030_WAKEUP3_SCRIPT,
0766 };
0767 
0768 static struct twl4030_script *omap3_idle_scripts[] = {
0769     &omap3_idle_wakeup_p12_script,
0770     &omap3_idle_wakeup_p3_script,
0771     &omap3_wrst_script,
0772     &omap3_idle_sleep_on_script,
0773 };
0774 
0775 /*
0776  * Recommended configuration based on "Recommended Sleep
0777  * Sequences for the Zoom Platform":
0778  * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf
0779  * Note that the type1 and type2 seem to be just the init order number
0780  * for type1 and type2 groups as specified in the document mentioned
0781  * above.
0782  */
0783 static struct twl4030_resconfig omap3_idle_rconfig[] = {
0784     TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0),
0785     TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0),
0786     TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0),
0787     TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0),
0788     TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0),
0789     TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0),
0790     TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1),
0791     TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0),
0792     TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0),
0793     TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0),
0794     TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2),
0795     TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2),
0796     TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2),
0797     TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2),
0798     TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1),
0799     TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1),
0800     TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0),
0801     TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0),
0802     TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0),
0803     /* Resource #20 USB charge pump skipped */
0804     TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1),
0805     TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1),
0806     TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2),
0807     TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1),
0808     TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2),
0809     TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0),
0810     TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0),
0811     TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0),
0812     { /* Terminator */ },
0813 };
0814 
0815 static struct twl4030_power_data omap3_idle = {
0816     .scripts        = omap3_idle_scripts,
0817     .num            = ARRAY_SIZE(omap3_idle_scripts),
0818     .resource_config    = omap3_idle_rconfig,
0819 };
0820 
0821 /* Disable 32 KiHz oscillator during idle */
0822 static struct twl4030_resconfig osc_off_rconfig[] = {
0823     TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2),
0824     { /* Terminator */ },
0825 };
0826 
0827 static struct twl4030_power_data osc_off_idle = {
0828     .scripts        = omap3_idle_scripts,
0829     .num            = ARRAY_SIZE(omap3_idle_scripts),
0830     .resource_config    = omap3_idle_rconfig,
0831     .board_config       = osc_off_rconfig,
0832 };
0833 
0834 static struct twl4030_power_data omap3_idle_ac_quirk = {
0835     .scripts        = omap3_idle_scripts,
0836     .num            = ARRAY_SIZE(omap3_idle_scripts),
0837     .resource_config    = omap3_idle_rconfig,
0838     .ac_charger_quirk   = true,
0839 };
0840 
0841 static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = {
0842     .scripts        = omap3_idle_scripts,
0843     .num            = ARRAY_SIZE(omap3_idle_scripts),
0844     .resource_config    = omap3_idle_rconfig,
0845     .board_config       = osc_off_rconfig,
0846     .ac_charger_quirk   = true,
0847 };
0848 
0849 static const struct of_device_id twl4030_power_of_match[] = {
0850     {
0851         .compatible = "ti,twl4030-power",
0852     },
0853     {
0854         .compatible = "ti,twl4030-power-reset",
0855         .data = &omap3_reset,
0856     },
0857     {
0858         .compatible = "ti,twl4030-power-idle",
0859         .data = &omap3_idle,
0860     },
0861     {
0862         .compatible = "ti,twl4030-power-idle-osc-off",
0863         .data = &osc_off_idle,
0864     },
0865     {
0866         .compatible = "ti,twl4030-power-omap3-sdp",
0867         .data = &omap3_idle_ac_quirk,
0868     },
0869     {
0870         .compatible = "ti,twl4030-power-omap3-ldp",
0871         .data = &omap3_idle_ac_quirk_osc_off,
0872     },
0873     {
0874         .compatible = "ti,twl4030-power-omap3-evm",
0875         .data = &omap3_idle_ac_quirk,
0876     },
0877     { },
0878 };
0879 MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
0880 #endif  /* CONFIG_OF */
0881 
0882 static int twl4030_power_probe(struct platform_device *pdev)
0883 {
0884     const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
0885     struct device_node *node = pdev->dev.of_node;
0886     const struct of_device_id *match;
0887     int err = 0;
0888     int err2 = 0;
0889     u8 val;
0890 
0891     if (!pdata && !node) {
0892         dev_err(&pdev->dev, "Platform data is missing\n");
0893         return -EINVAL;
0894     }
0895 
0896     err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
0897                    TWL4030_PM_MASTER_PROTECT_KEY);
0898     err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
0899                    TWL4030_PM_MASTER_KEY_CFG2,
0900                    TWL4030_PM_MASTER_PROTECT_KEY);
0901 
0902     if (err) {
0903         pr_err("TWL4030 Unable to unlock registers\n");
0904         return err;
0905     }
0906 
0907     match = of_match_device(of_match_ptr(twl4030_power_of_match),
0908                 &pdev->dev);
0909     if (match && match->data)
0910         pdata = match->data;
0911 
0912     if (pdata) {
0913         err = twl4030_power_configure_scripts(pdata);
0914         if (err) {
0915             pr_err("TWL4030 failed to load scripts\n");
0916             goto relock;
0917         }
0918         err = twl4030_power_configure_resources(pdata);
0919         if (err) {
0920             pr_err("TWL4030 failed to configure resource\n");
0921             goto relock;
0922         }
0923     }
0924 
0925     /* Board has to be wired properly to use this feature */
0926     if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
0927         /* Default for SEQ_OFFSYNC is set, lets ensure this */
0928         err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
0929                       TWL4030_PM_MASTER_CFG_P123_TRANSITION);
0930         if (err) {
0931             pr_warn("TWL4030 Unable to read registers\n");
0932         } else if (!(val & SEQ_OFFSYNC)) {
0933             val |= SEQ_OFFSYNC;
0934             err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
0935                     TWL4030_PM_MASTER_CFG_P123_TRANSITION);
0936             if (err) {
0937                 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
0938                 goto relock;
0939             }
0940         }
0941 
0942         pm_power_off = twl4030_power_off;
0943     }
0944 
0945 relock:
0946     err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
0947                    TWL4030_PM_MASTER_PROTECT_KEY);
0948     if (err2) {
0949         pr_err("TWL4030 Unable to relock registers\n");
0950         return err2;
0951     }
0952 
0953     return err;
0954 }
0955 
0956 static int twl4030_power_remove(struct platform_device *pdev)
0957 {
0958     return 0;
0959 }
0960 
0961 static struct platform_driver twl4030_power_driver = {
0962     .driver = {
0963         .name   = "twl4030_power",
0964         .of_match_table = of_match_ptr(twl4030_power_of_match),
0965     },
0966     .probe      = twl4030_power_probe,
0967     .remove     = twl4030_power_remove,
0968 };
0969 
0970 module_platform_driver(twl4030_power_driver);
0971 
0972 MODULE_AUTHOR("Nokia Corporation");
0973 MODULE_AUTHOR("Texas Instruments, Inc.");
0974 MODULE_DESCRIPTION("Power management for TWL4030");
0975 MODULE_LICENSE("GPL");
0976 MODULE_ALIAS("platform:twl4030_power");