diff options
| author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2012-06-14 00:58:08 -0400 |
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2012-07-12 07:40:17 -0400 |
| commit | 0c65ddd460086084079eeeb14d062c9a0c437ca0 (patch) | |
| tree | 060be558f2ec6c792cc5d9f9cd3195ec96141765 /drivers | |
| parent | da03d7400adfe56e2a54d0e38aa12704ab2a0e13 (diff) | |
gpio: pcf857x: share 8/16 bit access functions
This patch adds 8/16 bit write/read functions,
and shared gpio input/output/set/get functions.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpio/gpio-pcf857x.c | 93 |
1 files changed, 31 insertions, 62 deletions
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 2d1de9e7e9bd..076e236d0da7 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
| @@ -61,61 +61,28 @@ struct pcf857x { | |||
| 61 | struct i2c_client *client; | 61 | struct i2c_client *client; |
| 62 | struct mutex lock; /* protect 'out' */ | 62 | struct mutex lock; /* protect 'out' */ |
| 63 | unsigned out; /* software latch */ | 63 | unsigned out; /* software latch */ |
| 64 | |||
| 65 | int (*write)(struct i2c_client *client, unsigned data); | ||
| 66 | int (*read)(struct i2c_client *client); | ||
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| 66 | /*-------------------------------------------------------------------------*/ | 69 | /*-------------------------------------------------------------------------*/ |
| 67 | 70 | ||
| 68 | /* Talk to 8-bit I/O expander */ | 71 | /* Talk to 8-bit I/O expander */ |
| 69 | 72 | ||
| 70 | static int pcf857x_input8(struct gpio_chip *chip, unsigned offset) | 73 | static int i2c_write_le8(struct i2c_client *client, unsigned data) |
| 71 | { | ||
| 72 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | ||
| 73 | int status; | ||
| 74 | |||
| 75 | mutex_lock(&gpio->lock); | ||
| 76 | gpio->out |= (1 << offset); | ||
| 77 | status = i2c_smbus_write_byte(gpio->client, gpio->out); | ||
| 78 | mutex_unlock(&gpio->lock); | ||
| 79 | |||
| 80 | return status; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int pcf857x_get8(struct gpio_chip *chip, unsigned offset) | ||
| 84 | { | ||
| 85 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | ||
| 86 | s32 value; | ||
| 87 | |||
| 88 | value = i2c_smbus_read_byte(gpio->client); | ||
| 89 | return (value < 0) ? 0 : (value & (1 << offset)); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int pcf857x_output8(struct gpio_chip *chip, unsigned offset, int value) | ||
| 93 | { | 74 | { |
| 94 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 75 | return i2c_smbus_write_byte(client, data); |
| 95 | unsigned bit = 1 << offset; | ||
| 96 | int status; | ||
| 97 | |||
| 98 | mutex_lock(&gpio->lock); | ||
| 99 | if (value) | ||
| 100 | gpio->out |= bit; | ||
| 101 | else | ||
| 102 | gpio->out &= ~bit; | ||
| 103 | status = i2c_smbus_write_byte(gpio->client, gpio->out); | ||
| 104 | mutex_unlock(&gpio->lock); | ||
| 105 | |||
| 106 | return status; | ||
| 107 | } | 76 | } |
| 108 | 77 | ||
| 109 | static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value) | 78 | static int i2c_read_le8(struct i2c_client *client) |
| 110 | { | 79 | { |
| 111 | pcf857x_output8(chip, offset, value); | 80 | return (int)i2c_smbus_read_byte(client); |
| 112 | } | 81 | } |
| 113 | 82 | ||
| 114 | /*-------------------------------------------------------------------------*/ | ||
| 115 | |||
| 116 | /* Talk to 16-bit I/O expander */ | 83 | /* Talk to 16-bit I/O expander */ |
| 117 | 84 | ||
| 118 | static int i2c_write_le16(struct i2c_client *client, u16 word) | 85 | static int i2c_write_le16(struct i2c_client *client, unsigned word) |
| 119 | { | 86 | { |
| 120 | u8 buf[2] = { word & 0xff, word >> 8, }; | 87 | u8 buf[2] = { word & 0xff, word >> 8, }; |
| 121 | int status; | 88 | int status; |
| @@ -135,29 +102,31 @@ static int i2c_read_le16(struct i2c_client *client) | |||
| 135 | return (buf[1] << 8) | buf[0]; | 102 | return (buf[1] << 8) | buf[0]; |
| 136 | } | 103 | } |
| 137 | 104 | ||
| 138 | static int pcf857x_input16(struct gpio_chip *chip, unsigned offset) | 105 | /*-------------------------------------------------------------------------*/ |
| 106 | |||
| 107 | static int pcf857x_input(struct gpio_chip *chip, unsigned offset) | ||
| 139 | { | 108 | { |
| 140 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 109 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 141 | int status; | 110 | int status; |
| 142 | 111 | ||
| 143 | mutex_lock(&gpio->lock); | 112 | mutex_lock(&gpio->lock); |
| 144 | gpio->out |= (1 << offset); | 113 | gpio->out |= (1 << offset); |
| 145 | status = i2c_write_le16(gpio->client, gpio->out); | 114 | status = gpio->write(gpio->client, gpio->out); |
| 146 | mutex_unlock(&gpio->lock); | 115 | mutex_unlock(&gpio->lock); |
| 147 | 116 | ||
| 148 | return status; | 117 | return status; |
| 149 | } | 118 | } |
| 150 | 119 | ||
| 151 | static int pcf857x_get16(struct gpio_chip *chip, unsigned offset) | 120 | static int pcf857x_get(struct gpio_chip *chip, unsigned offset) |
| 152 | { | 121 | { |
| 153 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 122 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 154 | int value; | 123 | int value; |
| 155 | 124 | ||
| 156 | value = i2c_read_le16(gpio->client); | 125 | value = gpio->read(gpio->client); |
| 157 | return (value < 0) ? 0 : (value & (1 << offset)); | 126 | return (value < 0) ? 0 : (value & (1 << offset)); |
| 158 | } | 127 | } |
| 159 | 128 | ||
| 160 | static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | 129 | static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) |
| 161 | { | 130 | { |
| 162 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 131 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 163 | unsigned bit = 1 << offset; | 132 | unsigned bit = 1 << offset; |
| @@ -168,15 +137,15 @@ static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | |||
| 168 | gpio->out |= bit; | 137 | gpio->out |= bit; |
| 169 | else | 138 | else |
| 170 | gpio->out &= ~bit; | 139 | gpio->out &= ~bit; |
| 171 | status = i2c_write_le16(gpio->client, gpio->out); | 140 | status = gpio->write(gpio->client, gpio->out); |
| 172 | mutex_unlock(&gpio->lock); | 141 | mutex_unlock(&gpio->lock); |
| 173 | 142 | ||
| 174 | return status; | 143 | return status; |
| 175 | } | 144 | } |
| 176 | 145 | ||
| 177 | static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value) | 146 | static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value) |
| 178 | { | 147 | { |
| 179 | pcf857x_output16(chip, offset, value); | 148 | pcf857x_output(chip, offset, value); |
| 180 | } | 149 | } |
| 181 | 150 | ||
| 182 | /*-------------------------------------------------------------------------*/ | 151 | /*-------------------------------------------------------------------------*/ |
| @@ -200,10 +169,15 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 200 | 169 | ||
| 201 | mutex_init(&gpio->lock); | 170 | mutex_init(&gpio->lock); |
| 202 | 171 | ||
| 203 | gpio->chip.base = pdata ? pdata->gpio_base : -1; | 172 | gpio->chip.base = pdata ? pdata->gpio_base : -1; |
| 204 | gpio->chip.can_sleep = 1; | 173 | gpio->chip.can_sleep = 1; |
| 205 | gpio->chip.dev = &client->dev; | 174 | gpio->chip.dev = &client->dev; |
| 206 | gpio->chip.owner = THIS_MODULE; | 175 | gpio->chip.owner = THIS_MODULE; |
| 176 | gpio->chip.get = pcf857x_get; | ||
| 177 | gpio->chip.set = pcf857x_set; | ||
| 178 | gpio->chip.direction_input = pcf857x_input; | ||
| 179 | gpio->chip.direction_output = pcf857x_output; | ||
| 180 | gpio->chip.ngpio = id->driver_data; | ||
| 207 | 181 | ||
| 208 | /* NOTE: the OnSemi jlc1562b is also largely compatible with | 182 | /* NOTE: the OnSemi jlc1562b is also largely compatible with |
| 209 | * these parts, notably for output. It has a low-resolution | 183 | * these parts, notably for output. It has a low-resolution |
| @@ -216,12 +190,9 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 216 | * | 190 | * |
| 217 | * NOTE: we don't distinguish here between *4 and *4a parts. | 191 | * NOTE: we don't distinguish here between *4 and *4a parts. |
| 218 | */ | 192 | */ |
| 219 | gpio->chip.ngpio = id->driver_data; | ||
| 220 | if (gpio->chip.ngpio == 8) { | 193 | if (gpio->chip.ngpio == 8) { |
| 221 | gpio->chip.direction_input = pcf857x_input8; | 194 | gpio->write = i2c_write_le8; |
| 222 | gpio->chip.get = pcf857x_get8; | 195 | gpio->read = i2c_read_le8; |
| 223 | gpio->chip.direction_output = pcf857x_output8; | ||
| 224 | gpio->chip.set = pcf857x_set8; | ||
| 225 | 196 | ||
| 226 | if (!i2c_check_functionality(client->adapter, | 197 | if (!i2c_check_functionality(client->adapter, |
| 227 | I2C_FUNC_SMBUS_BYTE)) | 198 | I2C_FUNC_SMBUS_BYTE)) |
| @@ -238,10 +209,8 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 238 | * NOTE: we don't distinguish here between '75 and '75c parts. | 209 | * NOTE: we don't distinguish here between '75 and '75c parts. |
| 239 | */ | 210 | */ |
| 240 | } else if (gpio->chip.ngpio == 16) { | 211 | } else if (gpio->chip.ngpio == 16) { |
| 241 | gpio->chip.direction_input = pcf857x_input16; | 212 | gpio->write = i2c_write_le16; |
| 242 | gpio->chip.get = pcf857x_get16; | 213 | gpio->read = i2c_read_le16; |
| 243 | gpio->chip.direction_output = pcf857x_output16; | ||
| 244 | gpio->chip.set = pcf857x_set16; | ||
| 245 | 214 | ||
| 246 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | 215 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
| 247 | status = -EIO; | 216 | status = -EIO; |
