Commit d92c7962470b699ef7a697524b9a679846e9e15b

Authored by Cyril Chemparathy
Committed by Kevin Hilman
1 parent 4d1e78480c

Davinci: tnetv107x initial gpio support

This patch adds support for the tnetv107x gpio controller.

Key differences between davinci and tnetv107x controllers:
 - register map - davinci's controller is organized into banks of 32 gpios,
   tnetv107x has a single space with arrays of registers for in, out,
   direction, etc.
 - davinci's controller has separate set/clear registers for output, tnetv107x
   has a single direct mapped register.

This patch does not yet add gpio irq support on this controller.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>

Showing 3 changed files with 221 additions and 7 deletions Side-by-side Diff

arch/arm/mach-davinci/Makefile
... ... @@ -17,6 +17,7 @@
17 17 obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
18 18 obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
19 19 obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
  20 +obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
20 21  
21 22 obj-$(CONFIG_AINTC) += irq.o
22 23 obj-$(CONFIG_CP_INTC) += cp_intc.o
arch/arm/mach-davinci/gpio-tnetv107x.c
  1 +/*
  2 + * Texas Instruments TNETV107X GPIO Controller
  3 + *
  4 + * Copyright (C) 2010 Texas Instruments
  5 + *
  6 + * This program is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU General Public License as
  8 + * published by the Free Software Foundation version 2.
  9 + *
  10 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  11 + * kind, whether express or implied; without even the implied warranty
  12 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 + * GNU General Public License for more details.
  14 + */
  15 +#include <linux/kernel.h>
  16 +#include <linux/init.h>
  17 +#include <linux/gpio.h>
  18 +
  19 +#include <mach/common.h>
  20 +#include <mach/tnetv107x.h>
  21 +
  22 +struct tnetv107x_gpio_regs {
  23 + u32 idver;
  24 + u32 data_in[3];
  25 + u32 data_out[3];
  26 + u32 direction[3];
  27 + u32 enable[3];
  28 +};
  29 +
  30 +#define gpio_reg_index(gpio) ((gpio) >> 5)
  31 +#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f)
  32 +
  33 +#define gpio_reg_rmw(reg, mask, val) \
  34 + __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg))
  35 +
  36 +#define gpio_reg_set_bit(reg, gpio) \
  37 + gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio))
  38 +
  39 +#define gpio_reg_clear_bit(reg, gpio) \
  40 + gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0)
  41 +
  42 +#define gpio_reg_get_bit(reg, gpio) \
  43 + (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio))
  44 +
  45 +#define chip2controller(chip) \
  46 + container_of(chip, struct davinci_gpio_controller, chip)
  47 +
  48 +#define TNETV107X_GPIO_CTLRS DIV_ROUND_UP(TNETV107X_N_GPIO, 32)
  49 +
  50 +static struct davinci_gpio_controller chips[TNETV107X_GPIO_CTLRS];
  51 +
  52 +static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset)
  53 +{
  54 + struct davinci_gpio_controller *ctlr = chip2controller(chip);
  55 + struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
  56 + unsigned gpio = chip->base + offset;
  57 + unsigned long flags;
  58 +
  59 + spin_lock_irqsave(&ctlr->lock, flags);
  60 +
  61 + gpio_reg_set_bit(&regs->enable, gpio);
  62 +
  63 + spin_unlock_irqrestore(&ctlr->lock, flags);
  64 +
  65 + return 0;
  66 +}
  67 +
  68 +static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset)
  69 +{
  70 + struct davinci_gpio_controller *ctlr = chip2controller(chip);
  71 + struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
  72 + unsigned gpio = chip->base + offset;
  73 + unsigned long flags;
  74 +
  75 + spin_lock_irqsave(&ctlr->lock, flags);
  76 +
  77 + gpio_reg_clear_bit(&regs->enable, gpio);
  78 +
  79 + spin_unlock_irqrestore(&ctlr->lock, flags);
  80 +}
  81 +
  82 +static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
  83 +{
  84 + struct davinci_gpio_controller *ctlr = chip2controller(chip);
  85 + struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
  86 + unsigned gpio = chip->base + offset;
  87 + unsigned long flags;
  88 +
  89 + spin_lock_irqsave(&ctlr->lock, flags);
  90 +
  91 + gpio_reg_set_bit(&regs->direction, gpio);
  92 +
  93 + spin_unlock_irqrestore(&ctlr->lock, flags);
  94 +
  95 + return 0;
  96 +}
  97 +
  98 +static int tnetv107x_gpio_dir_out(struct gpio_chip *chip,
  99 + unsigned offset, int value)
  100 +{
  101 + struct davinci_gpio_controller *ctlr = chip2controller(chip);
  102 + struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
  103 + unsigned gpio = chip->base + offset;
  104 + unsigned long flags;
  105 +
  106 + spin_lock_irqsave(&ctlr->lock, flags);
  107 +
  108 + if (value)
  109 + gpio_reg_set_bit(&regs->data_out, gpio);
  110 + else
  111 + gpio_reg_clear_bit(&regs->data_out, gpio);
  112 +
  113 + gpio_reg_clear_bit(&regs->direction, gpio);
  114 +
  115 + spin_unlock_irqrestore(&ctlr->lock, flags);
  116 +
  117 + return 0;
  118 +}
  119 +
  120 +static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset)
  121 +{
  122 + struct davinci_gpio_controller *ctlr = chip2controller(chip);
  123 + struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
  124 + unsigned gpio = chip->base + offset;
  125 + int ret;
  126 +
  127 + ret = gpio_reg_get_bit(&regs->data_in, gpio);
  128 +
  129 + return ret ? 1 : 0;
  130 +}
  131 +
  132 +static void tnetv107x_gpio_set(struct gpio_chip *chip,
  133 + unsigned offset, int value)
  134 +{
  135 + struct davinci_gpio_controller *ctlr = chip2controller(chip);
  136 + struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
  137 + unsigned gpio = chip->base + offset;
  138 + unsigned long flags;
  139 +
  140 + spin_lock_irqsave(&ctlr->lock, flags);
  141 +
  142 + if (value)
  143 + gpio_reg_set_bit(&regs->data_out, gpio);
  144 + else
  145 + gpio_reg_clear_bit(&regs->data_out, gpio);
  146 +
  147 + spin_unlock_irqrestore(&ctlr->lock, flags);
  148 +}
  149 +
  150 +static int __init tnetv107x_gpio_setup(void)
  151 +{
  152 + int i, base;
  153 + unsigned ngpio;
  154 + struct davinci_soc_info *soc_info = &davinci_soc_info;
  155 + struct tnetv107x_gpio_regs *regs;
  156 + struct davinci_gpio_controller *ctlr;
  157 +
  158 + if (soc_info->gpio_type != GPIO_TYPE_TNETV107X)
  159 + return 0;
  160 +
  161 + ngpio = soc_info->gpio_num;
  162 + if (ngpio == 0) {
  163 + pr_err("GPIO setup: how many GPIOs?\n");
  164 + return -EINVAL;
  165 + }
  166 +
  167 + if (WARN_ON(TNETV107X_N_GPIO < ngpio))
  168 + ngpio = TNETV107X_N_GPIO;
  169 +
  170 + regs = ioremap(soc_info->gpio_base, SZ_4K);
  171 + if (WARN_ON(!regs))
  172 + return -EINVAL;
  173 +
  174 + for (i = 0, base = 0; base < ngpio; i++, base += 32) {
  175 + ctlr = &chips[i];
  176 +
  177 + ctlr->chip.label = "tnetv107x";
  178 + ctlr->chip.can_sleep = 0;
  179 + ctlr->chip.base = base;
  180 + ctlr->chip.ngpio = ngpio - base;
  181 + if (ctlr->chip.ngpio > 32)
  182 + ctlr->chip.ngpio = 32;
  183 +
  184 + ctlr->chip.request = tnetv107x_gpio_request;
  185 + ctlr->chip.free = tnetv107x_gpio_free;
  186 + ctlr->chip.direction_input = tnetv107x_gpio_dir_in;
  187 + ctlr->chip.get = tnetv107x_gpio_get;
  188 + ctlr->chip.direction_output = tnetv107x_gpio_dir_out;
  189 + ctlr->chip.set = tnetv107x_gpio_set;
  190 +
  191 + spin_lock_init(&ctlr->lock);
  192 +
  193 + ctlr->regs = regs;
  194 + ctlr->set_data = &regs->data_out[i];
  195 + ctlr->clr_data = &regs->data_out[i];
  196 + ctlr->in_data = &regs->data_in[i];
  197 +
  198 + gpiochip_add(&ctlr->chip);
  199 + }
  200 +
  201 + soc_info->gpio_ctlrs = chips;
  202 + soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
  203 + return 0;
  204 +}
  205 +pure_initcall(tnetv107x_gpio_setup);
