Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 331550
b: refs/heads/master
c: e7ee514
h: refs/heads/master
v: v3
  • Loading branch information
Jean Delvare authored and Jean Delvare committed Oct 5, 2012
1 parent de7327c commit 911aacd
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2614a8594152cad49047ed02255a3d9fbbbea8dd
refs/heads/master: e7ee51405835cac72e7b6e0ff26dba608cf186cc
38 changes: 32 additions & 6 deletions trunk/drivers/i2c/muxes/i2c-mux-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ 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)
{
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)
Expand All @@ -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;
Expand All @@ -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",
Expand All @@ -79,6 +104,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)

mux->parent = parent;
mux->data = *pdata;
mux->gpio_base = gpio_base;
mux->adap = devm_kzalloc(&pdev->dev,
sizeof(*mux->adap) * pdata->n_values,
GFP_KERNEL);
Expand All @@ -96,10 +122,10 @@ 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));
}

Expand Down Expand Up @@ -130,7 +156,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
i = pdata->n_gpios;
err_request_gpio:
for (; i > 0; i--)
gpio_free(pdata->gpios[i - 1]);
gpio_free(gpio_base + pdata->gpios[i - 1]);
alloc_failed:
i2c_put_adapter(parent);

Expand All @@ -146,7 +172,7 @@ 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);
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/i2c-mux-gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
* 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
Expand All @@ -32,6 +34,7 @@ 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;
Expand Down

0 comments on commit 911aacd

Please sign in to comment.