OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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 | |||
21 | struct adm8668_gpio_chip { |
||
22 | void __iomem *base; |
||
23 | struct gpio_chip chip; |
||
24 | }; |
||
25 | |||
26 | static 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 | |||
46 | static 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 | |||
61 | static 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 | |||
76 | static 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 | |||
88 | static 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 | |||
100 | static 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 | |||
113 | static 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 | } |
||
123 | arch_initcall(adm8668_gpio_init); |