Commit d785334a authored by Krzysztof Kozlowski's avatar Krzysztof Kozlowski Committed by Lee Jones

mfd: s2mps11: Add manual shutdown method for Odroid XU3

On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
register must be manually set to 0 before initiating power off sequence.

One of usual power down methods for Exynos based devices looks like:
1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos SoC.
2. Exynos holds up this pin during system operation.
3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
   other device.
4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
   ACOKB goes high.

On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
This means that PMIC must manually set PWRHOLD field to low and then
wait for signal from Application Processor (the usual change in
PWRHOLD/PSHOLD pin will actually cut off the power).

The patch adds respective binding allowing Odroid XU3 device to be
powered off.
Signed-off-by: default avatarKrzysztof Kozlowski <k.kozlowski.k@gmail.com>
Reported-by: default avatarAnand Moon <linux.amoon@gmail.com>
Tested-by: default avatarAnand Moon <linux.amoon@gmail.com>
Reviewed-by: default avatarJavier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 689d4453
...@@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( ...@@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
* not parsed here. * not parsed here.
*/ */
pd->manual_poweroff = of_property_read_bool(dev->of_node,
"samsung,s2mps11-acokb-ground");
return pd; return pd;
} }
#else #else
...@@ -440,6 +442,33 @@ static int sec_pmic_remove(struct i2c_client *i2c) ...@@ -440,6 +442,33 @@ static int sec_pmic_remove(struct i2c_client *i2c)
return 0; return 0;
} }
static void sec_pmic_shutdown(struct i2c_client *i2c)
{
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
unsigned int reg, mask;
if (!sec_pmic->pdata->manual_poweroff)
return;
switch (sec_pmic->device_type) {
case S2MPS11X:
reg = S2MPS11_REG_CTRL1;
mask = S2MPS11_CTRL1_PWRHOLD_MASK;
break;
default:
/*
* Currently only one board with S2MPS11 needs this, so just
* ignore the rest.
*/
dev_warn(sec_pmic->dev,
"Unsupported device %lu for manual power off\n",
sec_pmic->device_type);
return;
}
regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
}
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int sec_pmic_suspend(struct device *dev) static int sec_pmic_suspend(struct device *dev)
{ {
...@@ -491,6 +520,7 @@ static struct i2c_driver sec_pmic_driver = { ...@@ -491,6 +520,7 @@ static struct i2c_driver sec_pmic_driver = {
}, },
.probe = sec_pmic_probe, .probe = sec_pmic_probe,
.remove = sec_pmic_remove, .remove = sec_pmic_remove,
.shutdown = sec_pmic_shutdown,
.id_table = sec_pmic_id, .id_table = sec_pmic_id,
}; };
......
...@@ -132,6 +132,8 @@ struct sec_platform_data { ...@@ -132,6 +132,8 @@ struct sec_platform_data {
int buck2_init; int buck2_init;
int buck3_init; int buck3_init;
int buck4_init; int buck4_init;
/* Whether or not manually set PWRHOLD to low during shutdown. */
bool manual_poweroff;
}; };
/** /**
......
...@@ -179,6 +179,7 @@ enum s2mps11_regulators { ...@@ -179,6 +179,7 @@ enum s2mps11_regulators {
#define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1) #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
#define S2MPS11_RAMP_DELAY 25000 /* uV/us */ #define S2MPS11_RAMP_DELAY 25000 /* uV/us */
#define S2MPS11_CTRL1_PWRHOLD_MASK BIT(4)
#define S2MPS11_BUCK2_RAMP_SHIFT 6 #define S2MPS11_BUCK2_RAMP_SHIFT 6
#define S2MPS11_BUCK34_RAMP_SHIFT 4 #define S2MPS11_BUCK34_RAMP_SHIFT 4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment