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>
12 #include <linux/gpio/driver.h>
15 #include <asm/coldfire.h>
16 #include <asm/mcfsim.h>
17 #include <asm/mcfgpio.h>
19 int __mcfgpio_get_value(unsigned gpio
)
21 return mcfgpio_read(__mcfgpio_ppdr(gpio
)) & mcfgpio_bit(gpio
);
23 EXPORT_SYMBOL(__mcfgpio_get_value
);
25 void __mcfgpio_set_value(unsigned gpio
, int value
)
27 if (gpio
< MCFGPIO_SCR_START
) {
29 MCFGPIO_PORTTYPE data
;
31 local_irq_save(flags
);
32 data
= mcfgpio_read(__mcfgpio_podr(gpio
));
34 data
|= mcfgpio_bit(gpio
);
36 data
&= ~mcfgpio_bit(gpio
);
37 mcfgpio_write(data
, __mcfgpio_podr(gpio
));
38 local_irq_restore(flags
);
41 mcfgpio_write(mcfgpio_bit(gpio
),
42 MCFGPIO_SETR_PORT(gpio
));
44 mcfgpio_write(~mcfgpio_bit(gpio
),
45 MCFGPIO_CLRR_PORT(gpio
));
48 EXPORT_SYMBOL(__mcfgpio_set_value
);
50 int __mcfgpio_direction_input(unsigned gpio
)
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
);
63 EXPORT_SYMBOL(__mcfgpio_direction_input
);
65 int __mcfgpio_direction_output(unsigned gpio
, int value
)
68 MCFGPIO_PORTTYPE data
;
70 local_irq_save(flags
);
71 data
= mcfgpio_read(__mcfgpio_pddr(gpio
));
72 data
|= mcfgpio_bit(gpio
);
73 mcfgpio_write(data
, __mcfgpio_pddr(gpio
));
75 /* now set the data to output */
76 if (gpio
< MCFGPIO_SCR_START
) {
77 data
= mcfgpio_read(__mcfgpio_podr(gpio
));
79 data
|= mcfgpio_bit(gpio
);
81 data
&= ~mcfgpio_bit(gpio
);
82 mcfgpio_write(data
, __mcfgpio_podr(gpio
));
85 mcfgpio_write(mcfgpio_bit(gpio
),
86 MCFGPIO_SETR_PORT(gpio
));
88 mcfgpio_write(~mcfgpio_bit(gpio
),
89 MCFGPIO_CLRR_PORT(gpio
));
91 local_irq_restore(flags
);
94 EXPORT_SYMBOL(__mcfgpio_direction_output
);
96 int __mcfgpio_request(unsigned gpio
)
100 EXPORT_SYMBOL(__mcfgpio_request
);
102 void __mcfgpio_free(unsigned gpio
)
104 __mcfgpio_direction_input(gpio
);
106 EXPORT_SYMBOL(__mcfgpio_free
);
108 #ifdef CONFIG_GPIOLIB
110 static int mcfgpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
112 return __mcfgpio_direction_input(offset
);
115 static int mcfgpio_get_value(struct gpio_chip
*chip
, unsigned offset
)
117 return !!__mcfgpio_get_value(offset
);
120 static int mcfgpio_direction_output(struct gpio_chip
*chip
, unsigned offset
,
123 return __mcfgpio_direction_output(offset
, value
);
126 static void mcfgpio_set_value(struct gpio_chip
*chip
, unsigned offset
,
129 __mcfgpio_set_value(offset
, value
);
132 static int mcfgpio_request(struct gpio_chip
*chip
, unsigned offset
)
134 return __mcfgpio_request(offset
);
137 static void mcfgpio_free(struct gpio_chip
*chip
, unsigned offset
)
139 __mcfgpio_free(offset
);
142 static int mcfgpio_to_irq(struct gpio_chip
*chip
, unsigned offset
)
144 #if defined(MCFGPIO_IRQ_MIN)
145 if ((offset
>= MCFGPIO_IRQ_MIN
) && (offset
< MCFGPIO_IRQ_MAX
))
147 if (offset
< MCFGPIO_IRQ_MAX
)
149 return MCFGPIO_IRQ_VECBASE
+ offset
;
154 static struct gpio_chip mcfgpio_chip
= {
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
,
164 .ngpio
= MCFGPIO_PIN_MAX
,
167 static int __init
mcfgpio_sysinit(void)
169 return gpiochip_add_data(&mcfgpio_chip
, NULL
);
172 core_initcall(mcfgpio_sysinit
);