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.31-rc4 379 lines 8.4 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#ifdef CONFIG_OF_GPIO 19#include <linux/of_platform.h> 20#include <linux/of_gpio.h> 21#endif 22 23#include <asm/gpio.h> 24 25#define PCA953X_INPUT 0 26#define PCA953X_OUTPUT 1 27#define PCA953X_INVERT 2 28#define PCA953X_DIRECTION 3 29 30static const struct i2c_device_id pca953x_id[] = { 31 { "pca9534", 8, }, 32 { "pca9535", 16, }, 33 { "pca9536", 4, }, 34 { "pca9537", 4, }, 35 { "pca9538", 8, }, 36 { "pca9539", 16, }, 37 { "pca9554", 8, }, 38 { "pca9555", 16, }, 39 { "pca9556", 8, }, 40 { "pca9557", 8, }, 41 42 { "max7310", 8, }, 43 { "pca6107", 8, }, 44 { "tca6408", 8, }, 45 { "tca6416", 16, }, 46 /* NYET: { "tca6424", 24, }, */ 47 { } 48}; 49MODULE_DEVICE_TABLE(i2c, pca953x_id); 50 51struct pca953x_chip { 52 unsigned gpio_start; 53 uint16_t reg_output; 54 uint16_t reg_direction; 55 56 struct i2c_client *client; 57 struct pca953x_platform_data *dyn_pdata; 58 struct gpio_chip gpio_chip; 59 char **names; 60}; 61 62static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) 63{ 64 int ret; 65 66 if (chip->gpio_chip.ngpio <= 8) 67 ret = i2c_smbus_write_byte_data(chip->client, reg, val); 68 else 69 ret = i2c_smbus_write_word_data(chip->client, reg << 1, val); 70 71 if (ret < 0) { 72 dev_err(&chip->client->dev, "failed writing register\n"); 73 return ret; 74 } 75 76 return 0; 77} 78 79static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) 80{ 81 int ret; 82 83 if (chip->gpio_chip.ngpio <= 8) 84 ret = i2c_smbus_read_byte_data(chip->client, reg); 85 else 86 ret = i2c_smbus_read_word_data(chip->client, reg << 1); 87 88 if (ret < 0) { 89 dev_err(&chip->client->dev, "failed reading register\n"); 90 return ret; 91 } 92 93 *val = (uint16_t)ret; 94 return 0; 95} 96 97static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) 98{ 99 struct pca953x_chip *chip; 100 uint16_t reg_val; 101 int ret; 102 103 chip = container_of(gc, struct pca953x_chip, gpio_chip); 104 105 reg_val = chip->reg_direction | (1u << off); 106 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); 107 if (ret) 108 return ret; 109 110 chip->reg_direction = reg_val; 111 return 0; 112} 113 114static int pca953x_gpio_direction_output(struct gpio_chip *gc, 115 unsigned off, int val) 116{ 117 struct pca953x_chip *chip; 118 uint16_t reg_val; 119 int ret; 120 121 chip = container_of(gc, struct pca953x_chip, gpio_chip); 122 123 /* set output level */ 124 if (val) 125 reg_val = chip->reg_output | (1u << off); 126 else 127 reg_val = chip->reg_output & ~(1u << off); 128 129 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); 130 if (ret) 131 return ret; 132 133 chip->reg_output = reg_val; 134 135 /* then direction */ 136 reg_val = chip->reg_direction & ~(1u << off); 137 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); 138 if (ret) 139 return ret; 140 141 chip->reg_direction = reg_val; 142 return 0; 143} 144 145static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) 146{ 147 struct pca953x_chip *chip; 148 uint16_t reg_val; 149 int ret; 150 151 chip = container_of(gc, struct pca953x_chip, gpio_chip); 152 153 ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val); 154 if (ret < 0) { 155 /* NOTE: diagnostic already emitted; that's all we should 156 * do unless gpio_*_value_cansleep() calls become different 157 * from their nonsleeping siblings (and report faults). 158 */ 159 return 0; 160 } 161 162 return (reg_val & (1u << off)) ? 1 : 0; 163} 164 165static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) 166{ 167 struct pca953x_chip *chip; 168 uint16_t reg_val; 169 int ret; 170 171 chip = container_of(gc, struct pca953x_chip, gpio_chip); 172 173 if (val) 174 reg_val = chip->reg_output | (1u << off); 175 else 176 reg_val = chip->reg_output & ~(1u << off); 177 178 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); 179 if (ret) 180 return; 181 182 chip->reg_output = reg_val; 183} 184 185static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) 186{ 187 struct gpio_chip *gc; 188 189 gc = &chip->gpio_chip; 190 191 gc->direction_input = pca953x_gpio_direction_input; 192 gc->direction_output = pca953x_gpio_direction_output; 193 gc->get = pca953x_gpio_get_value; 194 gc->set = pca953x_gpio_set_value; 195 gc->can_sleep = 1; 196 197 gc->base = chip->gpio_start; 198 gc->ngpio = gpios; 199 gc->label = chip->client->name; 200 gc->dev = &chip->client->dev; 201 gc->owner = THIS_MODULE; 202 gc->names = chip->names; 203} 204 205/* 206 * Handlers for alternative sources of platform_data 207 */ 208#ifdef CONFIG_OF_GPIO 209/* 210 * Translate OpenFirmware node properties into platform_data 211 */ 212static struct pca953x_platform_data * 213pca953x_get_alt_pdata(struct i2c_client *client) 214{ 215 struct pca953x_platform_data *pdata; 216 struct device_node *node; 217 const uint16_t *val; 218 219 node = dev_archdata_get_node(&client->dev.archdata); 220 if (node == NULL) 221 return NULL; 222 223 pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL); 224 if (pdata == NULL) { 225 dev_err(&client->dev, "Unable to allocate platform_data\n"); 226 return NULL; 227 } 228 229 pdata->gpio_base = -1; 230 val = of_get_property(node, "linux,gpio-base", NULL); 231 if (val) { 232 if (*val < 0) 233 dev_warn(&client->dev, 234 "invalid gpio-base in device tree\n"); 235 else 236 pdata->gpio_base = *val; 237 } 238 239 val = of_get_property(node, "polarity", NULL); 240 if (val) 241 pdata->invert = *val; 242 243 return pdata; 244} 245#else 246static struct pca953x_platform_data * 247pca953x_get_alt_pdata(struct i2c_client *client) 248{ 249 return NULL; 250} 251#endif 252 253static int __devinit pca953x_probe(struct i2c_client *client, 254 const struct i2c_device_id *id) 255{ 256 struct pca953x_platform_data *pdata; 257 struct pca953x_chip *chip; 258 int ret; 259 260 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); 261 if (chip == NULL) 262 return -ENOMEM; 263 264 pdata = client->dev.platform_data; 265 if (pdata == NULL) { 266 pdata = pca953x_get_alt_pdata(client); 267 /* 268 * Unlike normal platform_data, this is allocated 269 * dynamically and must be freed in the driver 270 */ 271 chip->dyn_pdata = pdata; 272 } 273 274 if (pdata == NULL) { 275 dev_dbg(&client->dev, "no platform data\n"); 276 ret = -EINVAL; 277 goto out_failed; 278 } 279 280 chip->client = client; 281 282 chip->gpio_start = pdata->gpio_base; 283 284 chip->names = pdata->names; 285 286 /* initialize cached registers from their original values. 287 * we can't share this chip with another i2c master. 288 */ 289 pca953x_setup_gpio(chip, id->driver_data); 290 291 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); 292 if (ret) 293 goto out_failed; 294 295 ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); 296 if (ret) 297 goto out_failed; 298 299 /* set platform specific polarity inversion */ 300 ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); 301 if (ret) 302 goto out_failed; 303 304 305 ret = gpiochip_add(&chip->gpio_chip); 306 if (ret) 307 goto out_failed; 308 309 if (pdata->setup) { 310 ret = pdata->setup(client, chip->gpio_chip.base, 311 chip->gpio_chip.ngpio, pdata->context); 312 if (ret < 0) 313 dev_warn(&client->dev, "setup failed, %d\n", ret); 314 } 315 316 i2c_set_clientdata(client, chip); 317 return 0; 318 319out_failed: 320 kfree(chip->dyn_pdata); 321 kfree(chip); 322 return ret; 323} 324 325static int pca953x_remove(struct i2c_client *client) 326{ 327 struct pca953x_platform_data *pdata = client->dev.platform_data; 328 struct pca953x_chip *chip = i2c_get_clientdata(client); 329 int ret = 0; 330 331 if (pdata->teardown) { 332 ret = pdata->teardown(client, chip->gpio_chip.base, 333 chip->gpio_chip.ngpio, pdata->context); 334 if (ret < 0) { 335 dev_err(&client->dev, "%s failed, %d\n", 336 "teardown", ret); 337 return ret; 338 } 339 } 340 341 ret = gpiochip_remove(&chip->gpio_chip); 342 if (ret) { 343 dev_err(&client->dev, "%s failed, %d\n", 344 "gpiochip_remove()", ret); 345 return ret; 346 } 347 348 kfree(chip->dyn_pdata); 349 kfree(chip); 350 return 0; 351} 352 353static struct i2c_driver pca953x_driver = { 354 .driver = { 355 .name = "pca953x", 356 }, 357 .probe = pca953x_probe, 358 .remove = pca953x_remove, 359 .id_table = pca953x_id, 360}; 361 362static int __init pca953x_init(void) 363{ 364 return i2c_add_driver(&pca953x_driver); 365} 366/* register after i2c postcore initcall and before 367 * subsys initcalls that may rely on these GPIOs 368 */ 369subsys_initcall(pca953x_init); 370 371static void __exit pca953x_exit(void) 372{ 373 i2c_del_driver(&pca953x_driver); 374} 375module_exit(pca953x_exit); 376 377MODULE_AUTHOR("eric miao <eric.miao@marvell.com>"); 378MODULE_DESCRIPTION("GPIO expander driver for PCA953x"); 379MODULE_LICENSE("GPL");