Skip to content
Permalink
Browse files
i2c-mux-pca954x: Add regulator support
Add an optional vcc regulator and enable it when found for devices
that are powered off by default.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
  • Loading branch information
PatrickRudolph authored and intel-lab-lkp committed Dec 14, 2021
1 parent 7e6b1c8 commit 3498c52eb6aec09c78a3f07cdcb042897960f8ef
Showing 1 changed file with 28 additions and 5 deletions.
@@ -48,6 +48,7 @@
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <dt-bindings/mux/mux.h>
@@ -101,6 +102,7 @@ struct pca954x {
struct irq_domain *irq;
unsigned int irq_mask;
raw_spinlock_t lock;
struct regulator *supply;
};

/* Provide specs for the PCA954x and MAX735x types we know about */
@@ -425,6 +427,9 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc)
struct pca954x *data = i2c_mux_priv(muxc);
int c, irq;

if (!IS_ERR_OR_NULL(data->supply))
regulator_disable(data->supply);

if (data->irq) {
for (c = 0; c < data->chip->nchans; c++) {
irq = irq_find_mapping(data->irq, c);
@@ -484,15 +489,31 @@ static int pca954x_probe(struct i2c_client *client,
pca954x_select_chan, pca954x_deselect_mux);
if (!muxc)
return -ENOMEM;

data = i2c_mux_priv(muxc);

i2c_set_clientdata(client, muxc);
data->client = client;

data->supply = devm_regulator_get(dev, "vcc");
if (IS_ERR(data->supply)) {
if ((PTR_ERR(data->supply) == -EPROBE_DEFER))
return -EPROBE_DEFER;
dev_warn(dev, "Failed to get regulator for vcc: %d\n", ret);
} else {
ret = regulator_enable(data->supply);
if (ret) {
dev_err(dev, "Failed to enable regulator vcc\n");
return ret;
}
}

/* Reset the mux if a reset GPIO is specified. */
gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpio))
return PTR_ERR(gpio);
if (IS_ERR(gpio)) {
ret = PTR_ERR(gpio);
goto fail_cleanup;
}
if (gpio) {
udelay(1);
gpiod_set_value_cansleep(gpio, 0);
@@ -509,15 +530,16 @@ static int pca954x_probe(struct i2c_client *client,

ret = i2c_get_device_id(client, &id);
if (ret && ret != -EOPNOTSUPP)
return ret;
goto fail_cleanup;

if (!ret &&
(id.manufacturer_id != data->chip->id.manufacturer_id ||
id.part_id != data->chip->id.part_id)) {
dev_warn(dev, "unexpected device id %03x-%03x-%x\n",
id.manufacturer_id, id.part_id,
id.die_revision);
return -ENODEV;
ret = -ENODEV;
goto fail_cleanup;
}
}

@@ -536,7 +558,8 @@ static int pca954x_probe(struct i2c_client *client,
ret = pca954x_init(client, data);
if (ret < 0) {
dev_warn(dev, "probe failed\n");
return -ENODEV;
ret = -ENODEV;
goto fail_cleanup;
}

ret = pca954x_irq_setup(muxc);

0 comments on commit 3498c52

Please sign in to comment.