Linux Audio

Check our new training course

In-person Linux kernel drivers training

Jun 16-20, 2025
Register
Loading...
Note: File does not exist in v6.13.7.
  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#ifndef coldfire_gpio_h
 17#define coldfire_gpio_h
 18
 19#include <linux/io.h>
 20#include <asm-generic/gpio.h>
 21#include <asm/coldfire.h>
 22#include <asm/mcfsim.h>
 23
 24/*
 25 * The Freescale Coldfire family is quite varied in how they implement GPIO.
 26 * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have
 27 * only one port, others have multiple ports; some have a single data latch
 28 * for both input and output, others have a separate pin data register to read
 29 * input; some require a read-modify-write access to change an output, others
 30 * have set and clear registers for some of the outputs; Some have all the
 31 * GPIOs in a single control area, others have some GPIOs implemented in
 32 * different modules.
 33 *
 34 * This implementation attempts accommodate the differences while presenting
 35 * a generic interface that will optimize to as few instructions as possible.
 36 */
 37#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
 38    defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
 39    defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
 40    defined(CONFIG_M532x) || defined(CONFIG_M54xx)
 41
 42/* These parts have GPIO organized by 8 bit ports */
 43
 44#define MCFGPIO_PORTTYPE		u8
 45#define MCFGPIO_PORTSIZE		8
 46#define mcfgpio_read(port)		__raw_readb(port)
 47#define mcfgpio_write(data, port)	__raw_writeb(data, port)
 48
 49#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272)
 50
 51/* These parts have GPIO organized by 16 bit ports */
 52
 53#define MCFGPIO_PORTTYPE		u16
 54#define MCFGPIO_PORTSIZE		16
 55#define mcfgpio_read(port)		__raw_readw(port)
 56#define mcfgpio_write(data, port)	__raw_writew(data, port)
 57
 58#elif defined(CONFIG_M5249)
 59
 60/* These parts have GPIO organized by 32 bit ports */
 61
 62#define MCFGPIO_PORTTYPE		u32
 63#define MCFGPIO_PORTSIZE		32
 64#define mcfgpio_read(port)		__raw_readl(port)
 65#define mcfgpio_write(data, port)	__raw_writel(data, port)
 66
 67#endif
 68
 69#define mcfgpio_bit(gpio)		(1 << ((gpio) %  MCFGPIO_PORTSIZE))
 70#define mcfgpio_port(gpio)		((gpio) / MCFGPIO_PORTSIZE)
 71
 72#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
 73    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
 74/*
 75 * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses
 76 * read-modify-write to change an output and a GPIO module which has separate
 77 * set/clr registers to directly change outputs with a single write access.
 78 */
 79#if defined(CONFIG_M528x)
 80/*
 81 * The 528x also has GPIOs in other modules (GPT, QADC) which use
 82 * read-modify-write as well as those controlled by the EPORT and GPIO modules.
 83 */
 84#define MCFGPIO_SCR_START		40
 85#else
 86#define MCFGPIO_SCR_START		8
 87#endif
 88
 89#define MCFGPIO_SETR_PORT(gpio)		(MCFGPIO_SETR + \
 90					mcfgpio_port(gpio - MCFGPIO_SCR_START))
 91
 92#define MCFGPIO_CLRR_PORT(gpio)		(MCFGPIO_CLRR + \
 93					mcfgpio_port(gpio - MCFGPIO_SCR_START))
 94#else
 95
 96#define MCFGPIO_SCR_START		MCFGPIO_PIN_MAX
 97/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */
 98#define MCFGPIO_SETR_PORT(gpio)		0
 99#define MCFGPIO_CLRR_PORT(gpio)		0
