#ifndef _IPXE_GPIO_H #define _IPXE_GPIO_H /** @file * * General purpose I/O * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include #include /** 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 */