Merge remote-tracking branches 'regulator/topic/bd718xx' and 'regulator/topic/pfuze100' into regulator-next

This commit is contained in:
Mark Brown 2018-10-21 17:00:05 +01:00
commit f35b1e53a6
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
4 changed files with 98 additions and 1 deletions

View File

@ -12,6 +12,11 @@ Optional properties:
disabled. This binding is a workaround to keep backward compatibility with
old dtb's which rely on the fact that the switched regulators are always on
and don't mark them explicit as "regulator-always-on".
- fsl,pmic-stby-poweroff: if present, configure the PMIC to shutdown all
power rails when PMIC_STBY_REQ line is asserted during the power off sequence.
Use this option if the SoC should be powered off by external power
management IC (PMIC) on PMIC_STBY_REQ signal.
As opposite to PMIC_STBY_REQ boards can implement PMIC_ON_REQ signal.
Required child node:
- regulators: This is the list of child nodes that specify the regulator

View File

@ -98,7 +98,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
bd718xx->chip_irq = i2c->irq;
bd718xx->chip_type = (unsigned int)
bd718xx->chip_type = (unsigned int)(uintptr_t)
of_device_get_match_data(&i2c->dev);
bd718xx->dev = &i2c->dev;
dev_set_drvdata(&i2c->dev, bd718xx);

View File

@ -31,11 +31,17 @@
#define PFUZE100_COINVOL 0x1a
#define PFUZE100_SW1ABVOL 0x20
#define PFUZE100_SW1ABMODE 0x23
#define PFUZE100_SW1CVOL 0x2e
#define PFUZE100_SW1CMODE 0x31
#define PFUZE100_SW2VOL 0x35
#define PFUZE100_SW2MODE 0x38
#define PFUZE100_SW3AVOL 0x3c
#define PFUZE100_SW3AMODE 0x3f
#define PFUZE100_SW3BVOL 0x43
#define PFUZE100_SW3BMODE 0x46
#define PFUZE100_SW4VOL 0x4a
#define PFUZE100_SW4MODE 0x4d
#define PFUZE100_SWBSTCON1 0x66
#define PFUZE100_VREFDDRCON 0x6a
#define PFUZE100_VSNVSVOL 0x6b
@ -46,6 +52,13 @@
#define PFUZE100_VGEN5VOL 0x70
#define PFUZE100_VGEN6VOL 0x71
#define PFUZE100_SWxMODE_MASK 0xf
#define PFUZE100_SWxMODE_APS_APS 0x8
#define PFUZE100_SWxMODE_APS_OFF 0x4
#define PFUZE100_VGENxLPWR BIT(6)
#define PFUZE100_VGENxSTBY BIT(5)
enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3, PFUZE3001 = 0x31, };
struct pfuze_regulator {
@ -559,6 +572,69 @@ static inline struct device_node *match_of_node(int index)
}
#endif
static struct pfuze_chip *syspm_pfuze_chip;
static void pfuze_power_off_prepare(void)
{
dev_info(syspm_pfuze_chip->dev, "Configure standby mode for power off");
/* Switch from default mode: APS/APS to APS/Off */
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1ABMODE,
PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1CMODE,
PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW2MODE,
PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3AMODE,
PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3BMODE,
PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW4MODE,
PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN1VOL,
PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
PFUZE100_VGENxSTBY);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN2VOL,
PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
PFUZE100_VGENxSTBY);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN3VOL,
PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
PFUZE100_VGENxSTBY);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN4VOL,
PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
PFUZE100_VGENxSTBY);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN5VOL,
PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
PFUZE100_VGENxSTBY);
regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN6VOL,
PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
PFUZE100_VGENxSTBY);
}
static int pfuze_power_off_prepare_init(struct pfuze_chip *pfuze_chip)
{
if (pfuze_chip->chip_id != PFUZE100) {
dev_warn(pfuze_chip->dev, "Requested pm_power_off_prepare handler for not supported chip\n");
return -ENODEV;
}
if (pm_power_off_prepare) {
dev_warn(pfuze_chip->dev, "pm_power_off_prepare is already registered.\n");
return -EBUSY;
}
if (syspm_pfuze_chip) {
dev_warn(pfuze_chip->dev, "syspm_pfuze_chip is already set.\n");
return -EBUSY;
}
syspm_pfuze_chip = pfuze_chip;
pm_power_off_prepare = pfuze_power_off_prepare;
return 0;
}
static int pfuze_identify(struct pfuze_chip *pfuze_chip)
{
unsigned int value;
@ -753,6 +829,20 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
}
}
if (of_property_read_bool(client->dev.of_node,
"fsl,pmic-stby-poweroff"))
return pfuze_power_off_prepare_init(pfuze_chip);
return 0;
}
static int pfuze100_regulator_remove(struct i2c_client *client)
{
if (syspm_pfuze_chip) {
syspm_pfuze_chip = NULL;
pm_power_off_prepare = NULL;
}
return 0;
}
@ -763,6 +853,7 @@ static struct i2c_driver pfuze_driver = {
.of_match_table = pfuze_dt_ids,
},
.probe = pfuze100_regulator_probe,
.remove = pfuze100_regulator_remove,
};
module_i2c_driver(pfuze_driver);

View File

@ -49,6 +49,7 @@ int reboot_force;
*/
void (*pm_power_off_prepare)(void);
EXPORT_SYMBOL_GPL(pm_power_off_prepare);
/**
* emergency_restart - reboot the system