Loading...
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Coldfire generic GPIO support.
4 *
5 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
6 */
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/device.h>
12#include <linux/gpio/driver.h>
13
14#include <linux/io.h>
15#include <asm/coldfire.h>
16#include <asm/mcfsim.h>
17#include <asm/mcfgpio.h>
18
19int __mcfgpio_get_value(unsigned gpio)
20{
21 return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
22}
23EXPORT_SYMBOL(__mcfgpio_get_value);
24
25void __mcfgpio_set_value(unsigned gpio, int value)
26{
27 if (gpio < MCFGPIO_SCR_START) {
28 unsigned long flags;
29 MCFGPIO_PORTTYPE data;
30
31 local_irq_save(flags);
32 data = mcfgpio_read(__mcfgpio_podr(gpio));
33 if (value)
34 data |= mcfgpio_bit(gpio);
35 else
36 data &= ~mcfgpio_bit(gpio);
37 mcfgpio_write(data, __mcfgpio_podr(gpio));
38 local_irq_restore(flags);
39 } else {
40 if (value)
41 mcfgpio_write(mcfgpio_bit(gpio),
42 MCFGPIO_SETR_PORT(gpio));
43 else
44 mcfgpio_write(~mcfgpio_bit(gpio),
45 MCFGPIO_CLRR_PORT(gpio));
46 }
47}
48EXPORT_SYMBOL(__mcfgpio_set_value);
49
50int __mcfgpio_direction_input(unsigned gpio)
51{
52 unsigned long flags;
53 MCFGPIO_PORTTYPE dir;
54
55 local_irq_save(flags);
56 dir = mcfgpio_read(__mcfgpio_pddr(gpio));
57 dir &= ~mcfgpio_bit(gpio);
58 mcfgpio_write(dir, __mcfgpio_pddr(gpio));
59 local_irq_restore(flags);
60
61 return 0;
62}
63EXPORT_SYMBOL(__mcfgpio_direction_input);
64
65int __mcfgpio_direction_output(unsigned gpio, int value)
66{
67 unsigned long flags;
68 MCFGPIO_PORTTYPE data;
69
70 local_irq_save(flags);
71 data = mcfgpio_read(__mcfgpio_pddr(gpio));
72 data |= mcfgpio_bit(gpio);
73 mcfgpio_write(data, __mcfgpio_pddr(gpio));
74
75 /* now set the data to output */
76 if (gpio < MCFGPIO_SCR_START) {
77 data = mcfgpio_read(__mcfgpio_podr(gpio));
78 if (value)
79 data |= mcfgpio_bit(gpio);
80 else
81 data &= ~mcfgpio_bit(gpio);
82 mcfgpio_write(data, __mcfgpio_podr(gpio));
83 } else {
84 if (value)
85 mcfgpio_write(mcfgpio_bit(gpio),
86 MCFGPIO_SETR_PORT(gpio));
87 else
88 mcfgpio_write(~mcfgpio_bit(gpio),
89 MCFGPIO_CLRR_PORT(gpio));
90 }
91 local_irq_restore(flags);
92 return 0;
93}
94EXPORT_SYMBOL(__mcfgpio_direction_output);
95
96int __mcfgpio_request(unsigned gpio)
97{
98 return 0;
99}
100EXPORT_SYMBOL(__mcfgpio_request);
101
102void __mcfgpio_free(unsigned gpio)
103{
104 __mcfgpio_direction_input(gpio);
105}
106EXPORT_SYMBOL(__mcfgpio_free);
107
108#ifdef CONFIG_GPIOLIB
109
110static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
111{
112 return __mcfgpio_direction_input(offset);
113}
114
115static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
116{
117 return !!__mcfgpio_get_value(offset);
118}
119
120static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
121 int value)
122{
123 return __mcfgpio_direction_output(offset, value);
124}
125
126static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
127 int value)
128{
129 __mcfgpio_set_value(offset, value);
130}
131
132static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
133{
134 return __mcfgpio_request(offset);
135}
136
137static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
138{
139 __mcfgpio_free(offset);
140}
141
142static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
143{
144#if defined(MCFGPIO_IRQ_MIN)
145 if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
146#else
147 if (offset < MCFGPIO_IRQ_MAX)
148#endif
149 return MCFGPIO_IRQ_VECBASE + offset;
150 else
151 return -EINVAL;
152}
153
154static struct gpio_chip mcfgpio_chip = {
155 .label = "mcfgpio",
156 .request = mcfgpio_request,
157 .free = mcfgpio_free,
158 .direction_input = mcfgpio_direction_input,
159 .direction_output = mcfgpio_direction_output,
160 .get = mcfgpio_get_value,
161 .set = mcfgpio_set_value,
162 .to_irq = mcfgpio_to_irq,
163 .base = 0,
164 .ngpio = MCFGPIO_PIN_MAX,
165};
166
167static int __init mcfgpio_sysinit(void)
168{
169 return gpiochip_add_data(&mcfgpio_chip, NULL);
170}
171
172core_initcall(mcfgpio_sysinit);
173#endif
1/*
2 * Coldfire generic GPIO support.
3 *
4 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/device.h>
20
21#include <linux/io.h>
22#include <asm/coldfire.h>
23#include <asm/mcfsim.h>
24#include <asm/mcfgpio.h>
25
26int __mcfgpio_get_value(unsigned gpio)
27{
28 return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
29}
30EXPORT_SYMBOL(__mcfgpio_get_value);
31
32void __mcfgpio_set_value(unsigned gpio, int value)
33{
34 if (gpio < MCFGPIO_SCR_START) {
35 unsigned long flags;
36 MCFGPIO_PORTTYPE data;
37
38 local_irq_save(flags);
39 data = mcfgpio_read(__mcfgpio_podr(gpio));
40 if (value)
41 data |= mcfgpio_bit(gpio);
42 else
43 data &= ~mcfgpio_bit(gpio);
44 mcfgpio_write(data, __mcfgpio_podr(gpio));
45 local_irq_restore(flags);
46 } else {
47 if (value)
48 mcfgpio_write(mcfgpio_bit(gpio),
49 MCFGPIO_SETR_PORT(gpio));
50 else
51 mcfgpio_write(~mcfgpio_bit(gpio),
52 MCFGPIO_CLRR_PORT(gpio));
53 }
54}
55EXPORT_SYMBOL(__mcfgpio_set_value);
56
57int __mcfgpio_direction_input(unsigned gpio)
58{
59 unsigned long flags;
60 MCFGPIO_PORTTYPE dir;
61
62 local_irq_save(flags);
63 dir = mcfgpio_read(__mcfgpio_pddr(gpio));
64 dir &= ~mcfgpio_bit(gpio);
65 mcfgpio_write(dir, __mcfgpio_pddr(gpio));
66 local_irq_restore(flags);
67
68 return 0;
69}
70EXPORT_SYMBOL(__mcfgpio_direction_input);
71
72int __mcfgpio_direction_output(unsigned gpio, int value)
73{
74 unsigned long flags;
75 MCFGPIO_PORTTYPE data;
76
77 local_irq_save(flags);
78 data = mcfgpio_read(__mcfgpio_pddr(gpio));
79 data |= mcfgpio_bit(gpio);
80 mcfgpio_write(data, __mcfgpio_pddr(gpio));
81
82 /* now set the data to output */
83 if (gpio < MCFGPIO_SCR_START) {
84 data = mcfgpio_read(__mcfgpio_podr(gpio));
85 if (value)
86 data |= mcfgpio_bit(gpio);
87 else
88 data &= ~mcfgpio_bit(gpio);
89 mcfgpio_write(data, __mcfgpio_podr(gpio));
90 } else {
91 if (value)
92 mcfgpio_write(mcfgpio_bit(gpio),
93 MCFGPIO_SETR_PORT(gpio));
94 else
95 mcfgpio_write(~mcfgpio_bit(gpio),
96 MCFGPIO_CLRR_PORT(gpio));
97 }
98 local_irq_restore(flags);
99 return 0;
100}
101EXPORT_SYMBOL(__mcfgpio_direction_output);
102
103int __mcfgpio_request(unsigned gpio)
104{
105 return 0;
106}
107EXPORT_SYMBOL(__mcfgpio_request);
108
109void __mcfgpio_free(unsigned gpio)
110{
111 __mcfgpio_direction_input(gpio);
112}
113EXPORT_SYMBOL(__mcfgpio_free);
114
115#ifdef CONFIG_GPIOLIB
116
117static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
118{
119 return __mcfgpio_direction_input(offset);
120}
121
122static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
123{
124 return !!__mcfgpio_get_value(offset);
125}
126
127static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
128 int value)
129{
130 return __mcfgpio_direction_output(offset, value);
131}
132
133static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
134 int value)
135{
136 __mcfgpio_set_value(offset, value);
137}
138
139static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
140{
141 return __mcfgpio_request(offset);
142}
143
144static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
145{
146 __mcfgpio_free(offset);
147}
148
149static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
150{
151#if defined(MCFGPIO_IRQ_MIN)
152 if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
153#else
154 if (offset < MCFGPIO_IRQ_MAX)
155#endif
156 return MCFGPIO_IRQ_VECBASE + offset;
157 else
158 return -EINVAL;
159}
160
161static struct gpio_chip mcfgpio_chip = {
162 .label = "mcfgpio",
163 .request = mcfgpio_request,
164 .free = mcfgpio_free,
165 .direction_input = mcfgpio_direction_input,
166 .direction_output = mcfgpio_direction_output,
167 .get = mcfgpio_get_value,
168 .set = mcfgpio_set_value,
169 .to_irq = mcfgpio_to_irq,
170 .base = 0,
171 .ngpio = MCFGPIO_PIN_MAX,
172};
173
174static int __init mcfgpio_sysinit(void)
175{
176 return gpiochip_add_data(&mcfgpio_chip, NULL);
177}
178
179core_initcall(mcfgpio_sysinit);
180#endif