2 * Copyright 2006 Freescale Semiconductor, Inc. All Rights Reserved.
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
15 * This structure defines the offset of registers in gpio module.
19 #include <cyg/hal/hal_intr.h>
20 #include <cyg/hal/plf_mmap.h>
21 #include <cyg/hal/hal_soc.h> // Hardware definitions
22 #include <cyg/hal/hal_cache.h>
25 //#define MXC_MUX_DEBUG
28 #define diag_printf1 diag_printf
30 #define diag_printf1(fmt,args...)
33 typedef unsigned short u16;
34 typedef unsigned int u32;
35 typedef unsigned char u8;
37 struct mxc_gpio_port {
38 u32 num; /*!< gpio port number */
39 u32 base; /*!< gpio port base VA */
40 u16 irq; /*!< irq number to the core */
41 u16 virtual_irq_start; /*!< virtual irq start number */
45 * This enumeration data type defines the configuration for input mode.
48 GPIO_INPUT_GPIO = 0x00,
49 GPIO_INPUT_INTR = 0x01,
50 GPIO_INPUT_LOW = 0x02,
51 GPIO_INPUT_HIGH = 0x03
55 * This enumeration data type defines the configuration for output mode.
65 u32 num; /*!< gpio port number */
66 u32 base; /*!< gpio port base VA */
67 u16 irq; /*!< irq number to the core */
68 u16 virtual_irq_start; /*!< virtual irq start number */
69 u32 reserved_map; /*!< keep track of which pins are in use */
70 u32 irq_is_level_map; /*!< if a pin's irq is level sensitive. default is edge */
73 #define IO_ADDRESS(x) x
74 #define GPIO_BASE_ADDR SOC_GPIOA_BASE
76 struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
79 .base = IO_ADDRESS(GPIO_BASE_ADDR),
83 .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x100,
87 .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x200,
91 .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x300,
95 .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x400,
99 .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x500,
103 static struct gpio_port gpio_port[GPIO_PORT_NUM];
106 static inline int _request_gpio(struct gpio_port *port, u32 index)
108 if (port->reserved_map & (1 << index)) {
109 diag_printf("GPIO port %d (0-based), pin %d is already reserved!\n",
113 port->reserved_map |= (1 << index);
117 static inline struct gpio_port *get_gpio_port(u32 gpio)
119 return &gpio_port[GPIO_TO_PORT(gpio)];
122 static int check_gpio(u32 gpio)
124 if (gpio >= MXC_MAX_GPIO_LINES) {
125 diag_printf("mxc-gpio: invalid GPIO %d\n", gpio);
132 * Request ownership for a GPIO pin. The caller has to check the return value
133 * of this function to make sure it returns 0 before make use of that pin.
134 * @param pin a name defined by \b iomux_pin_name_t
135 * @return 0 if successful; Non-zero otherwise
137 int mxc_request_gpio(iomux_pin_name_t pin)
139 struct gpio_port *port;
140 u32 index, gpio = IOMUX_TO_GPIO(pin);
142 if (check_gpio(gpio) < 0)
145 port = get_gpio_port(gpio);
146 index = GPIO_TO_INDEX(gpio);
148 return _request_gpio(port, index);
152 * This function enable or disable the pullup feature to the pin.
153 * @param port a pointer of gpio port
154 * @param index the index of the pin in the port
155 * @param en 0 if disable pullup, otherwise enable it.
158 static inline void _gpio_set_puen(struct mxc_gpio_port *port, u32 index,
163 reg = readl(port->base + GPIO_PUEN);
167 reg &= ~(1 << index);
169 writel(reg, port->base + GPIO_PUEN);
173 * This function set the input configuration A.
174 * @param port a pointer of gpio port
175 * @param index the index of the pin in the port
176 * @param config a mode as define in \b #gpio_input_cfg_t
179 static inline void _gpio_set_iconfa(struct mxc_gpio_port *port, u32 index,
180 gpio_input_cfg_t config)
185 mask = 0x3 << ((index % 16) << 1);
188 reg = port->base + GPIO_ICONFA2;
189 val = config << ((index - 16) * 2);
191 reg = port->base + GPIO_ICONFA1;
192 val = config << (index * 2);
194 val |= readl(reg) & ~(mask);
199 * This function set the input configuration B.
200 * @param port a pointer of gpio port
201 * @param index the index of the pin in the port
202 * @param config a mode as define in \b #gpio_input_cfg_t
205 static inline void _gpio_set_iconfb(struct mxc_gpio_port *port, u32 index,
206 gpio_input_cfg_t config)
211 mask = 0x3 << ((index % 16) << 1);
214 reg = port->base + GPIO_ICONFB2;
215 val = config << ((index - 16) * 2);
217 reg = port->base + GPIO_ICONFB1;
218 val = config << (index * 2);
220 val |= readl(reg) & (~mask);
225 * This function set the output configuration.
226 * @param port a pointer of gpio port
227 * @param index the index of the pin in the port
228 * @param config a mode as define in \b #gpio_output_cfg_t
231 static inline void _gpio_set_ocr(struct mxc_gpio_port *port, u32 index,
232 gpio_output_cfg_t config)
237 mask = 0x3 << ((index % 16) << 1);
239 reg = port->base + GPIO_OCR2;
240 val = config << ((index - 16) * 2);
242 reg = port->base + GPIO_OCR1;
243 val = config << (index * 2);
245 val |= readl(reg) & (~mask);
250 *@brief gpio_config_mux - just configure the mode of the gpio pin.
251 *@param pin a pin number as defined in \b #iomux_pin_name_t
252 *@param mode a module as define in \b #gpio_mux_mode_t;
253 * GPIO_MUX_PRIMARY set pin to work as primary function.
254 * GPIO_MUX_ALT set pin to work as alternate function.
255 * GPIO_MUX_GPIO set pin to work as output function based the data register
256 * GPIO_MUX_INPUT1 set pin to work as input function connected with A_OUT
257 * GPIO_MUX_INPUT2 set pin to work as input function connected with B_OUT
258 * GPIO_MUX_OUTPUT1 set pin to work as output function connected with A_IN
259 * GPIO_MUX_OUTPUT2 set pin to work as output function connected with B_IN
260 * GPIO_MUX_OUTPUT3 set pin to work as output function connected with C_IN
261 *@return 0 if successful, Non-zero otherwise
264 int gpio_config_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode)
266 u32 gius_reg, gpr_reg;
267 struct mxc_gpio_port *port;
268 u32 index, gpio = IOMUX_TO_GPIO(pin);
270 port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]);
271 index = GPIO_TO_INDEX(gpio);
273 diag_printf1("%s: Configuring PORT %c, bit %d\n",
274 __FUNCTION__, port->num + 'A', index);
276 gius_reg = readl(port->base + GPIO_GIUS);
277 gpr_reg = readl(port->base + GPIO_GPR);
280 case GPIO_MUX_PRIMARY:
281 gius_reg &= ~(1L << index);
282 gpr_reg &= ~(1L << index);
285 gius_reg &= ~(1L << index);
286 gpr_reg |= (1L << index);
289 gius_reg |= (1L << index);
290 _gpio_set_ocr(port, index, GPIO_OUTPUT_DR);
292 case GPIO_MUX_INPUT1:
293 gius_reg |= (1L << index);
294 _gpio_set_iconfa(port, index, GPIO_INPUT_GPIO);
296 case GPIO_MUX_INPUT2:
297 gius_reg |= (1L << index);
298 _gpio_set_iconfb(port, index, GPIO_INPUT_GPIO);
300 case GPIO_MUX_OUTPUT1:
301 gius_reg |= (1L << index);
302 _gpio_set_ocr(port, index, GPIO_OUTPUT_A);
304 case GPIO_MUX_OUTPUT2:
305 gius_reg |= (1L << index);
306 _gpio_set_ocr(port, index, GPIO_OUTPUT_B);
308 case GPIO_MUX_OUTPUT3:
309 gius_reg |= (1L << index);
310 _gpio_set_ocr(port, index, GPIO_OUTPUT_C);
316 writel(gius_reg, port->base + GPIO_GIUS);
317 writel(gpr_reg, port->base + GPIO_GPR);
323 * This function is just used to enable or disable the pull up feature .
324 * @param pin a pin number as defined in \b #iomux_pin_name_t
325 * @param en 0 if disable, Non-zero enable
326 * @return 0 if successful, Non-zero otherwise
328 int gpio_set_puen(iomux_pin_name_t pin, bool en)
330 struct mxc_gpio_port *port;
331 u32 index, gpio = IOMUX_TO_GPIO(pin);
333 port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]);
334 index = GPIO_TO_INDEX(gpio);
336 // diag_printf("%s: Configuring output mode of PORT %c, bit %d\n",
337 // __FUNCTION__, port->num + 'A', index);
339 _gpio_set_puen(port, index, en);
345 * This function is just used to request a pin and configure it.
346 * @param pin a pin number as defined in \b #iomux_pin_name_t
347 * @param mode a module as define in \b #gpio_mux_mode_t;
348 * @return 0 if successful, Non-zero otherwise
350 int gpio_request_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode)
353 ret = mxc_request_gpio(pin);
355 ret = gpio_config_mux(pin, mode);
357 diag_printf("%s(pin=%d, mode=%d) failed\n", __FUNCTION__, pin, mode);