linux/drivers/gpio/gpio-adnp.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011-2012 Avionic Design GmbH
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#include <linux/gpio/driver.h>
  10#include <linux/i2c.h>
  11#include <linux/interrupt.h>
  12#include <linux/module.h>
  13#include <linux/of_irq.h>
  14#include <linux/seq_file.h>
  15#include <linux/slab.h>
  16
  17#define GPIO_DDR(gpio) (0x00 << (gpio)->reg_shift)
  18#define GPIO_PLR(gpio) (0x01 << (gpio)->reg_shift)
  19#define GPIO_IER(gpio) (0x02 << (gpio)->reg_shift)
  20#define GPIO_ISR(gpio) (0x03 << (gpio)->reg_shift)
  21#define GPIO_PTR(gpio) (0x04 << (gpio)->reg_shift)
  22
  23struct adnp {
  24        struct i2c_client *client;
  25        struct gpio_chip gpio;
  26        unsigned int reg_shift;
  27
  28        struct mutex i2c_lock;
  29        struct mutex irq_lock;
  30
  31        u8 *irq_enable;
  32        u8 *irq_level;
  33        u8 *irq_rise;
  34        u8 *irq_fall;
  35        u8 *irq_high;
  36        u8 *irq_low;
  37};
  38
  39static int adnp_read(struct adnp *adnp, unsigned offset, uint8_t *value)
  40{
  41        int err;
  42
  43        err = i2c_smbus_read_byte_data(adnp->client, offset);
  44        if (err < 0) {
  45                dev_err(adnp->gpio.parent, "%s failed: %d\n",
  46                        "i2c_smbus_read_byte_data()", err);
  47                return err;
  48        }
  49
  50        *value = err;
  51        return 0;
  52}
  53
  54static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value)
  55{
  56        int err;
  57
  58        err = i2c_smbus_write_byte_data(adnp->client, offset, value);
  59        if (err < 0) {
  60                dev_err(adnp->gpio.parent, "%s failed: %d\n",
  61                        "i2c_smbus_write_byte_data()", err);
  62                return err;
  63        }
  64
  65        return 0;
  66}
  67
  68static int adnp_gpio_get(struct gpio_chip *chip, unsigned offset)
  69{
  70        struct adnp *adnp = gpiochip_get_data(chip);
  71        unsigned int reg = offset >> adnp->reg_shift;
  72        unsigned int pos = offset & 7;
  73        u8 value;
  74        int err;
  75
  76        err = adnp_read(adnp, GPIO_PLR(adnp) + reg, &value);
  77        if (err < 0)
  78                return err;
  79
  80        return (value & BIT(pos)) ? 1 : 0;
  81}
  82
  83static void __adnp_gpio_set(struct adnp *adnp, unsigned offset, int value)
  84{
  85        unsigned int reg = offset >> adnp->reg_shift;
  86        unsigned int pos = offset & 7;
  87        int err;
  88        u8 val;
  89
  90        err = adnp_read(adnp, GPIO_PLR(adnp) + reg, &val);
  91        if (err < 0)
  92                return;
  93
  94        if (value)
  95                val |= BIT(pos);
  96        else
  97                val &= ~BIT(pos);
  98
  99        adnp_write(adnp, GPIO_PLR(adnp) + reg, val);
 100}
 101
 102static void adnp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 103{
 104        struct adnp *adnp = gpiochip_get_data(chip);
 105
 106        mutex_lock(&adnp->i2c_lock);
 107        __adnp_gpio_set(adnp, offset, value);
 108        mutex_unlock(&adnp->i2c_lock);
 109}
 110
 111static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 112{
 113        struct adnp *adnp = gpiochip_get_data(chip);
 114        unsigned int reg = offset >> adnp->reg_shift;
 115        unsigned int pos = offset & 7;
 116        u8 value;
 117        int err;
 118
 119        mutex_lock(&adnp->i2c_lock);
 120
 121        err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
 122        if (err < 0)
 123                goto out;
 124
 125        value &= ~BIT(pos);
 126
 127        err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value);
 128        if (err < 0)
 129                goto out;
 130
 131        err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
 132        if (err < 0)
 133                goto out;
 134
 135        if (err & BIT(pos))
 136                err = -EACCES;
 137
 138        err = 0;
 139
 140out:
 141        mutex_unlock(&adnp->i2c_lock);
 142        return err;
 143}
 144
 145static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 146                                      int value)
 147{
 148        struct adnp *adnp = gpiochip_get_data(chip);
 149        unsigned int reg = offset >> adnp->reg_shift;
 150        unsigned int pos = offset & 7;
 151        int err;
 152        u8 val;
 153
 154        mutex_lock(&adnp->i2c_lock);
 155
 156        err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
 157        if (err < 0)
 158                goto out;
 159
 160        val |= BIT(pos);
 161
 162        err = adnp_write(adnp, GPIO_DDR(adnp) + reg, val);
 163        if (err < 0)
 164                goto out;
 165
 166        err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
 167        if (err < 0)
 168                goto out;
 169
 170        if (!(val & BIT(pos))) {
 171                err = -EPERM;
 172                goto out;
 173        }
 174
 175        __adnp_gpio_set(adnp, offset, value);
 176        err = 0;
 177
 178out:
 179        mutex_unlock(&adnp->i2c_lock);
 180        return err;
 181}
 182
 183static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 184{
 185        struct adnp *adnp = gpiochip_get_data(chip);
 186        unsigned int num_regs = 1 << adnp->reg_shift, i, j;
 187        int err;
 188
 189        for (i = 0; i < num_regs; i++) {
 190                u8 ddr, plr, ier, isr;
 191
 192                mutex_lock(&adnp->i2c_lock);
 193
 194                err = adnp_read(adnp, GPIO_DDR(adnp) + i, &ddr);
 195                if (err < 0) {
 196                        mutex_unlock(&adnp->i2c_lock);
 197                        return;
 198                }
 199
 200                err = adnp_read(adnp, GPIO_PLR(adnp) + i, &plr);
 201                if (err < 0) {
 202                        mutex_unlock(&adnp->i2c_lock);
 203                        return;
 204                }
 205
 206                err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
 207                if (err < 0) {
 208                        mutex_unlock(&adnp->i2c_lock);
 209                        return;
 210                }
 211
 212                err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
 213                if (err < 0) {
 214                        mutex_unlock(&adnp->i2c_lock);
 215                        return;
 216                }
 217
 218                mutex_unlock(&adnp->i2c_lock);
 219
 220                for (j = 0; j < 8; j++) {
 221                        unsigned int bit = (i << adnp->reg_shift) + j;
 222                        const char *direction = "input ";
 223                        const char *level = "low ";
 224                        const char *interrupt = "disabled";
 225                        const char *pending = "";
 226
 227                        if (ddr & BIT(j))
 228                                direction = "output";
 229
 230                        if (plr & BIT(j))
 231                                level = "high";
 232
 233                        if (ier & BIT(j))
 234                                interrupt = "enabled ";
 235
 236                        if (isr & BIT(j))
 237                                pending = "pending";
 238
 239                        seq_printf(s, "%2u: %s %s IRQ %s %s\n", bit,
 240                                   direction, level, interrupt, pending);
 241                }
 242        }
 243}
 244
 245static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios)
 246{
 247        struct gpio_chip *chip = &adnp->gpio;
 248        int err;
 249
 250        adnp->reg_shift = get_count_order(num_gpios) - 3;
 251
 252        chip->direction_input = adnp_gpio_direction_input;
 253        chip->direction_output = adnp_gpio_direction_output;
 254        chip->get = adnp_gpio_get;
 255        chip->set = adnp_gpio_set;
 256        chip->can_sleep = true;
 257
 258        if (IS_ENABLED(CONFIG_DEBUG_FS))
 259                chip->dbg_show = adnp_gpio_dbg_show;
 260
 261        chip->base = -1;
 262        chip->ngpio = num_gpios;
 263        chip->label = adnp->client->name;
 264        chip->parent = &adnp->client->dev;
 265        chip->of_node = chip->parent->of_node;
 266        chip->owner = THIS_MODULE;
 267
 268        err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp);
 269        if (err)
 270                return err;
 271
 272        return 0;
 273}
 274
 275static irqreturn_t adnp_irq(int irq, void *data)
 276{
 277        struct adnp *adnp = data;
 278        unsigned int num_regs, i;
 279
 280        num_regs = 1 << adnp->reg_shift;
 281
 282        for (i = 0; i < num_regs; i++) {
 283                unsigned int base = i << adnp->reg_shift, bit;
 284                u8 changed, level, isr, ier;
 285                unsigned long pending;
 286                int err;
 287
 288                mutex_lock(&adnp->i2c_lock);
 289
 290                err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
 291                if (err < 0) {
 292                        mutex_unlock(&adnp->i2c_lock);
 293                        continue;
 294                }
 295
 296                err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
 297                if (err < 0) {
 298                        mutex_unlock(&adnp->i2c_lock);
 299                        continue;
 300                }
 301
 302                err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
 303                if (err < 0) {
 304                        mutex_unlock(&adnp->i2c_lock);
 305                        continue;
 306                }
 307
 308                mutex_unlock(&adnp->i2c_lock);
 309
 310                /* determine pins that changed levels */
 311                changed = level ^ adnp->irq_level[i];
 312
 313                /* compute edge-triggered interrupts */
 314                pending = changed & ((adnp->irq_fall[i] & ~level) |
 315                                     (adnp->irq_rise[i] & level));
 316
 317                /* add in level-triggered interrupts */
 318                pending |= (adnp->irq_high[i] & level) |
 319                           (adnp->irq_low[i] & ~level);
 320
 321                /* mask out non-pending and disabled interrupts */
 322                pending &= isr & ier;
 323
 324                for_each_set_bit(bit, &pending, 8) {
 325                        unsigned int child_irq;
 326                        child_irq = irq_find_mapping(adnp->gpio.irqdomain,
 327                                                     base + bit);
 328                        handle_nested_irq(child_irq);
 329                }
 330        }
 331
 332        return IRQ_HANDLED;
 333}
 334
 335static void adnp_irq_mask(struct irq_data *d)
 336{
 337        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 338        struct adnp *adnp = gpiochip_get_data(gc);
 339        unsigned int reg = d->hwirq >> adnp->reg_shift;
 340        unsigned int pos = d->hwirq & 7;
 341
 342        adnp->irq_enable[reg] &= ~BIT(pos);
 343}
 344
 345static void adnp_irq_unmask(struct irq_data *d)
 346{
 347        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 348        struct adnp *adnp = gpiochip_get_data(gc);
 349        unsigned int reg = d->hwirq >> adnp->reg_shift;
 350        unsigned int pos = d->hwirq & 7;
 351
 352        adnp->irq_enable[reg] |= BIT(pos);
 353}
 354
 355static int adnp_irq_set_type(struct irq_data *d, unsigned int type)
 356{
 357        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 358        struct adnp *adnp = gpiochip_get_data(gc);
 359        unsigned int reg = d->hwirq >> adnp->reg_shift;
 360        unsigned int pos = d->hwirq & 7;
 361
 362        if (type & IRQ_TYPE_EDGE_RISING)
 363                adnp->irq_rise[reg] |= BIT(pos);
 364        else
 365                adnp->irq_rise[reg] &= ~BIT(pos);
 366
 367        if (type & IRQ_TYPE_EDGE_FALLING)
 368                adnp->irq_fall[reg] |= BIT(pos);
 369        else
 370                adnp->irq_fall[reg] &= ~BIT(pos);
 371
 372        if (type & IRQ_TYPE_LEVEL_HIGH)
 373                adnp->irq_high[reg] |= BIT(pos);
 374        else
 375                adnp->irq_high[reg] &= ~BIT(pos);
 376
 377        if (type & IRQ_TYPE_LEVEL_LOW)
 378                adnp->irq_low[reg] |= BIT(pos);
 379        else
 380                adnp->irq_low[reg] &= ~BIT(pos);
 381
 382        return 0;
 383}
 384
 385static void adnp_irq_bus_lock(struct irq_data *d)
 386{
 387        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 388        struct adnp *adnp = gpiochip_get_data(gc);
 389
 390        mutex_lock(&adnp->irq_lock);
 391}
 392
 393static void adnp_irq_bus_unlock(struct irq_data *d)
 394{
 395        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 396        struct adnp *adnp = gpiochip_get_data(gc);
 397        unsigned int num_regs = 1 << adnp->reg_shift, i;
 398
 399        mutex_lock(&adnp->i2c_lock);
 400
 401        for (i = 0; i < num_regs; i++)
 402                adnp_write(adnp, GPIO_IER(adnp) + i, adnp->irq_enable[i]);
 403
 404        mutex_unlock(&adnp->i2c_lock);
 405        mutex_unlock(&adnp->irq_lock);
 406}
 407
 408static struct irq_chip adnp_irq_chip = {
 409        .name = "gpio-adnp",
 410        .irq_mask = adnp_irq_mask,
 411        .irq_unmask = adnp_irq_unmask,
 412        .irq_set_type = adnp_irq_set_type,
 413        .irq_bus_lock = adnp_irq_bus_lock,
 414        .irq_bus_sync_unlock = adnp_irq_bus_unlock,
 415};
 416
 417static int adnp_irq_setup(struct adnp *adnp)
 418{
 419        unsigned int num_regs = 1 << adnp->reg_shift, i;
 420        struct gpio_chip *chip = &adnp->gpio;
 421        int err;
 422
 423        mutex_init(&adnp->irq_lock);
 424
 425        /*
 426         * Allocate memory to keep track of the current level and trigger
 427         * modes of the interrupts. To avoid multiple allocations, a single
 428         * large buffer is allocated and pointers are setup to point at the
 429         * corresponding offsets. For consistency, the layout of the buffer
 430         * is chosen to match the register layout of the hardware in that
 431         * each segment contains the corresponding bits for all interrupts.
 432         */
 433        adnp->irq_enable = devm_kzalloc(chip->parent, num_regs * 6,
 434                                        GFP_KERNEL);
 435        if (!adnp->irq_enable)
 436                return -ENOMEM;
 437
 438        adnp->irq_level = adnp->irq_enable + (num_regs * 1);
 439        adnp->irq_rise = adnp->irq_enable + (num_regs * 2);
 440        adnp->irq_fall = adnp->irq_enable + (num_regs * 3);
 441        adnp->irq_high = adnp->irq_enable + (num_regs * 4);
 442        adnp->irq_low = adnp->irq_enable + (num_regs * 5);
 443
 444        for (i = 0; i < num_regs; i++) {
 445                /*
 446                 * Read the initial level of all pins to allow the emulation
 447                 * of edge triggered interrupts.
 448                 */
 449                err = adnp_read(adnp, GPIO_PLR(adnp) + i, &adnp->irq_level[i]);
 450                if (err < 0)
 451                        return err;
 452
 453                /* disable all interrupts */
 454                err = adnp_write(adnp, GPIO_IER(adnp) + i, 0);
 455                if (err < 0)
 456                        return err;
 457
 458                adnp->irq_enable[i] = 0x00;
 459        }
 460
 461        err = devm_request_threaded_irq(chip->parent, adnp->client->irq,
 462                                        NULL, adnp_irq,
 463                                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 464                                        dev_name(chip->parent), adnp);
 465        if (err != 0) {
 466                dev_err(chip->parent, "can't request IRQ#%d: %d\n",
 467                        adnp->client->irq, err);
 468                return err;
 469        }
 470
 471        err = gpiochip_irqchip_add(chip,
 472                                   &adnp_irq_chip,
 473                                   0,
 474                                   handle_simple_irq,
 475                                   IRQ_TYPE_NONE);
 476        if (err) {
 477                dev_err(chip->parent,
 478                        "could not connect irqchip to gpiochip\n");
 479                return err;
 480        }
 481
 482        return 0;
 483}
 484
 485static int adnp_i2c_probe(struct i2c_client *client,
 486                                    const struct i2c_device_id *id)
 487{
 488        struct device_node *np = client->dev.of_node;
 489        struct adnp *adnp;
 490        u32 num_gpios;
 491        int err;
 492
 493        err = of_property_read_u32(np, "nr-gpios", &num_gpios);
 494        if (err < 0)
 495                return err;
 496
 497        client->irq = irq_of_parse_and_map(np, 0);
 498        if (!client->irq)
 499                return -EPROBE_DEFER;
 500
 501        adnp = devm_kzalloc(&client->dev, sizeof(*adnp), GFP_KERNEL);
 502        if (!adnp)
 503                return -ENOMEM;
 504
 505        mutex_init(&adnp->i2c_lock);
 506        adnp->client = client;
 507
 508        err = adnp_gpio_setup(adnp, num_gpios);
 509        if (err)
 510                return err;
 511
 512        if (of_find_property(np, "interrupt-controller", NULL)) {
 513                err = adnp_irq_setup(adnp);
 514                if (err)
 515                        return err;
 516        }
 517
 518        i2c_set_clientdata(client, adnp);
 519
 520        return 0;
 521}
 522
 523static const struct i2c_device_id adnp_i2c_id[] = {
 524        { "gpio-adnp" },
 525        { },
 526};
 527MODULE_DEVICE_TABLE(i2c, adnp_i2c_id);
 528
 529static const struct of_device_id adnp_of_match[] = {
 530        { .compatible = "ad,gpio-adnp", },
 531        { },
 532};
 533MODULE_DEVICE_TABLE(of, adnp_of_match);
 534
 535static struct i2c_driver adnp_i2c_driver = {
 536        .driver = {
 537                .name = "gpio-adnp",
 538                .of_match_table = adnp_of_match,
 539        },
 540        .probe = adnp_i2c_probe,
 541        .id_table = adnp_i2c_id,
 542};
 543module_i2c_driver(adnp_i2c_driver);
 544
 545MODULE_DESCRIPTION("Avionic Design N-bit GPIO expander");
 546MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
 547MODULE_LICENSE("GPL");
 548