mirror of https://gitee.com/openkylin/linux.git
Merge branch 'i2c-mux/for-next' of https://github.com/peda-r/i2c-mux into i2c/for-5.3
I realize that there are changes in drivers/i2c/busses/i2c-i801.c that strictly speaking don't belong here, but I hope you don't mind. These changes are all about the interaction with the i2c-mux-gpio code, and I did a test-merge a few days ago w/o conflicts. Anyway, the GPIO-work from Linus Walleij (with help from Serge Semin) in the i2c-mux-gpio and i2c-arb-gpio-challenge drivers is the main feature.
This commit is contained in:
commit
45c9cc681d
|
@ -1,7 +1,7 @@
|
|||
What: /sys/devices/platform/<i2c-demux-name>/available_masters
|
||||
Date: January 2016
|
||||
KernelVersion: 4.6
|
||||
Contact: Wolfram Sang <wsa@the-dreams.de>
|
||||
Contact: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
Description:
|
||||
Reading the file will give you a list of masters which can be
|
||||
selected for a demultiplexed bus. The format is
|
||||
|
@ -12,7 +12,7 @@ Description:
|
|||
What: /sys/devices/platform/<i2c-demux-name>/current_master
|
||||
Date: January 2016
|
||||
KernelVersion: 4.6
|
||||
Contact: Wolfram Sang <wsa@the-dreams.de>
|
||||
Contact: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
Description:
|
||||
This file selects/shows the active I2C master for a demultiplexed
|
||||
bus. It uses the <index> value from the file 'available_masters'.
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/platform_data/i2c-mux-gpio.h>
|
||||
#endif
|
||||
|
||||
|
@ -278,6 +278,7 @@ struct i801_priv {
|
|||
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
|
||||
const struct i801_mux_config *mux_drvdata;
|
||||
struct platform_device *mux_pdev;
|
||||
struct gpiod_lookup_table *lookup;
|
||||
#endif
|
||||
struct platform_device *tco_pdev;
|
||||
|
||||
|
@ -1406,7 +1407,8 @@ static int i801_add_mux(struct i801_priv *priv)
|
|||
struct device *dev = &priv->adapter.dev;
|
||||
const struct i801_mux_config *mux_config;
|
||||
struct i2c_mux_gpio_platform_data gpio_data;
|
||||
int err;
|
||||
struct gpiod_lookup_table *lookup;
|
||||
int err, i;
|
||||
|
||||
if (!priv->mux_drvdata)
|
||||
return 0;
|
||||
|
@ -1418,17 +1420,36 @@ static int i801_add_mux(struct i801_priv *priv)
|
|||
gpio_data.values = mux_config->values;
|
||||
gpio_data.n_values = mux_config->n_values;
|
||||
gpio_data.classes = mux_config->classes;
|
||||
gpio_data.gpio_chip = mux_config->gpio_chip;
|
||||
gpio_data.gpios = mux_config->gpios;
|
||||
gpio_data.n_gpios = mux_config->n_gpios;
|
||||
gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
|
||||
|
||||
/* Register the mux device */
|
||||
/* Register GPIO descriptor lookup table */
|
||||
lookup = devm_kzalloc(dev,
|
||||
struct_size(lookup, table, mux_config->n_gpios),
|
||||
GFP_KERNEL);
|
||||
if (!lookup)
|
||||
return -ENOMEM;
|
||||
lookup->dev_id = "i2c-mux-gpio";
|
||||
for (i = 0; i < mux_config->n_gpios; i++) {
|
||||
lookup->table[i].chip_label = mux_config->gpio_chip;
|
||||
lookup->table[i].chip_hwnum = mux_config->gpios[i];
|
||||
lookup->table[i].con_id = "mux";
|
||||
}
|
||||
gpiod_add_lookup_table(lookup);
|
||||
priv->lookup = lookup;
|
||||
|
||||
/*
|
||||
* Register the mux device, we use PLATFORM_DEVID_NONE here
|
||||
* because since we are referring to the GPIO chip by name we are
|
||||
* anyways in deep trouble if there is more than one of these
|
||||
* devices, and there should likely only be one platform controller
|
||||
* hub.
|
||||
*/
|
||||
priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
|
||||
PLATFORM_DEVID_AUTO, &gpio_data,
|
||||
PLATFORM_DEVID_NONE, &gpio_data,
|
||||
sizeof(struct i2c_mux_gpio_platform_data));
|
||||
if (IS_ERR(priv->mux_pdev)) {
|
||||
err = PTR_ERR(priv->mux_pdev);
|
||||
gpiod_remove_lookup_table(lookup);
|
||||
priv->mux_pdev = NULL;
|
||||
dev_err(dev, "Failed to register i2c-mux-gpio device\n");
|
||||
return err;
|
||||
|
@ -1441,6 +1462,8 @@ static void i801_del_mux(struct i801_priv *priv)
|
|||
{
|
||||
if (priv->mux_pdev)
|
||||
platform_device_unregister(priv->mux_pdev);
|
||||
if (priv->lookup)
|
||||
gpiod_remove_lookup_table(priv->lookup);
|
||||
}
|
||||
|
||||
static unsigned int i801_get_adapter_class(struct i801_priv *priv)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
/* multiplexer per channel data */
|
||||
struct i2c_mux_priv {
|
||||
|
@ -243,8 +244,7 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
|
|||
{
|
||||
struct i2c_mux_core *muxc;
|
||||
|
||||
muxc = devm_kzalloc(dev, sizeof(*muxc)
|
||||
+ max_adapters * sizeof(muxc->adapter[0])
|
||||
muxc = devm_kzalloc(dev, struct_size(muxc, adapter, max_adapters)
|
||||
+ sizeof_priv, GFP_KERNEL);
|
||||
if (!muxc)
|
||||
return NULL;
|
||||
|
|
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -28,22 +27,16 @@
|
|||
/**
|
||||
* struct i2c_arbitrator_data - Driver data for I2C arbitrator
|
||||
*
|
||||
* @our_gpio: GPIO we'll use to claim.
|
||||
* @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
|
||||
* this then consider it released.
|
||||
* @their_gpio: GPIO that the other side will use to claim.
|
||||
* @their_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
|
||||
* this then consider it released.
|
||||
* @our_gpio: GPIO descriptor we'll use to claim.
|
||||
* @their_gpio: GPIO descriptor that the other side will use to claim.
|
||||
* @slew_delay_us: microseconds to wait for a GPIO to go high.
|
||||
* @wait_retry_us: we'll attempt another claim after this many microseconds.
|
||||
* @wait_free_us: we'll give up after this many microseconds.
|
||||
*/
|
||||
|
||||
struct i2c_arbitrator_data {
|
||||
int our_gpio;
|
||||
int our_gpio_release;
|
||||
int their_gpio;
|
||||
int their_gpio_release;
|
||||
struct gpio_desc *our_gpio;
|
||||
struct gpio_desc *their_gpio;
|
||||
unsigned int slew_delay_us;
|
||||
unsigned int wait_retry_us;
|
||||
unsigned int wait_free_us;
|
||||
|
@ -64,15 +57,15 @@ static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
|
|||
stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1;
|
||||
do {
|
||||
/* Indicate that we want to claim the bus */
|
||||
gpio_set_value(arb->our_gpio, !arb->our_gpio_release);
|
||||
gpiod_set_value(arb->our_gpio, 1);
|
||||
udelay(arb->slew_delay_us);
|
||||
|
||||
/* Wait for the other master to release it */
|
||||
stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1;
|
||||
while (time_before(jiffies, stop_retry)) {
|
||||
int gpio_val = !!gpio_get_value(arb->their_gpio);
|
||||
int gpio_val = gpiod_get_value(arb->their_gpio);
|
||||
|
||||
if (gpio_val == arb->their_gpio_release) {
|
||||
if (!gpio_val) {
|
||||
/* We got it, so return */
|
||||
return 0;
|
||||
}
|
||||
|
@ -81,13 +74,13 @@ static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
|
|||
}
|
||||
|
||||
/* It didn't release, so give up, wait, and try again */
|
||||
gpio_set_value(arb->our_gpio, arb->our_gpio_release);
|
||||
gpiod_set_value(arb->our_gpio, 0);
|
||||
|
||||
usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2);
|
||||
} while (time_before(jiffies, stop_time));
|
||||
|
||||
/* Give up, release our claim */
|
||||
gpio_set_value(arb->our_gpio, arb->our_gpio_release);
|
||||
gpiod_set_value(arb->our_gpio, 0);
|
||||
udelay(arb->slew_delay_us);
|
||||
dev_err(muxc->dev, "Could not claim bus, timeout\n");
|
||||
return -EBUSY;
|
||||
|
@ -103,7 +96,7 @@ static int i2c_arbitrator_deselect(struct i2c_mux_core *muxc, u32 chan)
|
|||
const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
|
||||
|
||||
/* Release the bus and wait for the other master to notice */
|
||||
gpio_set_value(arb->our_gpio, arb->our_gpio_release);
|
||||
gpiod_set_value(arb->our_gpio, 0);
|
||||
udelay(arb->slew_delay_us);
|
||||
|
||||
return 0;
|
||||
|
@ -116,8 +109,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
|
|||
struct device_node *parent_np;
|
||||
struct i2c_mux_core *muxc;
|
||||
struct i2c_arbitrator_data *arb;
|
||||
enum of_gpio_flags gpio_flags;
|
||||
unsigned long out_init;
|
||||
struct gpio_desc *dummy;
|
||||
int ret;
|
||||
|
||||
/* We only support probing from device tree; no platform_data */
|
||||
|
@ -138,45 +130,28 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, muxc);
|
||||
|
||||
/* Request GPIOs */
|
||||
ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags);
|
||||
if (!gpio_is_valid(ret)) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error getting our-claim-gpio\n");
|
||||
return ret;
|
||||
}
|
||||
arb->our_gpio = ret;
|
||||
arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
|
||||
out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ?
|
||||
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
ret = devm_gpio_request_one(dev, arb->our_gpio, out_init,
|
||||
"our-claim-gpio");
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error requesting our-claim-gpio\n");
|
||||
return ret;
|
||||
/* Request GPIOs, our GPIO as unclaimed to begin with */
|
||||
arb->our_gpio = devm_gpiod_get(dev, "our-claim", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(arb->our_gpio)) {
|
||||
dev_err(dev, "could not get \"our-claim\" GPIO (%ld)\n",
|
||||
PTR_ERR(arb->our_gpio));
|
||||
return PTR_ERR(arb->our_gpio);
|
||||
}
|
||||
|
||||
ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags);
|
||||
if (!gpio_is_valid(ret)) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error getting their-claim-gpio\n");
|
||||
return ret;
|
||||
}
|
||||
arb->their_gpio = ret;
|
||||
arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
|
||||
ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN,
|
||||
"their-claim-gpio");
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error requesting their-claim-gpio\n");
|
||||
return ret;
|
||||
arb->their_gpio = devm_gpiod_get(dev, "their-claim", GPIOD_IN);
|
||||
if (IS_ERR(arb->their_gpio)) {
|
||||
dev_err(dev, "could not get \"their-claim\" GPIO (%ld)\n",
|
||||
PTR_ERR(arb->their_gpio));
|
||||
return PTR_ERR(arb->their_gpio);
|
||||
}
|
||||
|
||||
/* At the moment we only support a single two master (us + 1 other) */
|
||||
if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) {
|
||||
dummy = devm_gpiod_get_index(dev, "their-claim", 1, GPIOD_IN);
|
||||
if (!IS_ERR(dummy)) {
|
||||
dev_err(dev, "Only one other master is supported\n");
|
||||
return -EINVAL;
|
||||
} else if (PTR_ERR(dummy) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
/* Arbitration parameters */
|
||||
|
|
|
@ -14,13 +14,14 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
/* FIXME: stop poking around inside gpiolib */
|
||||
#include "../../gpio/gpiolib.h"
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
struct gpiomux {
|
||||
struct i2c_mux_gpio_platform_data data;
|
||||
unsigned gpio_base;
|
||||
int ngpios;
|
||||
struct gpio_desc **gpios;
|
||||
};
|
||||
|
||||
|
@ -30,8 +31,7 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
|
|||
|
||||
values[0] = val;
|
||||
|
||||
gpiod_set_array_value_cansleep(mux->data.n_gpios, mux->gpios, NULL,
|
||||
values);
|
||||
gpiod_set_array_value_cansleep(mux->ngpios, mux->gpios, NULL, values);
|
||||
}
|
||||
|
||||
static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
|
||||
|
@ -52,12 +52,6 @@ static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int match_gpio_chip_by_label(struct gpio_chip *chip,
|
||||
void *data)
|
||||
{
|
||||
return !strcmp(chip->label, data);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
|
||||
struct platform_device *pdev)
|
||||
|
@ -65,8 +59,8 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
|
|||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *adapter_np, *child;
|
||||
struct i2c_adapter *adapter;
|
||||
unsigned *values, *gpios;
|
||||
int i = 0, ret;
|
||||
unsigned *values;
|
||||
int i = 0;
|
||||
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
@ -103,29 +97,6 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
|
|||
if (of_property_read_u32(np, "idle-state", &mux->data.idle))
|
||||
mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
|
||||
|
||||
mux->data.n_gpios = of_gpio_named_count(np, "mux-gpios");
|
||||
if (mux->data.n_gpios < 0) {
|
||||
dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpios = devm_kcalloc(&pdev->dev,
|
||||
mux->data.n_gpios, sizeof(*mux->data.gpios),
|
||||
GFP_KERNEL);
|
||||
if (!gpios) {
|
||||
dev_err(&pdev->dev, "Cannot allocate gpios array");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < mux->data.n_gpios; i++) {
|
||||
ret = of_get_named_gpio(np, "mux-gpios", i);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
gpios[i] = ret;
|
||||
}
|
||||
|
||||
mux->data.gpios = gpios;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -142,8 +113,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
|
|||
struct gpiomux *mux;
|
||||
struct i2c_adapter *parent;
|
||||
struct i2c_adapter *root;
|
||||
unsigned initial_state, gpio_base;
|
||||
int i, ret;
|
||||
unsigned initial_state;
|
||||
int i, ngpios, ret;
|
||||
|
||||
mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
|
@ -158,29 +129,19 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
|
|||
sizeof(mux->data));
|
||||
}
|
||||
|
||||
/*
|
||||
* If a GPIO chip name is provided, the GPIO pin numbers provided are
|
||||
* relative to its base GPIO number. Otherwise they are absolute.
|
||||
*/
|
||||
if (mux->data.gpio_chip) {
|
||||
struct gpio_chip *gpio;
|
||||
|
||||
gpio = gpiochip_find(mux->data.gpio_chip,
|
||||
match_gpio_chip_by_label);
|
||||
if (!gpio)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
gpio_base = gpio->base;
|
||||
} else {
|
||||
gpio_base = 0;
|
||||
ngpios = gpiod_count(&pdev->dev, "mux");
|
||||
if (ngpios <= 0) {
|
||||
dev_err(&pdev->dev, "no valid gpios provided\n");
|
||||
return ngpios ?: -EINVAL;
|
||||
}
|
||||
mux->ngpios = ngpios;
|
||||
|
||||
parent = i2c_get_adapter(mux->data.parent);
|
||||
if (!parent)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values,
|
||||
mux->data.n_gpios * sizeof(*mux->gpios), 0,
|
||||
ngpios * sizeof(*mux->gpios), 0,
|
||||
i2c_mux_gpio_select, NULL);
|
||||
if (!muxc) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -194,7 +155,6 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
|
|||
root = i2c_root_adapter(&parent->dev);
|
||||
|
||||
muxc->mux_locked = true;
|
||||
mux->gpio_base = gpio_base;
|
||||
|
||||
if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
|
||||
initial_state = mux->data.idle;
|
||||
|
@ -203,34 +163,28 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
|
|||
initial_state = mux->data.values[0];
|
||||
}
|
||||
|
||||
for (i = 0; i < mux->data.n_gpios; i++) {
|
||||
for (i = 0; i < ngpios; i++) {
|
||||
struct device *gpio_dev;
|
||||
struct gpio_desc *gpio_desc;
|
||||
struct gpio_desc *gpiod;
|
||||
enum gpiod_flags flag;
|
||||
|
||||
ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to request GPIO %d\n",
|
||||
mux->data.gpios[i]);
|
||||
goto err_request_gpio;
|
||||
if (initial_state & BIT(i))
|
||||
flag = GPIOD_OUT_HIGH;
|
||||
else
|
||||
flag = GPIOD_OUT_LOW;
|
||||
gpiod = devm_gpiod_get_index(&pdev->dev, "mux", i, flag);
|
||||
if (IS_ERR(gpiod)) {
|
||||
ret = PTR_ERR(gpiod);
|
||||
goto alloc_failed;
|
||||
}
|
||||
|
||||
ret = gpio_direction_output(gpio_base + mux->data.gpios[i],
|
||||
initial_state & (1 << i));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to set direction of GPIO %d to output\n",
|
||||
mux->data.gpios[i]);
|
||||
i++; /* gpio_request above succeeded, so must free */
|
||||
goto err_request_gpio;
|
||||
}
|
||||
|
||||
gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]);
|
||||
mux->gpios[i] = gpio_desc;
|
||||
mux->gpios[i] = gpiod;
|
||||
|
||||
if (!muxc->mux_locked)
|
||||
continue;
|
||||
|
||||
gpio_dev = &gpio_desc->gdev->dev;
|
||||
/* FIXME: find a proper way to access the GPIO device */
|
||||
gpio_dev = &gpiod->gdev->dev;
|
||||
muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
|
||||
}
|
||||
|
||||
|
@ -253,10 +207,6 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
add_adapter_failed:
|
||||
i2c_mux_del_adapters(muxc);
|
||||
i = mux->data.n_gpios;
|
||||
err_request_gpio:
|
||||
for (; i > 0; i--)
|
||||
gpio_free(gpio_base + mux->data.gpios[i - 1]);
|
||||
alloc_failed:
|
||||
i2c_put_adapter(parent);
|
||||
|
||||
|
@ -266,14 +216,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
|
|||
static int i2c_mux_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
|
||||
struct gpiomux *mux = i2c_mux_priv(muxc);
|
||||
int i;
|
||||
|
||||
i2c_mux_del_adapters(muxc);
|
||||
|
||||
for (i = 0; i < mux->data.n_gpios; i++)
|
||||
gpio_free(mux->gpio_base + mux->data.gpios[i]);
|
||||
|
||||
i2c_put_adapter(muxc->parent);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
struct i2c_mux_pinctrl {
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state **states;
|
||||
struct pinctrl_state *states[];
|
||||
};
|
||||
|
||||
static int i2c_mux_pinctrl_select(struct i2c_mux_core *muxc, u32 chan)
|
||||
|
@ -104,14 +104,13 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(parent);
|
||||
|
||||
muxc = i2c_mux_alloc(parent, dev, num_names,
|
||||
sizeof(*mux) + num_names * sizeof(*mux->states),
|
||||
struct_size(mux, states, num_names),
|
||||
0, i2c_mux_pinctrl_select, NULL);
|
||||
if (!muxc) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_parent;
|
||||
}
|
||||
mux = i2c_mux_priv(muxc);
|
||||
mux->states = (struct pinctrl_state **)(mux + 1);
|
||||
|
||||
platform_set_drvdata(pdev, muxc);
|
||||
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
* position
|
||||
* @n_values: Number of multiplexer positions (busses to instantiate)
|
||||
* @classes: Optional I2C auto-detection classes
|
||||
* @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given
|
||||
* relative to the base GPIO number of that chip
|
||||
* @gpios: Array of GPIO numbers used to control MUX
|
||||
* @n_gpios: Number of GPIOs used to control MUX
|
||||
* @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
|
||||
*/
|
||||
struct i2c_mux_gpio_platform_data {
|
||||
|
@ -34,9 +30,6 @@ struct i2c_mux_gpio_platform_data {
|
|||
const unsigned *values;
|
||||
int n_values;
|
||||
const unsigned *classes;
|
||||
char *gpio_chip;
|
||||
const unsigned *gpios;
|
||||
int n_gpios;
|
||||
unsigned idle;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue