/* Set resource group */
err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
rconfig_addr + DEV_GRP_OFFSET); if (err) {
pr_err("TWL4030 Resource %d group could not be read\n",
rconfig->resource); return err;
}
if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
grp &= ~DEV_GRP_MASK;
grp |= rconfig->devgroup << DEV_GRP_SHIFT;
err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
grp, rconfig_addr + DEV_GRP_OFFSET); if (err < 0) {
pr_err("TWL4030 failed to program devgroup\n"); return err;
}
}
/* Set resource types */
err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
rconfig_addr + TYPE_OFFSET); if (err < 0) {
pr_err("TWL4030 Resource %d type could not be read\n",
rconfig->resource); return err;
}
if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
type &= ~TYPE_MASK;
type |= rconfig->type << TYPE_SHIFT;
}
if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
type &= ~TYPE2_MASK;
type |= rconfig->type2 << TYPE2_SHIFT;
}
err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
type, rconfig_addr + TYPE_OFFSET); if (err < 0) {
pr_err("TWL4030 failed to program resource type\n"); return err;
}
/* Set remap states */
err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
rconfig_addr + REMAP_OFFSET); if (err < 0) {
pr_err("TWL4030 Resource %d remap could not be read\n",
rconfig->resource); return err;
}
/* Make sure the script isn't going beyond last valid address (0x3f) */ if ((address + tscript->size) > END_OF_SCRIPT) {
pr_err("TWL4030 scripts too big error\n"); return -EINVAL;
}
err = twl4030_write_script(address, tscript->script, tscript->size); if (err) goto out;
if (tscript->flags & TWL4030_WRST_SCRIPT) {
err = twl4030_config_warmreset_sequence(address); if (err) goto out;
} if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { /* Reset any existing sleep script to avoid hangs on reboot */
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
R_SEQ_ADD_A2S); if (err) goto out;
err = twl4030_config_wakeup12_sequence(pdata, address); if (err) goto out;
order = 1;
} if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
err = twl4030_config_wakeup3_sequence(address); if (err) goto out;
} if (tscript->flags & TWL4030_SLEEP_SCRIPT) { if (!order)
pr_warn("TWL4030: Bad order of scripts (sleep script before wakeup) Leads to boot failure on some boards\n");
err = twl4030_config_sleep_sequence(address);
}
out: return err;
}
int twl4030_remove_script(u8 flags)
{ int err = 0;
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
TWL4030_PM_MASTER_PROTECT_KEY); if (err) {
pr_err("twl4030: unable to unlock PROTECT_KEY\n"); return err;
}
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
TWL4030_PM_MASTER_PROTECT_KEY); if (err) {
pr_err("twl4030: unable to unlock PROTECT_KEY\n"); return err;
}
if (flags & TWL4030_WRST_SCRIPT) {
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
R_SEQ_ADD_WARM); if (err) return err;
} if (flags & TWL4030_WAKEUP12_SCRIPT) {
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
R_SEQ_ADD_S2A12); if (err) return err;
} if (flags & TWL4030_WAKEUP3_SCRIPT) {
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
R_SEQ_ADD_S2A3); if (err) return err;
} if (flags & TWL4030_SLEEP_SCRIPT) {
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
R_SEQ_ADD_A2S); if (err) return err;
}
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
TWL4030_PM_MASTER_PROTECT_KEY); if (err)
pr_err("TWL4030 Unable to relock registers\n");
return err;
}
staticint
twl4030_power_configure_scripts(conststruct twl4030_power_data *pdata)
{ int err; int i;
u8 address = twl4030_start_script_address;
for (i = 0; i < pdata->num; i++) {
err = load_twl4030_script(pdata, pdata->scripts[i], address); if (err) return err;
address += pdata->scripts[i]->size;
}
/* *Inmastermode,startthepoweroffsequence. *Afterasuccessfulexecution,TWLshutsdownthepowertotheSoC *andallperipheralsconnectedtoit.
*/ void twl4030_power_off(void)
{ int err;
/* Disable start on charger or VBUS as it can break poweroff */
err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0); if (err)
pr_err("TWL4030 Unable to configure start-up\n");
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
TWL4030_PM_MASTER_P1_SW_EVENTS); if (err)
pr_err("TWL4030 Unable to power off\n");
}
/* Recommended generic default idle configuration for off-idle */
/* Broadcast message to put res to sleep */ staticstruct twl4030_ins omap3_idle_sleep_on_seq[] = {
TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0),
};
/* Broadcast message to put res to active */ staticstruct twl4030_ins omap3_idle_wakeup_p12_seq[] = {
TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
};
/* Broadcast message to put res to active */ staticstruct twl4030_ins omap3_idle_wakeup_p3_seq[] = {
TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37),
TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0),
};
if (err) {
pr_err("TWL4030 Unable to unlock registers\n"); return err;
}
if (node)
pdata = device_get_match_data(&pdev->dev);
if (pdata) {
err = twl4030_power_configure_scripts(pdata); if (err) {
pr_err("TWL4030 failed to load scripts\n"); goto relock;
}
err = twl4030_power_configure_resources(pdata); if (err) {
pr_err("TWL4030 failed to configure resource\n"); goto relock;
}
}
/* Board has to be wired properly to use this feature */ if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) { /* Default for SEQ_OFFSYNC is set, lets ensure this */
err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
TWL4030_PM_MASTER_CFG_P123_TRANSITION); if (err) {
pr_warn("TWL4030 Unable to read registers\n");
} elseif (!(val & SEQ_OFFSYNC)) {
val |= SEQ_OFFSYNC;
err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
TWL4030_PM_MASTER_CFG_P123_TRANSITION); if (err) {
pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); goto relock;
}
}
pm_power_off = twl4030_power_off;
}
relock:
err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
TWL4030_PM_MASTER_PROTECT_KEY); if (err2) {
pr_err("TWL4030 Unable to relock registers\n"); return err2;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.33Bemerkung:
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.