linux/arch/avr32/mach-at32ap/pio.c
<<
>>
Prefs
   1/*
   2 * Atmel PIO2 Port Multiplexer support
   3 *
   4 * Copyright (C) 2004-2006 Atmel Corporation
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/clk.h>
  12#include <linux/debugfs.h>
  13#include <linux/fs.h>
  14#include <linux/platform_device.h>
  15#include <linux/irq.h>
  16
  17#include <asm/gpio.h>
  18#include <asm/io.h>
  19
  20#include <mach/portmux.h>
  21
  22#include "pio.h"
  23
  24#define MAX_NR_PIO_DEVICES              8
  25
  26struct pio_device {
  27        struct gpio_chip chip;
  28        void __iomem *regs;
  29        const struct platform_device *pdev;
  30        struct clk *clk;
  31        u32 pinmux_mask;
  32        char name[8];
  33};
  34
  35static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
  36
  37static struct pio_device *gpio_to_pio(unsigned int gpio)
  38{
  39        struct pio_device *pio;
  40        unsigned int index;
  41
  42        index = gpio >> 5;
  43        if (index >= MAX_NR_PIO_DEVICES)
  44                return NULL;
  45        pio = &pio_dev[index];
  46        if (!pio->regs)
  47                return NULL;
  48
  49        return pio;
  50}
  51
  52/* Pin multiplexing API */
  53static DEFINE_SPINLOCK(pio_lock);
  54
  55void __init at32_select_periph(unsigned int port, u32 pin_mask,
  56                               unsigned int periph, unsigned long flags)
  57{
  58        struct pio_device *pio;
  59
  60        /* assign and verify pio */
  61        pio = gpio_to_pio(port);
  62        if (unlikely(!pio)) {
  63                printk(KERN_WARNING "pio: invalid port %u\n", port);
  64                goto fail;
  65        }
  66
  67        /* Test if any of the requested pins is already muxed */
  68        spin_lock(&pio_lock);
  69        if (unlikely(pio->pinmux_mask & pin_mask)) {
  70                printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n",
  71                       pio->name, pin_mask, pio->pinmux_mask & pin_mask);
  72                spin_unlock(&pio_lock);
  73                goto fail;
  74        }
  75
  76        pio->pinmux_mask |= pin_mask;
  77
  78        /* enable pull ups */
  79        pio_writel(pio, PUER, pin_mask);
  80
  81        /* select either peripheral A or B */
  82        if (periph)
  83                pio_writel(pio, BSR, pin_mask);
  84        else
  85                pio_writel(pio, ASR, pin_mask);
  86
  87        /* enable peripheral control */
  88        pio_writel(pio, PDR, pin_mask);
  89
  90        /* Disable pull ups if not requested. */
  91        if (!(flags & AT32_GPIOF_PULLUP))
  92                pio_writel(pio, PUDR, pin_mask);
  93
  94        spin_unlock(&pio_lock);
  95
  96        return;
  97
  98fail:
  99        dump_stack();
 100}
 101
 102void __init at32_select_gpio(unsigned int pin, unsigned long flags)
 103{
 104        struct pio_device *pio;
 105        unsigned int pin_index = pin & 0x1f;
 106        u32 mask = 1 << pin_index;
 107
 108        pio = gpio_to_pio(pin);
 109        if (unlikely(!pio)) {
 110                printk("pio: invalid pin %u\n", pin);
 111                goto fail;
 112        }
 113
 114        if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
 115                printk("%s: pin %u is busy\n", pio->name, pin_index);
 116                goto fail;
 117        }
 118
 119        if (flags & AT32_GPIOF_OUTPUT) {
 120                if (flags & AT32_GPIOF_HIGH)
 121                        pio_writel(pio, SODR, mask);
 122                else
 123                        pio_writel(pio, CODR, mask);
 124                if (flags & AT32_GPIOF_MULTIDRV)
 125                        pio_writel(pio, MDER, mask);
 126                else
 127                        pio_writel(pio, MDDR, mask);
 128                pio_writel(pio, PUDR, mask);
 129                pio_writel(pio, OER, mask);
 130        } else {
 131                if (flags & AT32_GPIOF_PULLUP)
 132                        pio_writel(pio, PUER, mask);
 133                else
 134                        pio_writel(pio, PUDR, mask);
 135                if (flags & AT32_GPIOF_DEGLITCH)
 136                        pio_writel(pio, IFER, mask);
 137                else
 138                        pio_writel(pio, IFDR, mask);
 139                pio_writel(pio, ODR, mask);
 140        }
 141
 142        pio_writel(pio, PER, mask);
 143
 144        return;
 145
 146fail:
 147        dump_stack();
 148}
 149
 150/*
 151 * Undo a previous pin reservation. Will not affect the hardware
 152 * configuration.
 153 */
 154void at32_deselect_pin(unsigned int pin)
 155{
 156        struct pio_device *pio;
 157        unsigned int pin_index = pin & 0x1f;
 158
 159        pio = gpio_to_pio(pin);
 160        if (unlikely(!pio)) {
 161                printk("pio: invalid pin %u\n", pin);
 162                dump_stack();
 163                return;
 164        }
 165
 166        clear_bit(pin_index, &pio->pinmux_mask);
 167}
 168
 169/* Reserve a pin, preventing anyone else from changing its configuration. */
 170void __init at32_reserve_pin(unsigned int pin)
 171{
 172        struct pio_device *pio;
 173        unsigned int pin_index = pin & 0x1f;
 174
 175        pio = gpio_to_pio(pin);
 176        if (unlikely(!pio)) {
 177                printk("pio: invalid pin %u\n", pin);
 178                goto fail;
 179        }
 180
 181        if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
 182                printk("%s: pin %u is busy\n", pio->name, pin_index);
 183                goto fail;
 184        }
 185
 186        return;
 187
 188fail:
 189        dump_stack();
 190}
 191
 192/*--------------------------------------------------------------------------*/
 193
 194/* GPIO API */
 195
 196static int direction_input(struct gpio_chip *chip, unsigned offset)
 197{
 198        struct pio_device *pio = container_of(chip, struct pio_device, chip);
 199        u32 mask = 1 << offset;
 200
 201        if (!(pio_readl(pio, PSR) & mask))
 202                return -EINVAL;
 203
 204        pio_writel(pio, ODR, mask);
 205        return 0;
 206}
 207
 208static int gpio_get(struct gpio_chip *chip, unsigned offset)
 209{
 210        struct pio_device *pio = container_of(chip, struct pio_device, chip);
 211
 212        return (pio_readl(pio, PDSR) >> offset) & 1;
 213}
 214
 215static void gpio_set(struct gpio_chip *chip, unsigned offset, int value);
 216
 217static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
 218{
 219        struct pio_device *pio = container_of(chip, struct pio_device, chip);
 220        u32 mask = 1 << offset;
 221
 222        if (!(pio_readl(pio, PSR) & mask))
 223                return -EINVAL;
 224
 225        gpio_set(chip, offset, value);
 226        pio_writel(pio, OER, mask);
 227        return 0;
 228}
 229
 230static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 231{
 232        struct pio_device *pio = container_of(chip, struct pio_device, chip);
 233        u32 mask = 1 << offset;
 234
 235        if (value)
 236                pio_writel(pio, SODR, mask);
 237        else
 238                pio_writel(pio, CODR, mask);
 239}
 240
 241/*--------------------------------------------------------------------------*/
 242
 243/* GPIO IRQ support */
 244
 245static void gpio_irq_mask(unsigned irq)
 246{
 247        unsigned                gpio = irq_to_gpio(irq);
 248        struct pio_device       *pio = &pio_dev[gpio >> 5];
 249
 250        pio_writel(pio, IDR, 1 << (gpio & 0x1f));
 251}
 252
 253static void gpio_irq_unmask(unsigned irq)
 254{
 255        unsigned                gpio = irq_to_gpio(irq);
 256        struct pio_device       *pio = &pio_dev[gpio >> 5];
 257
 258        pio_writel(pio, IER, 1 << (gpio & 0x1f));
 259}
 260
 261static int gpio_irq_type(unsigned irq, unsigned type)
 262{
 263        if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE)
 264                return -EINVAL;
 265
 266        return 0;
 267}
 268
 269static struct irq_chip gpio_irqchip = {
 270        .name           = "gpio",
 271        .mask           = gpio_irq_mask,
 272        .unmask         = gpio_irq_unmask,
 273        .set_type       = gpio_irq_type,
 274};
 275
 276static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 277{
 278        struct pio_device       *pio = get_irq_chip_data(irq);
 279        unsigned                gpio_irq;
 280
 281        gpio_irq = (unsigned) get_irq_data(irq);
 282        for (;;) {
 283                u32             isr;
 284                struct irq_desc *d;
 285
 286                /* ack pending GPIO interrupts */
 287                isr = pio_readl(pio, ISR) & pio_readl(pio, IMR);
 288                if (!isr)
 289                        break;
 290                do {
 291                        int i;
 292
 293                        i = ffs(isr) - 1;
 294                        isr &= ~(1 << i);
 295
 296                        i += gpio_irq;
 297                        d = &irq_desc[i];
 298
 299                        d->handle_irq(i, d);
 300                } while (isr);
 301        }
 302}
 303
 304static void __init
 305gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq)
 306{
 307        unsigned        i;
 308
 309        set_irq_chip_data(irq, pio);
 310        set_irq_data(irq, (void *) gpio_irq);
 311
 312        for (i = 0; i < 32; i++, gpio_irq++) {
 313                set_irq_chip_data(gpio_irq, pio);
 314                set_irq_chip_and_handler(gpio_irq, &gpio_irqchip,
 315                                handle_simple_irq);
 316        }
 317
 318        set_irq_chained_handler(irq, gpio_irq_handler);
 319}
 320
 321/*--------------------------------------------------------------------------*/
 322
 323#ifdef CONFIG_DEBUG_FS
 324
 325#include <linux/seq_file.h>
 326
 327/*
 328 * This shows more info than the generic gpio dump code:
 329 * pullups, deglitching, open drain drive.
 330 */
 331static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip)
 332{
 333        struct pio_device *pio = container_of(chip, struct pio_device, chip);
 334        u32                     psr, osr, imr, pdsr, pusr, ifsr, mdsr;
 335        unsigned                i;
 336        u32                     mask;
 337        char                    bank;
 338
 339        psr = pio_readl(pio, PSR);
 340        osr = pio_readl(pio, OSR);
 341        imr = pio_readl(pio, IMR);
 342        pdsr = pio_readl(pio, PDSR);
 343        pusr = pio_readl(pio, PUSR);
 344        ifsr = pio_readl(pio, IFSR);
 345        mdsr = pio_readl(pio, MDSR);
 346
 347        bank = 'A' + pio->pdev->id;
 348
 349        for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
 350                const char *label;
 351
 352                label = gpiochip_is_requested(chip, i);
 353                if (!label && (imr & mask))
 354                        label = "[irq]";
 355                if (!label)
 356                        continue;
 357
 358                seq_printf(s, " gpio-%-3d P%c%-2d (%-12s) %s %s %s",
 359                        chip->base + i, bank, i,
 360                        label,
 361                        (osr & mask) ? "out" : "in ",
 362                        (mask & pdsr) ? "hi" : "lo",
 363                        (mask & pusr) ? "  " : "up");
 364                if (ifsr & mask)
 365                        seq_printf(s, " deglitch");
 366                if ((osr & mdsr) & mask)
 367                        seq_printf(s, " open-drain");
 368                if (imr & mask)
 369                        seq_printf(s, " irq-%d edge-both",
 370                                gpio_to_irq(chip->base + i));
 371                seq_printf(s, "\n");
 372        }
 373}
 374
 375#else
 376#define pio_bank_show   NULL
 377#endif
 378
 379
 380/*--------------------------------------------------------------------------*/
 381
 382static int __init pio_probe(struct platform_device *pdev)
 383{
 384        struct pio_device *pio = NULL;
 385        int irq = platform_get_irq(pdev, 0);
 386        int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32;
 387
 388        BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES);
 389        pio = &pio_dev[pdev->id];
 390        BUG_ON(!pio->regs);
 391
 392        pio->chip.label = pio->name;
 393        pio->chip.base = pdev->id * 32;
 394        pio->chip.ngpio = 32;
 395        pio->chip.dev = &pdev->dev;
 396        pio->chip.owner = THIS_MODULE;
 397
 398        pio->chip.direction_input = direction_input;
 399        pio->chip.get = gpio_get;
 400        pio->chip.direction_output = direction_output;
 401        pio->chip.set = gpio_set;
 402        pio->chip.dbg_show = pio_bank_show;
 403
 404        gpiochip_add(&pio->chip);
 405
 406        gpio_irq_setup(pio, irq, gpio_irq_base);
 407
 408        platform_set_drvdata(pdev, pio);
 409
 410        printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n",
 411               pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31);
 412
 413        return 0;
 414}
 415
 416static struct platform_driver pio_driver = {
 417        .driver         = {
 418                .name           = "pio",
 419        },
 420};
 421
 422static int __init pio_init(void)
 423{
 424        return platform_driver_probe(&pio_driver, pio_probe);
 425}
 426postcore_initcall(pio_init);
 427
 428void __init at32_init_pio(struct platform_device *pdev)
 429{
 430        struct resource *regs;
 431        struct pio_device *pio;
 432
 433        if (pdev->id > MAX_NR_PIO_DEVICES) {
 434                dev_err(&pdev->dev, "only %d PIO devices supported\n",
 435                        MAX_NR_PIO_DEVICES);
 436                return;
 437        }
 438
 439        pio = &pio_dev[pdev->id];
 440        snprintf(pio->name, sizeof(pio->name), "pio%d", pdev->id);
 441
 442        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 443        if (!regs) {
 444                dev_err(&pdev->dev, "no mmio resource defined\n");
 445                return;
 446        }
 447
 448        pio->clk = clk_get(&pdev->dev, "mck");
 449        if (IS_ERR(pio->clk))
 450                /*
 451                 * This is a fatal error, but if we continue we might
 452                 * be so lucky that we manage to initialize the
 453                 * console and display this message...
 454                 */
 455                dev_err(&pdev->dev, "no mck clock defined\n");
 456        else
 457                clk_enable(pio->clk);
 458
 459        pio->pdev = pdev;
 460        pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
 461
 462        /* start with irqs disabled and acked */
 463        pio_writel(pio, IDR, ~0UL);
 464        (void) pio_readl(pio, ISR);
 465}
 466
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.