leds: aw2013: Enable pull-up supply for interrupt and I2C

Request and enable the "vio" regulator that represents the power supply
that is needed for the pull-up resistors of the interrupt and I2C lines
of AW2013. While this regulator is not wired directly to the AW2013
chip it is best managed as part of the AW2013 driver since it decides
when AW2013 is powered on and when the interrupt is enabled or
disabled.

This regulator should always be enabled in conjunction with the main
VCC power supply, so use the bulk regulator functions to enable both
at the same time.

Signed-off-by: Lin, Meng-Bo <linmengbo0689@protonmail.com>
[rewrite commit message based on discussion]
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Reviewed-by: Nikita Travkin <nikita@trvn.ru>
Link: https://lore.kernel.org/r/20230815-aw2013-vio-v3-3-2505296b0856@gerhold.net
Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
Lin, Meng-Bo 2023-08-15 19:21:06 +02:00 committed by Lee Jones
parent 2cccb179ad
commit baca986e1f

View File

@ -62,7 +62,7 @@ struct aw2013_led {
struct aw2013 {
struct mutex mutex; /* held when writing to registers */
struct regulator *vcc_regulator;
struct regulator_bulk_data regulators[2];
struct i2c_client *client;
struct aw2013_led leds[AW2013_MAX_LEDS];
struct regmap *regmap;
@ -106,10 +106,11 @@ static void aw2013_chip_disable(struct aw2013 *chip)
regmap_write(chip->regmap, AW2013_GCR, 0);
ret = regulator_disable(chip->vcc_regulator);
ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
chip->regulators);
if (ret) {
dev_err(&chip->client->dev,
"Failed to disable regulator: %d\n", ret);
"Failed to disable regulators: %d\n", ret);
return;
}
@ -123,10 +124,11 @@ static int aw2013_chip_enable(struct aw2013 *chip)
if (chip->enabled)
return 0;
ret = regulator_enable(chip->vcc_regulator);
ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators),
chip->regulators);
if (ret) {
dev_err(&chip->client->dev,
"Failed to enable regulator: %d\n", ret);
"Failed to enable regulators: %d\n", ret);
return ret;
}
chip->enabled = true;
@ -348,19 +350,23 @@ static int aw2013_probe(struct i2c_client *client)
goto error;
}
chip->vcc_regulator = devm_regulator_get(&client->dev, "vcc");
ret = PTR_ERR_OR_ZERO(chip->vcc_regulator);
if (ret) {
chip->regulators[0].supply = "vcc";
chip->regulators[1].supply = "vio";
ret = devm_regulator_bulk_get(&client->dev,
ARRAY_SIZE(chip->regulators),
chip->regulators);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
dev_err(&client->dev,
"Failed to request regulator: %d\n", ret);
"Failed to request regulators: %d\n", ret);
goto error;
}
ret = regulator_enable(chip->vcc_regulator);
ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators),
chip->regulators);
if (ret) {
dev_err(&client->dev,
"Failed to enable regulator: %d\n", ret);
"Failed to enable regulators: %d\n", ret);
goto error;
}
@ -382,10 +388,11 @@ static int aw2013_probe(struct i2c_client *client)
if (ret < 0)
goto error_reg;
ret = regulator_disable(chip->vcc_regulator);
ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
chip->regulators);
if (ret) {
dev_err(&client->dev,
"Failed to disable regulator: %d\n", ret);
"Failed to disable regulators: %d\n", ret);
goto error;
}
@ -394,7 +401,8 @@ static int aw2013_probe(struct i2c_client *client)
return 0;
error_reg:
regulator_disable(chip->vcc_regulator);
regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
chip->regulators);
error:
mutex_destroy(&chip->mutex);