1
2
3
4
5
6
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/device.h>
12
13#include <linux/io.h>
14#include <asm/coldfire.h>
15#include <asm/mcfsim.h>
16#include <asm/mcfgpio.h>
17
18int __mcfgpio_get_value(unsigned gpio)
19{
20 return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
21}
22EXPORT_SYMBOL(__mcfgpio_get_value);
23
24void __mcfgpio_set_value(unsigned gpio, int value)
25{
26 if (gpio < MCFGPIO_SCR_START) {
27 unsigned long flags;
28 MCFGPIO_PORTTYPE data;
29
30 local_irq_save(flags);
31 data = mcfgpio_read(__mcfgpio_podr(gpio));
32 if (value)
33 data |= mcfgpio_bit(gpio);
34 else
35 data &= ~mcfgpio_bit(gpio);
36 mcfgpio_write(data, __mcfgpio_podr(gpio));
37 local_irq_restore(flags);
38 } else {
39 if (value)
40 mcfgpio_write(mcfgpio_bit(gpio),
41 MCFGPIO_SETR_PORT(gpio));
42 else
43 mcfgpio_write(~mcfgpio_bit(gpio),
44 MCFGPIO_CLRR_PORT(gpio));
45 }
46}
47EXPORT_SYMBOL(__mcfgpio_set_value);
48
49int __mcfgpio_direction_input(unsigned gpio)
50{
51 unsigned long flags;
52 MCFGPIO_PORTTYPE dir;
53
54 local_irq_save(flags);
55 dir = mcfgpio_read(__mcfgpio_pddr(gpio));
56 dir &= ~mcfgpio_bit(gpio);
57 mcfgpio_write(dir, __mcfgpio_pddr(gpio));
58 local_irq_restore(flags);
59
60 return 0;
61}
62EXPORT_SYMBOL(__mcfgpio_direction_input);
63
64int __mcfgpio_direction_output(unsigned gpio, int value)
65{
66 unsigned long flags;
67 MCFGPIO_PORTTYPE data;
68
69 local_irq_save(flags);
70 data = mcfgpio_read(__mcfgpio_pddr(gpio));
71 data |= mcfgpio_bit(gpio);
72 mcfgpio_write(data, __mcfgpio_pddr(gpio));
73
74
75 if (gpio < MCFGPIO_SCR_START) {
76 data = mcfgpio_read(__mcfgpio_podr(gpio));
77 if (value)
78 data |= mcfgpio_bit(gpio);
79 else
80 data &= ~mcfgpio_bit(gpio);
81 mcfgpio_write(data, __mcfgpio_podr(gpio));
82 } else {
83 if (value)
84 mcfgpio_write(mcfgpio_bit(gpio),
85 MCFGPIO_SETR_PORT(gpio));
86 else
87 mcfgpio_write(~mcfgpio_bit(gpio),
88 MCFGPIO_CLRR_PORT(gpio));
89 }
90 local_irq_restore(flags);
91 return 0;
92}
93EXPORT_SYMBOL(__mcfgpio_direction_output);
94
95int __mcfgpio_request(unsigned gpio)
96{
97 return 0;
98}
99EXPORT_SYMBOL(__mcfgpio_request);
100
101void __mcfgpio_free(unsigned gpio)
102{
103 __mcfgpio_direction_input(gpio);
104}
105EXPORT_SYMBOL(__mcfgpio_free);
106
107#ifdef CONFIG_GPIOLIB
108
109static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
110{
111 return __mcfgpio_direction_input(offset);
112}
113
114static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
115{
116 return !!__mcfgpio_get_value(offset);
117}
118
119static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
120 int value)
121{
122 return __mcfgpio_direction_output(offset, value);
123}
124
125static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
126 int value)
127{
128 __mcfgpio_set_value(offset, value);
129}
130
131static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
132{
133 return __mcfgpio_request(offset);
134}
135
136static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
137{
138 __mcfgpio_free(offset);
139}
140
141static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
142{
143#if defined(MCFGPIO_IRQ_MIN)
144 if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
145#else
146 if (offset < MCFGPIO_IRQ_MAX)
147#endif
148 return MCFGPIO_IRQ_VECBASE + offset;
149 else
150 return -EINVAL;
151}
152
153static struct gpio_chip mcfgpio_chip = {
154 .label = "mcfgpio",
155 .request = mcfgpio_request,
156 .free = mcfgpio_free,
157 .direction_input = mcfgpio_direction_input,
158 .direction_output = mcfgpio_direction_output,
159 .get = mcfgpio_get_value,
160 .set = mcfgpio_set_value,
161 .to_irq = mcfgpio_to_irq,
162 .base = 0,
163 .ngpio = MCFGPIO_PIN_MAX,
164};
165
166static int __init mcfgpio_sysinit(void)
167{
168 return gpiochip_add_data(&mcfgpio_chip, NULL);
169}
170
171core_initcall(mcfgpio_sysinit);
172#endif
173