Skip to content

Commit b7b73f6

Browse files
cpackham-atlnzWolfram Sang
authored andcommitted
i2c: muxes: pca954x: Allow sharing reset GPIO
Some hardware designs with multiple PCA954x devices use a reset GPIO connected to all the muxes. Support this configuration by making use of the reset controller framework which can deal with the shared reset GPIOs. Fall back to the old GPIO descriptor method if the reset controller framework is not enabled. Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz> Acked-by: Peter Rosin <peda@axentia.se> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
1 parent 7e5d423 commit b7b73f6

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

drivers/i2c/muxes/i2c-mux-pca954x.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <linux/pm.h>
5050
#include <linux/property.h>
5151
#include <linux/regulator/consumer.h>
52+
#include <linux/reset.h>
5253
#include <linux/slab.h>
5354
#include <linux/spinlock.h>
5455
#include <dt-bindings/mux/mux.h>
@@ -116,6 +117,9 @@ struct pca954x {
116117
unsigned int irq_mask;
117118
raw_spinlock_t lock;
118119
struct regulator *supply;
120+
121+
struct gpio_desc *reset_gpio;
122+
struct reset_control *reset_cont;
119123
};
120124

121125
/* Provide specs for the MAX735x, PCA954x and PCA984x types we know about */
@@ -518,6 +522,35 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data)
518522
return ret;
519523
}
520524

525+
static int pca954x_get_reset(struct device *dev, struct pca954x *data)
526+
{
527+
data->reset_cont = devm_reset_control_get_optional_shared(dev, NULL);
528+
if (IS_ERR(data->reset_cont))
529+
return dev_err_probe(dev, PTR_ERR(data->reset_cont),
530+
"Failed to get reset\n");
531+
else if (data->reset_cont)
532+
return 0;
533+
534+
/*
535+
* fallback to legacy reset-gpios
536+
*/
537+
data->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
538+
if (IS_ERR(data->reset_gpio)) {
539+
return dev_err_probe(dev, PTR_ERR(data->reset_gpio),
540+
"Failed to get reset gpio");
541+
}
542+
543+
return 0;
544+
}
545+
546+
static void pca954x_reset_deassert(struct pca954x *data)
547+
{
548+
if (data->reset_cont)
549+
reset_control_deassert(data->reset_cont);
550+
else
551+
gpiod_set_value_cansleep(data->reset_gpio, 0);
552+
}
553+
521554
/*
522555
* I2C init/probing/exit functions
523556
*/
@@ -526,7 +559,6 @@ static int pca954x_probe(struct i2c_client *client)
526559
const struct i2c_device_id *id = i2c_client_get_device_id(client);
527560
struct i2c_adapter *adap = client->adapter;
528561
struct device *dev = &client->dev;
529-
struct gpio_desc *gpio;
530562
struct i2c_mux_core *muxc;
531563
struct pca954x *data;
532564
int num;
@@ -554,15 +586,13 @@ static int pca954x_probe(struct i2c_client *client)
554586
return dev_err_probe(dev, ret,
555587
"Failed to enable vdd supply\n");
556588

557-
/* Reset the mux if a reset GPIO is specified. */
558-
gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
559-
if (IS_ERR(gpio)) {
560-
ret = PTR_ERR(gpio);
589+
ret = pca954x_get_reset(dev, data);
590+
if (ret)
561591
goto fail_cleanup;
562-
}
563-
if (gpio) {
592+
593+
if (data->reset_cont || data->reset_gpio) {
564594
udelay(1);
565-
gpiod_set_value_cansleep(gpio, 0);
595+
pca954x_reset_deassert(data);
566596
/* Give the chip some time to recover. */
567597
udelay(1);
568598
}

0 commit comments

Comments
 (0)