summaryrefslogtreecommitdiff
path: root/drivers/i2c/muxes
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/muxes')
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpio.c56
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca9541.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c10
-rw-r--r--drivers/i2c/muxes/i2c-mux-pinctrl.c2
4 files changed, 48 insertions, 22 deletions
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 68b1f8e..566a675 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -21,6 +21,7 @@ struct gpiomux {
struct i2c_adapter *parent;
struct i2c_adapter **adap; /* child busses */
struct i2c_mux_gpio_platform_data data;
+ unsigned gpio_base;
};
static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
@@ -28,7 +29,8 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
int i;
for (i = 0; i < mux->data.n_gpios; i++)
- gpio_set_value(mux->data.gpios[i], val & (1 << i));
+ gpio_set_value(mux->gpio_base + mux->data.gpios[i],
+ val & (1 << i));
}
static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
@@ -49,13 +51,19 @@ static int i2c_mux_gpio_deselect(struct i2c_adapter *adap, void *data, u32 chan)
return 0;
}
+static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
+ void *data)
+{
+ return !strcmp(chip->label, data);
+}
+
static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
{
struct gpiomux *mux;
struct i2c_mux_gpio_platform_data *pdata;
struct i2c_adapter *parent;
int (*deselect) (struct i2c_adapter *, void *, u32);
- unsigned initial_state;
+ unsigned initial_state, gpio_base;
int i, ret;
pdata = pdev->dev.platform_data;
@@ -64,6 +72,23 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
+ /*
+ * If a GPIO chip name is provided, the GPIO pin numbers provided are
+ * relative to its base GPIO number. Otherwise they are absolute.
+ */
+ if (pdata->gpio_chip) {
+ struct gpio_chip *gpio;
+
+ gpio = gpiochip_find(pdata->gpio_chip,
+ match_gpio_chip_by_label);
+ if (!gpio)
+ return -EPROBE_DEFER;
+
+ gpio_base = gpio->base;
+ } else {
+ gpio_base = 0;
+ }
+
parent = i2c_get_adapter(pdata->parent);
if (!parent) {
dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
@@ -71,7 +96,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
if (!mux) {
ret = -ENOMEM;
goto alloc_failed;
@@ -79,11 +104,13 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
mux->parent = parent;
mux->data = *pdata;
- mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
- GFP_KERNEL);
+ mux->gpio_base = gpio_base;
+ mux->adap = devm_kzalloc(&pdev->dev,
+ sizeof(*mux->adap) * pdata->n_values,
+ GFP_KERNEL);
if (!mux->adap) {
ret = -ENOMEM;
- goto alloc_failed2;
+ goto alloc_failed;
}
if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) {
@@ -95,17 +122,19 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
}
for (i = 0; i < pdata->n_gpios; i++) {
- ret = gpio_request(pdata->gpios[i], "i2c-mux-gpio");
+ ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio");
if (ret)
goto err_request_gpio;
- gpio_direction_output(pdata->gpios[i],
+ gpio_direction_output(gpio_base + pdata->gpios[i],
initial_state & (1 << i));
}
for (i = 0; i < pdata->n_values; i++) {
u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
+ unsigned int class = pdata->classes ? pdata->classes[i] : 0;
- mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, i,
+ mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
+ i, class,
i2c_mux_gpio_select, deselect);
if (!mux->adap[i]) {
ret = -ENODEV;
@@ -127,10 +156,7 @@ add_adapter_failed:
i = pdata->n_gpios;
err_request_gpio:
for (; i > 0; i--)
- gpio_free(pdata->gpios[i - 1]);
- kfree(mux->adap);
-alloc_failed2:
- kfree(mux);
+ gpio_free(gpio_base + pdata->gpios[i - 1]);
alloc_failed:
i2c_put_adapter(parent);
@@ -146,12 +172,10 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev)
i2c_del_mux_adapter(mux->adap[i]);
for (i = 0; i < mux->data.n_gpios; i++)
- gpio_free(mux->data.gpios[i]);
+ gpio_free(mux->gpio_base + mux->data.gpios[i]);
platform_set_drvdata(pdev, NULL);
i2c_put_adapter(mux->parent);
- kfree(mux->adap);
- kfree(mux);
return 0;
}
diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index f8f72f3..f3b8f9a 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -354,7 +354,7 @@ static int pca9541_probe(struct i2c_client *client,
if (pdata)
force = pdata->modes[0].adap_id;
data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
- force, 0,
+ force, 0, 0,
pca9541_select_chan,
pca9541_release_chan);
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index f2dfe0d..8e43872 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -186,7 +186,7 @@ static int pca954x_probe(struct i2c_client *client,
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
struct pca954x_platform_data *pdata = client->dev.platform_data;
- int num, force;
+ int num, force, class;
struct pca954x *data;
int ret = -ENODEV;
@@ -216,18 +216,20 @@ static int pca954x_probe(struct i2c_client *client,
/* Now create an adapter for each channel */
for (num = 0; num < chips[data->type].nchans; num++) {
force = 0; /* dynamic adap number */
+ class = 0; /* no class by default */
if (pdata) {
- if (num < pdata->num_modes)
+ if (num < pdata->num_modes) {
/* force static number */
force = pdata->modes[num].adap_id;
- else
+ class = pdata->modes[num].class;
+ } else
/* discard unconfigured channels */
break;
}
data->virt_adaps[num] =
i2c_add_mux_adapter(adap, &client->dev, client,
- force, num, pca954x_select_chan,
+ force, num, class, pca954x_select_chan,
(pdata && pdata->modes[num].deselect_on_exit)
? pca954x_deselect_mux : NULL);
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 46a6697..5f097f3 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -221,7 +221,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev)
(mux->pdata->base_bus_num + i) : 0;
mux->busses[i] = i2c_add_mux_adapter(mux->parent, &pdev->dev,
- mux, bus, i,
+ mux, bus, i, 0,
i2c_mux_pinctrl_select,
deselect);
if (!mux->busses[i]) {