/* * Copyright (C) 2008 STMicroelectronics Limited * Author: Pawel Moll * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. */ #ifndef __LINUX_STM_GPIO_H #define __LINUX_STM_GPIO_H #include #include #include /* Value indicating wrong GPIO number (gpio numbers are sadly unsigned...) */ #define STM_GPIO_INVALID (~0) /* STM SoCs organise GPIO lines into ports, 8 lines (pins) in each */ #define STM_GPIO_PINS_PER_PORT 8 /* The following macros help to get a gpio-space number * basing on the port/pin pair and vice-versa (assuming * that passed gpio number is really an internal one...) */ #define stm_gpio(port, pin) ((port) * STM_GPIO_PINS_PER_PORT + (pin)) #define stm_gpio_port(gpio) ((gpio) / STM_GPIO_PINS_PER_PORT) #define stm_gpio_pin(gpio) ((gpio) % STM_GPIO_PINS_PER_PORT) /* Here are the generic GPIO access functions, optimised for internal * PIOs and using the gpiolib calls for the rest */ #define STM_GPIO_REG_SET_POUT 0x04 #define STM_GPIO_REG_CLR_POUT 0x08 #define STM_GPIO_REG_PIN 0x10 extern int stm_gpio_num; /* Number of available internal PIOs */ extern void __iomem **stm_gpio_bases; /* PIO blocks base addresses array */ static inline int gpio_get_value(unsigned gpio) { if (likely(gpio < stm_gpio_num)) return (readl(stm_gpio_bases[stm_gpio_port(gpio)] + STM_GPIO_REG_PIN) & (1 << stm_gpio_pin(gpio))) != 0; else return __gpio_get_value(gpio); } static inline void gpio_set_value(unsigned gpio, int value) { if (likely(gpio < stm_gpio_num)) writel(1 << stm_gpio_pin(gpio), stm_gpio_bases[stm_gpio_port(gpio)] + (value ? STM_GPIO_REG_SET_POUT : STM_GPIO_REG_CLR_POUT)); else __gpio_set_value(gpio, value); } static inline int gpio_cansleep(unsigned gpio) { if (likely(gpio < stm_gpio_num)) return 0; else return __gpio_cansleep(gpio); } #define gpio_to_irq(gpio) __gpio_to_irq(gpio) /* The gpiolib doesn't provides irq support so the following * functions are valid for internal PIOs only */ int irq_to_gpio(unsigned irq); /* STM specific API */ /* Early initialisation */ void stm_gpio_early_init(struct platform_device pdevs[], int num, int irq_base); /* Pin direction control */ #define STM_GPIO_DIRECTION_BIDIR 0x1 #define STM_GPIO_DIRECTION_OUT 0x2 #define STM_GPIO_DIRECTION_IN 0x4 #define STM_GPIO_DIRECTION_ALT_OUT 0x6 #define STM_GPIO_DIRECTION_ALT_BIDIR 0x7 int stm_gpio_direction(unsigned int gpio, unsigned int direction); #endif