diff options
Diffstat (limited to 'src/include/ipxe/gpio.h')
| -rw-r--r-- | src/include/ipxe/gpio.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/include/ipxe/gpio.h b/src/include/ipxe/gpio.h new file mode 100644 index 000000000..fa9e19089 --- /dev/null +++ b/src/include/ipxe/gpio.h @@ -0,0 +1,199 @@ +#ifndef _IPXE_GPIO_H +#define _IPXE_GPIO_H + +/** @file + * + * General purpose I/O + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> +#include <ipxe/list.h> +#include <ipxe/refcnt.h> +#include <ipxe/device.h> + +/** A GPIO pin */ +struct gpio { + /** GPIO controller */ + struct gpios *gpios; + /** Pin index */ + unsigned int index; + /** Configuration */ + unsigned int config; +}; + +/** GPIO is active low + * + * This bit is chosen to match the devicetree standard usage. + */ +#define GPIO_CFG_ACTIVE_LOW 0x01 + +/** GPIO is an output */ +#define GPIO_CFG_OUTPUT 0x0100 + +/** A GPIO controller */ +struct gpios { + /** Reference count */ + struct refcnt refcnt; + /** List of GPIO controllers */ + struct list_head list; + /** Generic device */ + struct device *dev; + /** Number of GPIOs */ + unsigned int count; + + /** Individual GPIOs */ + struct gpio *gpio; + /** GPIO operations */ + struct gpio_operations *op; + + /** Driver-private data */ + void *priv; +}; + +/** GPIO operations */ +struct gpio_operations { + /** + * Get current GPIO input value + * + * @v gpios GPIO controller + * @v gpio GPIO pin + * @ret active Pin is in the active state + */ + int ( * in ) ( struct gpios *gpios, struct gpio *gpio ); + /** + * Set current GPIO output value + * + * @v gpios GPIO controller + * @v gpio GPIO pin + * @v active Set pin to active state + */ + void ( * out ) ( struct gpios *gpios, struct gpio *gpio, int active ); + /** + * Configure GPIO pin + * + * @v gpios GPIO controller + * @v gpio GPIO pin + * @v config Configuration + * @ret rc Return status code + */ + int ( * config ) ( struct gpios *gpios, struct gpio *gpio, + unsigned int config ); +}; + +extern struct gpio_operations null_gpio_operations; + +/** + * Get reference to GPIO controller + * + * @v gpios GPIO controller + * @ret gpios GPIO controller + */ +static inline __attribute__ (( always_inline )) struct gpios * +gpios_get ( struct gpios *gpios ) { + ref_get ( &gpios->refcnt ); + return gpios; +} + +/** + * Drop reference to GPIO controller + * + * @v gpios GPIO controller + */ +static inline __attribute__ (( always_inline )) void +gpios_put ( struct gpios *gpios ) { + ref_put ( &gpios->refcnt ); +} + +/** + * Get reference to GPIO pin + * + * @v gpio GPIO pin + * @ret gpio GPIO pin + */ +static inline __attribute__ (( always_inline )) struct gpio * +gpio_get ( struct gpio *gpio ) { + gpios_get ( gpio->gpios ); + return gpio; +} + +/** + * Drop reference to GPIO ping + * + * @v gpio GPIO pin + */ +static inline __attribute__ (( always_inline )) void +gpio_put ( struct gpio *gpio ) { + gpios_put ( gpio->gpios ); +} + +/** + * Initialise a GPIO controller + * + * @v gpios GPIO controller + * @v op GPIO operations + */ +static inline __attribute__ (( always_inline )) void +gpios_init ( struct gpios *gpios, struct gpio_operations *op ) { + gpios->op = op; +} + +/** + * Stop using a GPIO controller + * + * @v gpios GPIO controller + * + * Drivers should call this method immediately before the final call + * to gpios_put(). + */ +static inline __attribute__ (( always_inline )) void +gpios_nullify ( struct gpios *gpios ) { + gpios->op = &null_gpio_operations; +} + +/** + * Get current GPIO input value + * + * @v gpio GPIO pin + * @ret active Pin is in the active state + */ +static inline int gpio_in ( struct gpio *gpio ) { + struct gpios *gpios = gpio->gpios; + + return gpios->op->in ( gpios, gpio ); +} + +/** + * Set current GPIO output value + * + * @v gpio GPIO pin + * @v active Set pin to active state + */ +static inline void gpio_out ( struct gpio *gpio, int active ) { + struct gpios *gpios = gpio->gpios; + + gpios->op->out ( gpios, gpio, active ); +} + +/** + * Configure GPIO pin + * + * @v gpio GPIO pin + * @v config Configuration + * @ret rc Return status code + */ +static inline int gpio_config ( struct gpio *gpio, unsigned int config ) { + struct gpios *gpios = gpio->gpios; + + return gpios->op->config ( gpios, gpio, config ); +} + +extern struct gpios * alloc_gpios ( unsigned int count, size_t priv_len ); +extern int gpios_register ( struct gpios *gpios ); +extern void gpios_unregister ( struct gpios *gpios ); +extern struct gpios * gpios_find ( unsigned int bus_type, + unsigned int location ); + +#endif /* _IPXE_GPIO_H */ |
