linux/drivers/gpio/gpio-vt8500.c
<<
>>
Prefs
   1/* drivers/gpio/gpio-vt8500.c
   2 *
   3 * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
   4 * Based on arch/arm/mach-vt8500/gpio.c:
   5 * - Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License version 2, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/err.h>
  20#include <linux/io.h>
  21#include <linux/gpio.h>
  22#include <linux/platform_device.h>
  23#include <linux/bitops.h>
  24#include <linux/of.h>
  25#include <linux/of_address.h>
  26#include <linux/of_irq.h>
  27#include <linux/of_device.h>
  28
  29/*
  30        We handle GPIOs by bank, each bank containing up to 32 GPIOs covered
  31        by one set of registers (although not all may be valid).
  32
  33        Because different SoC's have different register offsets, we pass the
  34        register offsets as data in vt8500_gpio_dt_ids[].
  35
  36        A value of NO_REG is used to indicate that this register is not
  37        supported. Only used for ->en at the moment.
  38*/
  39
  40#define NO_REG  0xFFFF
  41
  42/*
  43 * struct vt8500_gpio_bank_regoffsets
  44 * @en: offset to enable register of the bank
  45 * @dir: offset to direction register of the bank
  46 * @data_out: offset to the data out register of the bank
  47 * @data_in: offset to the data in register of the bank
  48 * @ngpio: highest valid pin in this bank
  49 */
  50
  51struct vt8500_gpio_bank_regoffsets {
  52        unsigned int    en;
  53        unsigned int    dir;
  54        unsigned int    data_out;
  55        unsigned int    data_in;
  56        unsigned char   ngpio;
  57};
  58
  59struct vt8500_gpio_data {
  60        unsigned int                            num_banks;
  61        struct vt8500_gpio_bank_regoffsets      banks[];
  62};
  63
  64#define VT8500_BANK(__en, __dir, __out, __in, __ngpio)          \
  65{                                                               \
  66        .en = __en,                                             \
  67        .dir = __dir,                                           \
  68        .data_out = __out,                                      \
  69        .data_in = __in,                                        \
  70        .ngpio = __ngpio,                                       \
  71}
  72
  73static struct vt8500_gpio_data vt8500_data = {
  74        .num_banks      = 7,
  75        .banks  = {
  76                VT8500_BANK(0x00, 0x20, 0x40, 0x60, 26),
  77                VT8500_BANK(0x04, 0x24, 0x44, 0x64, 28),
  78                VT8500_BANK(0x08, 0x28, 0x48, 0x68, 31),
  79                VT8500_BANK(0x0C, 0x2C, 0x4C, 0x6C, 19),
  80                VT8500_BANK(0x10, 0x30, 0x50, 0x70, 19),
  81                VT8500_BANK(0x14, 0x34, 0x54, 0x74, 23),
  82                VT8500_BANK(NO_REG, 0x3C, 0x5C, 0x7C, 9),
  83        },
  84};
  85
  86static struct vt8500_gpio_data wm8505_data = {
  87        .num_banks      = 10,
  88        .banks  = {
  89                VT8500_BANK(0x40, 0x68, 0x90, 0xB8, 8),
  90                VT8500_BANK(0x44, 0x6C, 0x94, 0xBC, 32),
  91                VT8500_BANK(0x48, 0x70, 0x98, 0xC0, 6),
  92                VT8500_BANK(0x4C, 0x74, 0x9C, 0xC4, 16),
  93                VT8500_BANK(0x50, 0x78, 0xA0, 0xC8, 25),
  94                VT8500_BANK(0x54, 0x7C, 0xA4, 0xCC, 5),
  95                VT8500_BANK(0x58, 0x80, 0xA8, 0xD0, 5),
  96                VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12),
  97                VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16),
  98                VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22),
  99        },
 100};
 101
 102/*
 103 * No information about which bits are valid so we just make
 104 * them all available until its figured out.
 105 */
 106static struct vt8500_gpio_data wm8650_data = {
 107        .num_banks      = 9,
 108        .banks  = {
 109                VT8500_BANK(0x40, 0x80, 0xC0, 0x00, 32),
 110                VT8500_BANK(0x44, 0x84, 0xC4, 0x04, 32),
 111                VT8500_BANK(0x48, 0x88, 0xC8, 0x08, 32),
 112                VT8500_BANK(0x4C, 0x8C, 0xCC, 0x0C, 32),
 113                VT8500_BANK(0x50, 0x90, 0xD0, 0x10, 32),
 114                VT8500_BANK(0x54, 0x94, 0xD4, 0x14, 32),
 115                VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32),
 116                VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32),
 117                VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32),
 118        },
 119};
 120
 121struct vt8500_gpio_chip {
 122        struct gpio_chip                chip;
 123
 124        const struct vt8500_gpio_bank_regoffsets *regs;
 125        void __iomem    *base;
 126};
 127
 128
 129#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
 130
 131static int vt8500_gpio_request(struct gpio_chip *chip, unsigned offset)
 132{
 133        u32 val;
 134        struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
 135
 136        if (vt8500_chip->regs->en == NO_REG)
 137                return 0;
 138
 139        val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en);
 140        val |= BIT(offset);
 141        writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en);
 142
 143        return 0;
 144}
 145
 146static void vt8500_gpio_free(struct gpio_chip *chip, unsigned offset)
 147{
 148        struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
 149        u32 val;
 150
 151        if (vt8500_chip->regs->en == NO_REG)
 152                return;
 153
 154        val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en);
 155        val &= ~BIT(offset);
 156        writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en);
 157}
 158
 159static int vt8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 160{
 161        struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
 162
 163        u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir);
 164        val &= ~BIT(offset);
 165        writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir);
 166
 167        return 0;
 168}
 169
 170static int vt8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 171                                                                int value)
 172{
 173        struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
 174
 175        u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir);
 176        val |= BIT(offset);
 177        writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir);
 178
 179        if (value) {
 180                val = readl_relaxed(vt8500_chip->base +
 181                                                vt8500_chip->regs->data_out);
 182                val |= BIT(offset);
 183                writel_relaxed(val, vt8500_chip->base +
 184                                                vt8500_chip->regs->data_out);
 185        }
 186        return 0;
 187}
 188
 189static int vt8500_gpio_get_value(struct gpio_chip *chip, unsigned offset)
 190{
 191        struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
 192
 193        return (readl_relaxed(vt8500_chip->base + vt8500_chip->regs->data_in) >>
 194                                                                offset) & 1;
 195}
 196
 197static void vt8500_gpio_set_value(struct gpio_chip *chip, unsigned offset,
 198                                                                int value)
 199{
 200        struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
 201
 202        u32 val = readl_relaxed(vt8500_chip->base +
 203                                                vt8500_chip->regs->data_out);
 204        if (value)
 205                val |= BIT(offset);
 206        else
 207                val &= ~BIT(offset);
 208
 209        writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->data_out);
 210}
 211
 212static int vt8500_of_xlate(struct gpio_chip *gc,
 213                            const struct of_phandle_args *gpiospec, u32 *flags)
 214{
 215        /* bank if specificed in gpiospec->args[0] */
 216        if (flags)
 217                *flags = gpiospec->args[2];
 218
 219        return gpiospec->args[1];
 220}
 221
 222static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base,
 223                                const struct vt8500_gpio_data *data)
 224{
 225        struct vt8500_gpio_chip *vtchip;
 226        struct gpio_chip *chip;
 227        int i;
 228        int pin_cnt = 0;
 229
 230        vtchip = devm_kzalloc(&pdev->dev,
 231                        sizeof(struct vt8500_gpio_chip) * data->num_banks,
 232                        GFP_KERNEL);
 233        if (!vtchip) {
 234                pr_err("%s: failed to allocate chip memory\n", __func__);
 235                return -ENOMEM;
 236        }
 237
 238        for (i = 0; i < data->num_banks; i++) {
 239                vtchip[i].base = base;
 240                vtchip[i].regs = &data->banks[i];
 241
 242                chip = &vtchip[i].chip;
 243
 244                chip->of_xlate = vt8500_of_xlate;
 245                chip->of_gpio_n_cells = 3;
 246                chip->of_node = pdev->dev.of_node;
 247
 248                chip->request = vt8500_gpio_request;
 249                chip->free = vt8500_gpio_free;
 250                chip->direction_input = vt8500_gpio_direction_input;
 251                chip->direction_output = vt8500_gpio_direction_output;
 252                chip->get = vt8500_gpio_get_value;
 253                chip->set = vt8500_gpio_set_value;
 254                chip->can_sleep = 0;
 255                chip->base = pin_cnt;
 256                chip->ngpio = data->banks[i].ngpio;
 257
 258                pin_cnt += data->banks[i].ngpio;
 259
 260                gpiochip_add(chip);
 261        }
 262        return 0;
 263}
 264
 265static struct of_device_id vt8500_gpio_dt_ids[] = {
 266        { .compatible = "via,vt8500-gpio", .data = &vt8500_data, },
 267        { .compatible = "wm,wm8505-gpio", .data = &wm8505_data, },
 268        { .compatible = "wm,wm8650-gpio", .data = &wm8650_data, },
 269        { /* Sentinel */ },
 270};
 271
 272static int __devinit vt8500_gpio_probe(struct platform_device *pdev)
 273{
 274        void __iomem *gpio_base;
 275        struct device_node *np;
 276        const struct of_device_id *of_id =
 277                                of_match_device(vt8500_gpio_dt_ids, &pdev->dev);
 278
 279        if (!of_id) {
 280                dev_err(&pdev->dev, "Failed to find gpio controller\n");
 281                return -ENODEV;
 282        }
 283
 284        np = pdev->dev.of_node;
 285        if (!np) {
 286                dev_err(&pdev->dev, "Missing GPIO description in devicetree\n");
 287                return -EFAULT;
 288        }
 289
 290        gpio_base = of_iomap(np, 0);
 291        if (!gpio_base) {
 292                dev_err(&pdev->dev, "Unable to map GPIO registers\n");
 293                of_node_put(np);
 294                return -ENOMEM;
 295        }
 296
 297        vt8500_add_chips(pdev, gpio_base, of_id->data);
 298
 299        return 0;
 300}
 301
 302static struct platform_driver vt8500_gpio_driver = {
 303        .probe          = vt8500_gpio_probe,
 304        .driver         = {
 305                .name   = "vt8500-gpio",
 306                .owner  = THIS_MODULE,
 307                .of_match_table = vt8500_gpio_dt_ids,
 308        },
 309};
 310
 311module_platform_driver(vt8500_gpio_driver);
 312
 313MODULE_DESCRIPTION("VT8500 GPIO Driver");
 314MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
 315MODULE_LICENSE("GPL v2");
 316MODULE_DEVICE_TABLE(of, vt8500_gpio_dt_ids);
 317
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.