Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 83550
b: refs/heads/master
c: f5e8ff4
h: refs/heads/master
v: v3
  • Loading branch information
Guennadi Liakhovetski authored and Linus Torvalds committed Feb 6, 2008
1 parent 30aadcc commit 2e0ecaa
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 18 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: f3dc3630f687aa4664b663143f69d99d83195c54
refs/heads/master: f5e8ff483266e2913bd676d520f46b5675a18e7a
71 changes: 54 additions & 17 deletions trunk/drivers/gpio/pca953x.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* pca953x.c - 16-bit I/O port with interrupt and reset
* pca953x.c - 4/8/16 bit I/O ports
*
* Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
* Copyright (C) 2007 Marvell International Ltd.
Expand All @@ -18,13 +18,26 @@

#include <asm/gpio.h>

#define PCA953X_INPUT 0
#define PCA953X_OUTPUT 1
#define PCA953X_INVERT 2
#define PCA953X_DIRECTION 3

#define NR_PCA953X_GPIOS 16
/* This is temporary - in 2.6.26 i2c_driver_data should replace it. */
struct pca953x_desc {
char name[I2C_NAME_SIZE];
unsigned long driver_data;
};

#define PCA953X_INPUT 0
#define PCA953X_OUTPUT 2
#define PCA953X_INVERT 4
#define PCA953X_DIRECTION 6
static const struct pca953x_desc pca953x_descs[] = {
{ "pca9534", 8, },
{ "pca9535", 16, },
{ "pca9536", 4, },
{ "pca9537", 4, },
{ "pca9538", 8, },
{ "pca9539", 16, },
/* REVISIT several pca955x parts should work here too */
};

struct pca953x_chip {
unsigned gpio_start;
Expand All @@ -40,17 +53,30 @@ struct pca953x_chip {
*/
static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
{
if (i2c_smbus_write_word_data(chip->client, reg, val) < 0)
return -EIO;
int ret;

if (chip->gpio_chip.ngpio <= 8)
ret = i2c_smbus_write_byte_data(chip->client, reg, val);
else
return 0;
ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);

if (ret < 0) {
dev_err(&chip->client->dev, "failed writing register\n");
return -EIO;
}

return 0;
}

static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val)
{
int ret;

ret = i2c_smbus_read_word_data(chip->client, reg);
if (chip->gpio_chip.ngpio <= 8)
ret = i2c_smbus_read_byte_data(chip->client, reg);
else
ret = i2c_smbus_read_word_data(chip->client, reg << 1);

if (ret < 0) {
dev_err(&chip->client->dev, "failed reading register\n");
return -EIO;
Expand Down Expand Up @@ -148,7 +174,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
chip->reg_output = reg_val;
}

static int pca953x_init_gpio(struct pca953x_chip *chip)
static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
{
struct gpio_chip *gc;

Expand All @@ -160,22 +186,30 @@ static int pca953x_init_gpio(struct pca953x_chip *chip)
gc->set = pca953x_gpio_set_value;

gc->base = chip->gpio_start;
gc->ngpio = NR_PCA953X_GPIOS;
gc->label = "pca953x";

return gpiochip_add(gc);
gc->ngpio = gpios;
gc->label = chip->client->name;
}

static int __devinit pca953x_probe(struct i2c_client *client)
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
int ret;
int ret, i;
const struct pca953x_desc *id = NULL;

pdata = client->dev.platform_data;
if (pdata == NULL)
return -ENODEV;

/* this loop vanishes when we get i2c_device_id */
for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++)
if (!strcmp(pca953x_descs[i].name, client->name)) {
id = pca953x_descs + i;
break;
}
if (!id)
return -ENODEV;

chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
Expand All @@ -187,6 +221,8 @@ static int __devinit pca953x_probe(struct i2c_client *client)
/* initialize cached registers from their original values.
* we can't share this chip with another i2c master.
*/
pca953x_setup_gpio(chip, id->driver_data);

ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
if (ret)
goto out_failed;
Expand All @@ -200,7 +236,8 @@ static int __devinit pca953x_probe(struct i2c_client *client)
if (ret)
goto out_failed;

ret = pca953x_init_gpio(chip);

ret = gpiochip_add(&chip->gpio_chip);
if (ret)
goto out_failed;

Expand Down

0 comments on commit 2e0ecaa

Please sign in to comment.