1 // SPDX-License-Identifier: GPL-2.0-only
3 * Coldfire generic GPIO support.
5 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/device.h>
14 #include <asm/coldfire.h>
15 #include <asm/mcfsim.h>
16 #include <asm/mcfgpio.h>
18 int __mcfgpio_get_value(unsigned gpio)
20 return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
22 EXPORT_SYMBOL(__mcfgpio_get_value);
24 void __mcfgpio_set_value(unsigned gpio, int value)
26 if (gpio < MCFGPIO_SCR_START) {
28 MCFGPIO_PORTTYPE data;
30 local_irq_save(flags);
31 data = mcfgpio_read(__mcfgpio_podr(gpio));
33 data |= mcfgpio_bit(gpio);
35 data &= ~mcfgpio_bit(gpio);
36 mcfgpio_write(data, __mcfgpio_podr(gpio));
37 local_irq_restore(flags);
40 mcfgpio_write(mcfgpio_bit(gpio),
41 MCFGPIO_SETR_PORT(gpio));
43 mcfgpio_write(~mcfgpio_bit(gpio),
44 MCFGPIO_CLRR_PORT(gpio));
47 EXPORT_SYMBOL(__mcfgpio_set_value);
49 int __mcfgpio_direction_input(unsigned gpio)
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);
62 EXPORT_SYMBOL(__mcfgpio_direction_input);
64 int __mcfgpio_direction_output(unsigned gpio, int value)
67 MCFGPIO_PORTTYPE data;
69 local_irq_save(flags);
70 data = mcfgpio_read(__mcfgpio_pddr(gpio));
71 data |= mcfgpio_bit(gpio);
72 mcfgpio_write(data, __mcfgpio_pddr(gpio));
74 /* now set the data to output */
75 if (gpio < MCFGPIO_SCR_START) {
76 data = mcfgpio_read(__mcfgpio_podr(gpio));
78 data |= mcfgpio_bit(gpio);
80 data &= ~mcfgpio_bit(gpio);
81 mcfgpio_write(data, __mcfgpio_podr(gpio));
84 mcfgpio_write(mcfgpio_bit(gpio),
85 MCFGPIO_SETR_PORT(gpio));
87 mcfgpio_write(~mcfgpio_bit(gpio),
88 MCFGPIO_CLRR_PORT(gpio));
90 local_irq_restore(flags);
93 EXPORT_SYMBOL(__mcfgpio_direction_output);
95 int __mcfgpio_request(unsigned gpio)
99 EXPORT_SYMBOL(__mcfgpio_request);
101 void __mcfgpio_free(unsigned gpio)
103 __mcfgpio_direction_input(gpio);
105 EXPORT_SYMBOL(__mcfgpio_free);
107 #ifdef CONFIG_GPIOLIB
109 static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
111 return __mcfgpio_direction_input(offset);
114 static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
116 return !!__mcfgpio_get_value(offset);
119 static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
122 return __mcfgpio_direction_output(offset, value);
125 static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
128 __mcfgpio_set_value(offset, value);
131 static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
133 return __mcfgpio_request(offset);
136 static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
138 __mcfgpio_free(offset);
141 static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
143 #if defined(MCFGPIO_IRQ_MIN)
144 if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
146 if (offset < MCFGPIO_IRQ_MAX)
148 return MCFGPIO_IRQ_VECBASE + offset;
153 static struct gpio_chip mcfgpio_chip = {
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,
163 .ngpio = MCFGPIO_PIN_MAX,
166 static int __init mcfgpio_sysinit(void)
168 return gpiochip_add_data(&mcfgpio_chip, NULL);
171 core_initcall(mcfgpio_sysinit);