From 50497409761daa7041f7502ed5f49d3fc56b80af Mon Sep 17 00:00:00 2001 From: shengfei Xu Date: Mon, 11 Jan 2021 10:10:08 +0000 Subject: [PATCH] regulator: fan53555: support reboot Fixes: 91c0d689ea8a ("Revert "regulator: fan53555: support reboot"") Signed-off-by: shengfei Xu Signed-off-by: Elaine Zhang Change-Id: I143fc44f49c95f01248c72a8f48282bf984b826b --- drivers/regulator/fan53555.c | 42 +++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index e00dd5ae52b8..9ed748d603f6 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -29,6 +29,7 @@ #define TCS4525_VSEL1 0x10 #define TCS4525_TIME 0x13 #define TCS4525_COMMAND 0x14 +#define TCS4525_LIMCONF 0x16 /* Control register */ #define FAN53555_CONTROL 0x02 @@ -109,6 +110,7 @@ enum { struct fan53555_device_info { enum fan53555_vendor vendor; + struct regmap *regmap; struct device *dev; struct regulator_desc desc; struct regulator_init_data *regulator; @@ -635,6 +637,7 @@ static int fan53555_regulator_probe(struct i2c_client *client, dev_err(&client->dev, "Failed to allocate regmap!\n"); return PTR_ERR(regmap); } + di->regmap = regmap; di->dev = &client->dev; i2c_set_clientdata(client, di); /* Get chip ID */ @@ -669,8 +672,44 @@ static int fan53555_regulator_probe(struct i2c_client *client, ret = fan53555_regulator_register(di, &config); if (ret < 0) dev_err(&client->dev, "Failed to register regulator!\n"); - return ret; + return ret; +} + +static void fan53555_regulator_shutdown(struct i2c_client *client) +{ + struct fan53555_device_info *di; + int ret; + + di = i2c_get_clientdata(client); + + dev_info(di->dev, "fan53555..... reset\n"); + + switch (di->vendor) { + case FAN53555_VENDOR_FAIRCHILD: + case FAN53555_VENDOR_SILERGY: + ret = regmap_update_bits(di->regmap, di->slew_reg, + CTL_RESET, CTL_RESET); + break; + case FAN53526_VENDOR_TCS: + ret = regmap_update_bits(di->regmap, TCS4525_LIMCONF, + CTL_RESET, CTL_RESET); + /* + * the device can't return 'ack' during the reset, + * it will return -ENXIO, ignore this error. + */ + if (ret == -ENXIO) + ret = 0; + break; + default: + ret = -EINVAL; + break; + } + + if (ret < 0) + dev_err(di->dev, "reset: force fan53555_reset error! ret=%d\n", ret); + else + dev_info(di->dev, "reset: force fan53555_reset ok!\n"); } static const struct i2c_device_id fan53555_id[] = { @@ -703,6 +742,7 @@ static struct i2c_driver fan53555_regulator_driver = { .of_match_table = of_match_ptr(fan53555_dt_ids), }, .probe = fan53555_regulator_probe, + .shutdown = fan53555_regulator_shutdown, .id_table = fan53555_id, };