linux/drivers/gpio/pca953x.c
<<
>>
Prefs
   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
  37        { "max7310", 8, },
  38        { "pca6107", 8, },
  39        { "tca6408", 8, },
  40        { "tca6416", 16, },
  41        /* NYET:  { "tca6424", 24, }, */
  42        { }
  43};
  44MODULE_DEVICE_TABLE(i2c, pca953x_id);
  45
  46struct pca953x_chip {
  47        unsigned gpio_start;
  48        uint16_t reg_output;
  49        uint16_t reg_direction;
  50
  51        struct i2c_client *client;
  52        struct gpio_chip gpio_chip;
  53};
  54
  55static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
  56{
  57        int ret;
  58
  59        if (chip->gpio_chip.ngpio <= 8)
  60                ret = i2c_smbus_write_byte_data(chip->client, reg, val);
  61        else
  62                ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
  63
  64        if (ret < 0) {
  65                dev_err(&chip->client->dev, "failed writing register\n");
  66                return ret;
  67        }
  68
  69        return 0;
  70}
  71
  72static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val)
  73{
  74        int ret;
  75
  76        if (chip->gpio_chip.ngpio <= 8)
  77                ret = i2c_smbus_read_byte_data(chip->client, reg);
  78        else
  79                ret = i2c_smbus_read_word_data(chip->client, reg << 1);
  80
  81        if (ret < 0) {
  82                dev_err(&chip->client->dev, "failed reading register\n");
  83                return ret;
  84        }
  85
  86        *val = (uint16_t)ret;
  87        return 0;
  88}
  89
  90static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
  91{
  92        struct pca953x_chip *chip;
  93        uint16_t reg_val;
  94        int ret;
  95
  96        chip = container_of(gc, struct pca953x_chip, gpio_chip);
  97
  98        reg_val = chip->reg_direction | (1u << off);
  99        ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
 100        if (ret)
 101                return ret;
 102
 103        chip->reg_direction = reg_val;
 104        return 0;
 105}
 106
 107static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 108                unsigned off, int val)
 109{
 110        struct pca953x_chip *chip;
 111        uint16_t reg_val;
 112        int ret;
 113
 114        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 115
 116        /* set output level */
 117        if (val)
 118                reg_val = chip->reg_output | (1u << off);
 119        else
 120                reg_val = chip->reg_output & ~(1u << off);
 121
 122        ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
 123        if (ret)
 124                return ret;
 125
 126        chip->reg_output = reg_val;
 127
 128        /* then direction */
 129        reg_val = chip->reg_direction & ~(1u << off);
 130        ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
 131        if (ret)
 132                return ret;
 133
 134        chip->reg_direction = reg_val;
 135        return 0;
 136}
 137
 138static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
 139{
 140        struct pca953x_chip *chip;
 141        uint16_t reg_val;
 142        int ret;
 143
 144        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 145
 146        ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
 147        if (ret < 0) {
 148                /* NOTE:  diagnostic already emitted; that's all we should
 149                 * do unless gpio_*_value_cansleep() calls become different
 150                 * from their nonsleeping siblings (and report faults).
 151                 */
 152                return 0;
 153        }
 154
 155        return (reg_val & (1u << off)) ? 1 : 0;
 156}
 157
 158static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 159{
 160        struct pca953x_chip *chip;
 161        uint16_t reg_val;
 162        int ret;
 163
 164        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 165
 166        if (val)
 167                reg_val = chip->reg_output | (1u << off);
 168        else
 169                reg_val = chip->reg_output & ~(1u << off);
 170
 171        ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
 172        if (ret)
 173                return;
 174
 175        chip->reg_output = reg_val;
 176}
 177
 178static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
 179{
 180        struct gpio_chip *gc;
 181
 182        gc = &chip->gpio_chip;
 183
 184        gc->direction_input  = pca953x_gpio_direction_input;
 185        gc->direction_output = pca953x_gpio_direction_output;
 186        gc->get = pca953x_gpio_get_value;
 187        gc->set = pca953x_gpio_set_value;
 188        gc->can_sleep = 1;
 189
 190        gc->base = chip->gpio_start;
 191        gc->ngpio = gpios;
 192        gc->label = chip->client->name;
 193        gc->dev = &chip->client->dev;
 194        gc->owner = THIS_MODULE;
 195}
 196
 197static int __devinit pca953x_probe(struct i2c_client *client,
 198                                   const struct i2c_device_id *id)
 199{
 200        struct pca953x_platform_data *pdata;
 201        struct pca953x_chip *chip;
 202        int ret;
 203
 204        pdata = client->dev.platform_data;
 205        if (pdata == NULL) {
 206                dev_dbg(&client->dev, "no platform data\n");
 207                return -EINVAL;
 208        }
 209
 210        chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
 211        if (chip == NULL)
 212                return -ENOMEM;
 213
 214        chip->client = client;
 215
 216        chip->gpio_start = pdata->gpio_base;
 217
 218        /* initialize cached registers from their original values.
 219         * we can't share this chip with another i2c master.
 220         */
 221        pca953x_setup_gpio(chip, id->driver_data);
 222
 223        ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
 224        if (ret)
 225                goto out_failed;
 226
 227        ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
 228        if (ret)
 229                goto out_failed;
 230
 231        /* set platform specific polarity inversion */
 232        ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
 233        if (ret)
 234                goto out_failed;
 235
 236
 237        ret = gpiochip_add(&chip->gpio_chip);
 238        if (ret)
 239                goto out_failed;
 240
 241        if (pdata->setup) {
 242                ret = pdata->setup(client, chip->gpio_chip.base,
 243                                chip->gpio_chip.ngpio, pdata->context);
 244                if (ret < 0)
 245                        dev_warn(&client->dev, "setup failed, %d\n", ret);
 246        }
 247
 248        i2c_set_clientdata(client, chip);
 249        return 0;
 250
 251out_failed:
 252        kfree(chip);
 253        return ret;
 254}
 255
 256static int pca953x_remove(struct i2c_client *client)
 257{
 258        struct pca953x_platform_data *pdata = client->dev.platform_data;
 259        struct pca953x_chip *chip = i2c_get_clientdata(client);
 260        int ret = 0;
 261
 262        if (pdata->teardown) {
 263                ret = pdata->teardown(client, chip->gpio_chip.base,
 264                                chip->gpio_chip.ngpio, pdata->context);
 265                if (ret < 0) {
 266                        dev_err(&client->dev, "%s failed, %d\n",
 267                                        "teardown", ret);
 268                        return ret;
 269                }
 270        }
 271
 272        ret = gpiochip_remove(&chip->gpio_chip);
 273        if (ret) {
 274                dev_err(&client->dev, "%s failed, %d\n",
 275                                "gpiochip_remove()", ret);
 276                return ret;
 277        }
 278
 279        kfree(chip);
 280        return 0;
 281}
 282
 283static struct i2c_driver pca953x_driver = {
 284        .driver = {
 285                .name   = "pca953x",
 286        },
 287        .probe          = pca953x_probe,
 288        .remove         = pca953x_remove,
 289        .id_table       = pca953x_id,
 290};
 291
 292static int __init pca953x_init(void)
 293{
 294        return i2c_add_driver(&pca953x_driver);
 295}
 296/* register after i2c postcore initcall and before
 297 * subsys initcalls that may rely on these GPIOs
 298 */
 299subsys_initcall(pca953x_init);
 300
 301static void __exit pca953x_exit(void)
 302{
 303        i2c_del_driver(&pca953x_driver);
 304}
 305module_exit(pca953x_exit);
 306
 307MODULE_AUTHOR("eric miao <eric.miao@marvell.com>");
 308MODULE_DESCRIPTION("GPIO expander driver for PCA953x");
 309MODULE_LICENSE("GPL");
 310