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