/* * Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef __CROS_EC_IOEXPANDER_H #define __CROS_EC_IOEXPANDER_H #ifdef CONFIG_ZEPHYR #define ioex_signal gpio_signal #include "gpio.h" #else enum ioex_signal; /* from gpio_signal.h */ #endif /* IO expander signal definition structure */ struct ioex_info { /* Signal name */ const char *name; /* IO expander port number */ uint16_t ioex; /* IO port number in IO expander */ uint16_t port; /* Bitmask on that port (1 << N) */ uint32_t mask; /* Flags - the same as the GPIO flags */ uint32_t flags; }; /* Signal information from board.c. Must match order from enum ioex_signal. */ extern const struct ioex_info ioex_list[]; extern void (*const ioex_irq_handlers[])(enum ioex_signal signal); extern const int ioex_ih_count; /* Get ioex_info structure for specified signal */ #define IOEX_GET_INFO(signal) (ioex_list + (signal)-IOEX_SIGNAL_START) struct ioexpander_drv { /* Initialize IO expander chip/driver */ int (*init)(int ioex); /* Get the current level of the IOEX pin */ int (*get_level)(int ioex, int port, int mask, int *val); /* Set the level of the IOEX pin */ int (*set_level)(int ioex, int port, int mask, int val); /* Get flags for the IOEX pin */ int (*get_flags_by_mask)(int ioex, int port, int mask, int *flags); /* Set flags for the IOEX pin */ int (*set_flags_by_mask)(int ioex, int port, int mask, int flags); /* Enable/disable interrupt for the IOEX pin */ int (*enable_interrupt)(int ioex, int port, int mask, int enable); #ifdef CONFIG_IO_EXPANDER_SUPPORT_GET_PORT /* Read levels for whole IOEX port */ int (*get_port)(int ioex, int port, int *val); #endif }; /* IO expander default init disabled. No I2C communication will be attempted. */ #define IOEX_FLAGS_DEFAULT_INIT_DISABLED BIT(0) /* IO Expander has been initialized */ #define IOEX_FLAGS_INITIALIZED BIT(1) /* * BITS 24 to 31 are used by io-expander drivers that need to control multiple * devices */ #define IOEX_FLAGS_CUSTOM_BIT(x) BUILD_CHECK_INLINE(BIT(x), BIT(x) & 0xff000000) struct ioexpander_config_t { /* Physical I2C port connects to the IO expander chip. */ int i2c_host_port; /* I2C address */ int i2c_addr_flags; /* * Pointer to the specific IO expander chip's ops defined in * the struct ioexpander_drv. */ const struct ioexpander_drv *drv; /* Config flags for this IO expander chip. See IOEX_FLAGS_* */ uint32_t flags; }; extern struct ioexpander_config_t ioex_config[]; #ifdef CONFIG_ZEPHYR #define ioex_enable_interrupt gpio_enable_interrupt #define ioex_disable_interrupt gpio_disable_interrupt #ifdef CONFIG_GPIO_GET_EXTENDED static inline int ioex_get_flags(enum gpio_signal signal, int *flags) { *flags = gpio_get_flags(signal); return EC_SUCCESS; } #endif static inline int ioex_set_flags(enum gpio_signal signal, int flags) { gpio_set_flags(signal, flags); return EC_SUCCESS; } static inline int ioex_get_level(enum gpio_signal signal, int *val) { *val = gpio_get_level(signal); return EC_SUCCESS; } static inline int ioex_set_level(enum gpio_signal signal, int val) { gpio_set_level(signal, val); return EC_SUCCESS; } int ioex_init(int ioex); static inline const char *ioex_get_name(enum ioex_signal signal) { return gpio_get_name(signal); } #else /* * Enable the interrupt for the IOEX signal * * @param signal IOEX signal to enable the interrupt * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_enable_interrupt(enum ioex_signal signal); /* * Disable the interrupt for the IOEX signal * * @param signal IOEX signal to disable the interrupt * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_disable_interrupt(enum ioex_signal signal); /* * Get io expander flags (IOEX_FLAGS_*) for chip that specified IOEX signal * belongs to. They contain information if port was disabled or initialized. * * @param signal IOEX signal that belongs to chip which flags will be returned * @param val Pointer to memory where flags will be stored * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_get_ioex_flags(enum ioex_signal signal, int *val); /* * Get flags for the IOEX signal * * @param signal IOEX signal to get flags for * @param flags Pointer to the keep the flags read * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_get_flags(enum ioex_signal signal, int *flags); /* * Set flags for the IOEX signal * * @param signal IOEX signal to set flags for * @param flags New flags for the IOEX signal * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_set_flags(enum ioex_signal signal, int flags); /* * Get the current level of the IOEX signal * * @param signal IOEX signal to get the level * @param val Pointer to the keep the level read * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_get_level(enum ioex_signal signal, int *val); /* * Set the level of the IOEX signal * * @param signal IOEX signal to set the level * @param value New level for the IOEX signal * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_set_level(enum ioex_signal signal, int value); #ifdef CONFIG_IO_EXPANDER_SUPPORT_GET_PORT /* * Get the current levels on the IOEX port * * @param ioex Number of I/O expander * @param port Number of port in ioex * @param val Pointer to variable where port will be read * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_get_port(int ioex, int port, int *val); #endif /* * Initialize IO expander chip/driver * * @param ioex IO expander chip's port number * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_init(int ioex); /* * Get the name for the IOEX signal * * @param signal IOEX signal to get the name * @returns name of the given IOEX signal */ const char *ioex_get_name(enum ioex_signal signal); /* * Check if signal is an IO expander signal or GPIO signal. * * @param signal GPIO or IOEX signal * @return 1 if signal is IOEX else return 0 */ int signal_is_ioex(int signal); /* * Save gpio state of IO expander * * @param ioex IO expander chip's port number * @param state Buffer to hold gpio state * @param state_len Length of state buffer, IOEX_COUNT is recommended * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_save_gpio_state(int ioex, int *state, int state_len); /* * Restore gpio state of IO expander * * @param ioex IO expander chip's port number * @param state Buffer with gpio state saved by ioex_save_gpio_state * @param state_len Length of state buffer, IOEX_COUNT is recommended * @return EC_SUCCESS if successful, non-zero if error. */ int ioex_restore_gpio_state(int ioex, const int *state, int state_len); #endif /* CONFIG_ZEPHYR */ #endif /* __CROS_EC_IOEXPANDER_H */