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