arch/arm/mach-davinci/include/mach/gpio.h
... ... @@ -25,6 +25,7 @@
25 25  
26 26 enum davinci_gpio_type {
27 27 GPIO_TYPE_DAVINCI = 0,
  28 + GPIO_TYPE_TNETV107X,
28 29 };
29 30  
30 31 /*
31 32  
... ... @@ -87,9 +88,13 @@
87 88 return 1 << (gpio % 32);
88 89 }
89 90  
90   -/* The get/set/clear functions will inline when called with constant
  91 +/*
  92 + * The get/set/clear functions will inline when called with constant
91 93 * parameters referencing built-in GPIOs, for low-overhead bitbanging.
92 94 *
  95 + * gpio_set_value() will inline only on traditional Davinci style controllers
  96 + * with distinct set/clear registers.
  97 + *
93 98 * Otherwise, calls with variable parameters or referencing external
94 99 * GPIOs (e.g. on GPIO expander chips) use outlined functions.
95 100 */
... ... @@ -100,12 +105,15 @@
100 105 u32 mask;
101 106  
102 107 ctlr = __gpio_to_controller(gpio);
103   - mask = __gpio_mask(gpio);
104   - if (value)
105   - __raw_writel(mask, ctlr->set_data);
106   - else
107   - __raw_writel(mask, ctlr->clr_data);
108   - return;
  108 +
  109 + if (ctlr->set_data != ctlr->clr_data) {
  110 + mask = __gpio_mask(gpio);
  111 + if (value)
  112 + __raw_writel(mask, ctlr->set_data);
  113 + else
  114 + __raw_writel(mask, ctlr->clr_data);
  115 + return;
  116 + }
109 117 }
110 118  
111 119 __gpio_set_value(gpio, value);