100
101#endif
102/*
103 * Coldfire specific helper functions
104 */
105
106/* return the port pin data register for a gpio */
107static inline u32 __mcf_gpio_ppdr(unsigned gpio)
108{
109#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
110    defined(CONFIG_M5307) || defined(CONFIG_M5407)
111	return MCFSIM_PADAT;
112#elif defined(CONFIG_M5272)
113	if (gpio < 16)
114		return MCFSIM_PADAT;
115	else if (gpio < 32)
116		return MCFSIM_PBDAT;
117	else
118		return MCFSIM_PCDAT;
119#elif defined(CONFIG_M5249)
120	if (gpio < 32)
121		return MCFSIM2_GPIOREAD;
122	else
123		return MCFSIM2_GPIO1READ;
124#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
125      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
126	if (gpio < 8)
127		return MCFEPORT_EPPDR;
128#if defined(CONFIG_M528x)
129	else if (gpio < 16)
130		return MCFGPTA_GPTPORT;
131	else if (gpio < 24)
132		return MCFGPTB_GPTPORT;
133	else if (gpio < 32)
134		return MCFQADC_PORTQA;
135	else if (gpio < 40)
136		return MCFQADC_PORTQB;
137#endif
138	else
139		return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
140#else
141	return 0;
142#endif
143}
144
145/* return the port output data register for a gpio */
146static inline u32 __mcf_gpio_podr(unsigned gpio)
147{
148#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
149    defined(CONFIG_M5307) || defined(CONFIG_M5407)
150	return MCFSIM_PADAT;
151#elif defined(CONFIG_M5272)
152	if (gpio < 16)
153		return MCFSIM_PADAT;
154	else if (gpio < 32)
155		return MCFSIM_PBDAT;
156	else
157		return MCFSIM_PCDAT;
158#elif defined(CONFIG_M5249)
159	if (gpio < 32)
160		return MCFSIM2_GPIOWRITE;
161	else
162		return MCFSIM2_GPIO1WRITE;
163#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
164      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
165	if (gpio < 8)
166		return MCFEPORT_EPDR;
167#if defined(CONFIG_M528x)
168	else if (gpio < 16)
169		return MCFGPTA_GPTPORT;
170	else if (gpio < 24)
171		return MCFGPTB_GPTPORT;
172	else if (gpio < 32)
173		return MCFQADC_PORTQA;
174	else if (gpio < 40)
175		return MCFQADC_PORTQB;
176#endif
177	else
178		return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
179#else
180	return 0;
181#endif
182}
183
184/*
185 * The Generic GPIO functions
186 *
187 * If the gpio is a compile time constant and is one of the Coldfire gpios,
188 * use the inline version, otherwise dispatch thru gpiolib.
189 */
190
191static inline int gpio_get_value(unsigned gpio)
192{
193	if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX)
194		return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio);
195	else
196		return __gpio_get_value(gpio);
197}
198
199static inline void gpio_set_value(unsigned gpio, int value)
200{
201	if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) {
202		if (gpio < MCFGPIO_SCR_START) {
203			unsigned long flags;
204			MCFGPIO_PORTTYPE data;
205
206			local_irq_save(flags);
207			data = mcfgpio_read(__mcf_gpio_podr(gpio));
208			if (value)
209				data |= mcfgpio_bit(gpio);
210			else
211				data &= ~mcfgpio_bit(gpio);
212			mcfgpio_write(data, __mcf_gpio_podr(gpio));
213			local_irq_restore(flags);
214		} else {
215			if (value)
216				mcfgpio_write(mcfgpio_bit(gpio),
217						MCFGPIO_SETR_PORT(gpio));
218			else
219				mcfgpio_write(~mcfgpio_bit(gpio),
220						MCFGPIO_CLRR_PORT(gpio));
221		}
222	} else
223		__gpio_set_value(gpio, value);
224}
225
226static inline int gpio_to_irq(unsigned gpio)
227{
228	return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL;
229}
230
231static inline int irq_to_gpio(unsigned irq)
232{
233	return (irq >= MCFGPIO_IRQ_VECBASE &&
234		irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ?
235		irq - MCFGPIO_IRQ_VECBASE : -ENXIO;
236}
237
238static inline int gpio_cansleep(unsigned gpio)
239{
240	return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
241}
242
243#endif