Root/target/linux/adm8668/files/arch/mips/adm8668/gpio.c

1/*
2 * Infineon/ADMTek ADM8668 WildPass GPIO support
3 *
4 * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org>
5 *
6 * Licensed under the terms of GPLv2.
7 *
8 */
9#include <linux/kernel.h>
10#include <linux/gpio.h>
11#include <linux/io.h>
12
13#include <adm8668.h>
14
15#define GPIO_MASK 0x3f
16
17#define GPIO_IN_OFS 0
18#define GPIO_OUT_OFS 6
19#define GPIO_OE_OFS 12
20
21struct adm8668_gpio_chip {
22    void __iomem *base;
23    struct gpio_chip chip;
24};
25
26static int adm8668_gpio_dir_out(struct gpio_chip *chip,
27                unsigned offset, int value)
28{
29    struct adm8668_gpio_chip *c =
30        container_of(chip, struct adm8668_gpio_chip, chip);
31    u32 mask;
32
33    /* clear input, set output enable and output value */
34    mask = __raw_readl(c->base);
35    mask &= ~(1 << offset);
36    mask |= (1 << (offset + GPIO_OE_OFS));
37    if (value)
38        mask |= (1 << (offset + GPIO_OUT_OFS));
39    else
40        mask &= ~(1 << (offset + GPIO_OUT_OFS));
41    __raw_writel(mask, c->base);
42
43    return 0;
44}
45
46static int adm8668_gpio_dir_in(struct gpio_chip *chip,
47                unsigned offset)
48{
49    struct adm8668_gpio_chip *c =
50        container_of(chip, struct adm8668_gpio_chip, chip);
51    u32 mask;
52
53    mask = __raw_readl(c->base);
54    mask &= ~(((1 << (offset + GPIO_OE_OFS)) | (1 << (offset + GPIO_OUT_OFS))));
55    mask |= (1 << offset);
56    __raw_writel(mask, c->base);
57
58    return 0;
59}
60
61static void adm8668_gpio_set(struct gpio_chip *chip,
62                unsigned offset, int value)
63{
64    struct adm8668_gpio_chip *c =
65        container_of(chip, struct adm8668_gpio_chip, chip);
66    u32 mask;
67
68    mask = __raw_readl(c->base);
69    if (value)
70        mask |= (1 << (offset + GPIO_OUT_OFS));
71    else
72        mask &= ~(1 << (offset + GPIO_OUT_OFS));
73    __raw_writel(mask, c->base);
74}
75
76static int adm8668_gpio_get(struct gpio_chip *chip,
77                unsigned offset)
78{
79    struct adm8668_gpio_chip *c =
80        container_of(chip, struct adm8668_gpio_chip, chip);
81    u32 value;
82
83    value = __raw_readl(c->base) & GPIO_MASK;
84
85    return value & (1 << offset);
86}
87
88static struct adm8668_gpio_chip adm8668_gpio_cpu = {
89    .base = (void __iomem *)KSEG1ADDR(ADM8668_CONFIG_BASE + CRGPIO_REG),
90    .chip = {
91        .label = "adm8668-cpu-gpio",
92        .direction_output = adm8668_gpio_dir_out,
93        .direction_input = adm8668_gpio_dir_in,
94        .set = adm8668_gpio_set,
95        .get = adm8668_gpio_get,
96        .ngpio = 6,
97    },
98};
99
100static struct adm8668_gpio_chip adm8668_gpio_wlan = {
101    .base = (void __iomem *)KSEG1ADDR(ADM8668_WLAN_BASE + GPIO_REG),
102    .chip = {
103        .label = "adm8668-wlan-gpio",
104        .direction_output = adm8668_gpio_dir_out,
105        .direction_input = adm8668_gpio_dir_in,
106        .set = adm8668_gpio_set,
107        .get = adm8668_gpio_get,
108        .ngpio = 6,
109        .base = 6,
110    },
111};
112
113static int __init adm8668_gpio_init(void)
114{
115    int ret;
116
117    ret = gpiochip_add(&adm8668_gpio_cpu.chip);
118    if (ret)
119        return ret;
120
121    return gpiochip_add(&adm8668_gpio_wlan.chip);
122}
123arch_initcall(adm8668_gpio_init);
124

Archive Download this file



interactive