93 lines
2.5 KiB
C
93 lines
2.5 KiB
C
/*
|
|
* Copyright (C) 2008 STMicroelectronics Limited
|
|
* Author: Pawel Moll <pawel.moll@st.com>
|
|
*
|
|
* 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 <linux/io.h>
|
|
#include <linux/platform_device.h>
|
|
#include <asm-generic/gpio.h>
|
|
|
|
|
|
|
|
/* 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
|