/* * The PMIC has four sets of registers corresponding to four power modes: * Performance, Active, Low-power, Hibernate. * * Registers: * Each regulator has a register for each power mode. To access a register * for a specific regulator and mode BASE_* and OFFSET_* need to be added. * * Operating modes: * In order for the PMIC to transition to operating modes it has to be * controlled via GPIO lines called LPM and HPM. * * The registers are fully configurable such that you can put all regulators in * a low-power state while the PMIC is in Active mode. They are supposed to be * configured at startup and then simply transition to/from a global low-power * state by setting the GPIO lpm pin high/low. * * This driver keeps the PMIC in Active mode, Low-power state is set for the * regulators by enabling/disabling operating mode (FPWM or Auto PFM). * * The PMIC's Low-power and Hibernate modes are used during standby/suspend. * To enter standby/suspend the PMIC will go to Low-power mode. From there, it * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
*/
/* * This function is useful for iterating over all regulators and accessing their * registers in a generic way or accessing a regulator device by its id.
*/ #define MCP16502_REG_BASE(i, r) ((((i) + 1) << 4) + MCP16502_REG_##r) #define MCP16502_STAT_BASE(i) ((i) + 5)
/* * mcp16502_gpio_set_mode() - set the GPIO corresponding value * * Used to prepare transitioning into hibernate or resuming from it.
*/ staticvoid mcp16502_gpio_set_mode(struct mcp16502 *mcp, int mode)
{ switch (mode) { case MCP16502_OPMODE_ACTIVE:
gpiod_set_value(mcp->lpm, 0); break; case MCP16502_OPMODE_LPM: case MCP16502_OPMODE_HIB:
gpiod_set_value(mcp->lpm, 1); break; default:
pr_err("%s: %d invalid\n", __func__, mode);
}
}
/* * mcp16502_get_reg() - get the PMIC's state configuration register for opmode * * @rdev: the regulator whose register we are searching * @opmode: the PMIC's operating mode ACTIVE, Low-power, Hibernate
*/ staticint mcp16502_get_state_reg(struct regulator_dev *rdev, int opmode)
{ switch (opmode) { case MCP16502_OPMODE_ACTIVE: return MCP16502_REG_BASE(rdev_get_id(rdev), A); case MCP16502_OPMODE_LPM: return MCP16502_REG_BASE(rdev_get_id(rdev), LPM); case MCP16502_OPMODE_HIB: return MCP16502_REG_BASE(rdev_get_id(rdev), HIB); default: return -EINVAL;
}
}
/* * mcp16502_get_mode() - return the current operating mode of a regulator * * Note: all functions that are not part of entering/exiting standby/suspend * use the Active mode registers. * * Note: this is different from the PMIC's operatig mode, it is the * MODE bit from the regulator's register.
*/ staticunsignedint mcp16502_get_mode(struct regulator_dev *rdev)
{ unsignedint val; int ret, reg;
reg = mcp16502_get_state_reg(rdev, MCP16502_OPMODE_ACTIVE); if (reg < 0) return reg;
ret = regmap_read(rdev->regmap, reg, &val); if (ret) return ret;
switch (val & MCP16502_MODE) { case MCP16502_MODE_FPWM: return REGULATOR_MODE_NORMAL; case MCP16502_MODE_AUTO_PFM: return REGULATOR_MODE_IDLE; default: return REGULATOR_MODE_INVALID;
}
}
/* * _mcp16502_set_mode() - helper for set_mode and set_suspend_mode * * @rdev: the regulator for which we are setting the mode * @mode: the regulator's mode (the one from MODE bit) * @opmode: the PMIC's operating mode: Active/Low-power/Hibernate
*/ staticint _mcp16502_set_mode(struct regulator_dev *rdev, unsignedint mode, unsignedint op_mode)
{ int val; int reg;
reg = mcp16502_get_state_reg(rdev, op_mode); if (reg < 0) return reg;
switch (mode) { case REGULATOR_MODE_NORMAL:
val = MCP16502_MODE_FPWM; break; case REGULATOR_MODE_IDLE:
val = MCP16502_MODE_AUTO_PFM; break; default: return -EINVAL;
}
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.