Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.28-rc2 305 lines 6.9 kB view raw
1/* 2 * pca953x.c - 4/8/16 bit I/O ports 3 * 4 * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> 5 * Copyright (C) 2007 Marvell International Ltd. 6 * 7 * Derived from drivers/i2c/chips/pca9539.c 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; version 2 of the License. 12 */ 13 14#include <linux/module.h> 15#include <linux/init.h> 16#include <linux/i2c.h> 17#include <linux/i2c/pca953x.h> 18 19#include <asm/gpio.h> 20 21#define PCA953X_INPUT 0 22#define PCA953X_OUTPUT 1 23#define PCA953X_INVERT 2 24#define PCA953X_DIRECTION 3 25 26static const struct i2c_device_id pca953x_id[] = { 27 { "pca9534", 8, }, 28 { "pca9535", 16, }, 29 { "pca9536", 4, }, 30 { "pca9537", 4, }, 31 { "pca9538", 8, }, 32 { "pca9539", 16, }, 33 { "pca9554", 8, }, 34 { "pca9555", 16, }, 35 { "pca9557", 8, }, 36 { "max7310", 8, }, 37 { } 38}; 39MODULE_DEVICE_TABLE(i2c, pca953x_id); 40 41struct pca953x_chip { 42 unsigned gpio_start; 43 uint16_t reg_output; 44 uint16_t reg_direction; 45 46 struct i2c_client *client; 47 struct gpio_chip gpio_chip; 48}; 49 50/* NOTE: we can't currently rely on fault codes to come from SMBus 51 * calls, so we map all errors to EIO here and return zero otherwise. 52 */ 53static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) 54{ 55 int ret; 56 57 if (chip->gpio_chip.ngpio <= 8) 58 ret = i2c_smbus_write_byte_data(chip->client, reg, val); 59 else 60 ret = i2c_smbus_write_word_data(chip->client, reg << 1, val); 61 62 if (ret < 0) { 63 dev_err(&chip->client->dev, "failed writing register\n"); 64 return -EIO; 65 } 66 67 return 0; 68} 69 70static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) 71{ 72 int ret; 73 74 if (chip->gpio_chip.ngpio <= 8) 75 ret = i2c_smbus_read_byte_data(chip->client, reg); 76 else 77 ret = i2c_smbus_read_word_data(chip->client, reg << 1); 78 79 if (ret < 0) { 80 dev_err(&chip->client->dev, "failed reading register\n"); 81 return -EIO; 82 } 83 84 *val = (uint16_t)ret; 85 return 0; 86} 87 88static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) 89{ 90 struct pca953x_chip *chip; 91 uint16_t reg_val; 92 int ret; 93 94 chip = container_of(gc, struct pca953x_chip, gpio_chip); 95 96 reg_val = chip->reg_direction | (1u << off); 97 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); 98 if (ret) 99 return ret; 100 101 chip->reg_direction = reg_val; 102 return 0; 103} 104 105static int pca953x_gpio_direction_output(struct gpio_chip *gc, 106 unsigned off, int val) 107{ 108 struct pca953x_chip *chip; 109 uint16_t reg_val; 110 int ret; 111 112 chip = container_of(gc, struct pca953x_chip, gpio_chip); 113 114 /* set output level */ 115 if (val) 116 reg_val = chip->reg_output | (1u << off); 117 else 118 reg_val = chip->reg_output & ~(1u << off); 119 120 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); 121 if (ret) 122 return ret; 123 124 chip->reg_output = reg_val; 125 126 /* then direction */ 127 reg_val = chip->reg_direction & ~(1u << off); 128 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); 129 if (ret) 130 return ret; 131 132 chip->reg_direction = reg_val; 133 return 0; 134} 135 136static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) 137{ 138 struct pca953x_chip *chip; 139 uint16_t reg_val; 140 int ret; 141 142 chip = container_of(gc, struct pca953x_chip, gpio_chip); 143 144 ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val); 145 if (ret < 0) { 146 /* NOTE: diagnostic already emitted; that's all we should 147 * do unless gpio_*_value_cansleep() calls become different 148 * from their nonsleeping siblings (and report faults). 149 */ 150 return 0; 151 } 152 153 return (reg_val & (1u << off)) ? 1 : 0; 154} 155 156static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) 157{ 158 struct pca953x_chip *chip; 159 uint16_t reg_val; 160 int ret; 161 162 chip = container_of(gc, struct pca953x_chip, gpio_chip); 163 164 if (val) 165 reg_val = chip->reg_output | (1u << off); 166 else 167 reg_val = chip->reg_output & ~(1u << off); 168 169 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); 170 if (ret) 171 return; 172 173 chip->reg_output = reg_val; 174} 175 176static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) 177{ 178 struct gpio_chip *gc; 179 180 gc = &chip->gpio_chip; 181 182 gc->direction_input = pca953x_gpio_direction_input; 183 gc->direction_output = pca953x_gpio_direction_output; 184 gc->get = pca953x_gpio_get_value; 185 gc->set = pca953x_gpio_set_value; 186 gc->can_sleep = 1; 187 188 gc->base = chip->gpio_start; 189 gc->ngpio = gpios; 190 gc->label = chip->client->name; 191 gc->dev = &chip->client->dev; 192 gc->owner = THIS_MODULE; 193} 194 195static int __devinit pca953x_probe(struct i2c_client *client, 196 const struct i2c_device_id *id) 197{ 198 struct pca953x_platform_data *pdata; 199 struct pca953x_chip *chip; 200 int ret; 201 202 pdata = client->dev.platform_data; 203 if (pdata == NULL) 204 return -ENODEV; 205 206 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); 207 if (chip == NULL) 208 return -ENOMEM; 209 210 chip->client = client; 211 212 chip->gpio_start = pdata->gpio_base; 213 214 /* initialize cached registers from their original values. 215 * we can't share this chip with another i2c master. 216 */ 217 pca953x_setup_gpio(chip, id->driver_data); 218 219 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); 220 if (ret) 221 goto out_failed; 222 223 ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); 224 if (ret) 225 goto out_failed; 226 227 /* set platform specific polarity inversion */ 228 ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); 229 if (ret) 230 goto out_failed; 231 232 233 ret = gpiochip_add(&chip->gpio_chip); 234 if (ret) 235 goto out_failed; 236 237 if (pdata->setup) { 238 ret = pdata->setup(client, chip->gpio_chip.base, 239 chip->gpio_chip.ngpio, pdata->context); 240 if (ret < 0) 241 dev_warn(&client->dev, "setup failed, %d\n", ret); 242 } 243 244 i2c_set_clientdata(client, chip); 245 return 0; 246 247out_failed: 248 kfree(chip); 249 return ret; 250} 251 252static int pca953x_remove(struct i2c_client *client) 253{ 254 struct pca953x_platform_data *pdata = client->dev.platform_data; 255 struct pca953x_chip *chip = i2c_get_clientdata(client); 256 int ret = 0; 257 258 if (pdata->teardown) { 259 ret = pdata->teardown(client, chip->gpio_chip.base, 260 chip->gpio_chip.ngpio, pdata->context); 261 if (ret < 0) { 262 dev_err(&client->dev, "%s failed, %d\n", 263 "teardown", ret); 264 return ret; 265 } 266 } 267 268 ret = gpiochip_remove(&chip->gpio_chip); 269 if (ret) { 270 dev_err(&client->dev, "%s failed, %d\n", 271 "gpiochip_remove()", ret); 272 return ret; 273 } 274 275 kfree(chip); 276 return 0; 277} 278 279static struct i2c_driver pca953x_driver = { 280 .driver = { 281 .name = "pca953x", 282 }, 283 .probe = pca953x_probe, 284 .remove = pca953x_remove, 285 .id_table = pca953x_id, 286}; 287 288static int __init pca953x_init(void) 289{ 290 return i2c_add_driver(&pca953x_driver); 291} 292/* register after i2c postcore initcall and before 293 * subsys initcalls that may rely on these GPIOs 294 */ 295subsys_initcall(pca953x_init); 296 297static void __exit pca953x_exit(void) 298{ 299 i2c_del_driver(&pca953x_driver); 300} 301module_exit(pca953x_exit); 302 303MODULE_AUTHOR("eric miao <eric.miao@marvell.com>"); 304MODULE_DESCRIPTION("GPIO expander driver for PCA953x"); 305MODULE_LICENSE("GPL");