1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * CZ.NIC's Turris Omnia MCU driver 4 * 5 * 2024 by Marek Behún <kabel@kernel.org> 6 */ 7 8 #ifndef __TURRIS_OMNIA_MCU_H 9 #define __TURRIS_OMNIA_MCU_H 10 11 #include <linux/completion.h> 12 #include <linux/gpio/driver.h> 13 #include <linux/hw_random.h> 14 #include <linux/if_ether.h> 15 #include <linux/mutex.h> 16 #include <linux/types.h> 17 #include <linux/watchdog.h> 18 #include <linux/workqueue.h> 19 20 struct i2c_client; 21 struct rtc_device; 22 23 /** 24 * struct omnia_mcu - driver private data structure 25 * @client: I2C client 26 * @type: MCU type (STM32, GD32, MKL, or unknown) 27 * @features: bitmap of features supported by the MCU firmware 28 * @board_serial_number: board serial number, if stored in MCU 29 * @board_first_mac: board first MAC address, if stored in MCU 30 * @board_revision: board revision, if stored in MCU 31 * @gc: GPIO chip 32 * @lock: mutex to protect internal GPIO chip state 33 * @mask: bitmap of masked IRQs 34 * @rising: bitmap of rising edge IRQs 35 * @falling: bitmap of falling edge IRQs 36 * @both: bitmap of both edges IRQs 37 * @cached: bitmap of cached IRQ line values (when an IRQ line is configured for 38 * both edges, we cache the corresponding GPIO values in the IRQ 39 * handler) 40 * @is_cached: bitmap of which IRQ line values are cached 41 * @button_release_emul_work: front button release emulation work, used with old MCU firmware 42 * versions which did not send button release events, only button press 43 * events 44 * @last_status: cached value of the status word, to be compared with new value to 45 * determine which interrupt events occurred, used with old MCU 46 * firmware versions which only informed that the status word changed, 47 * but not which bits of the status word changed 48 * @button_pressed_emul: the front button is still emulated to be pressed 49 * @rtcdev: RTC device, does not actually count real-time, the device is only 50 * used for the RTC alarm mechanism, so that the board can be 51 * configured to wake up from poweroff state at a specific time 52 * @rtc_alarm: RTC alarm that was set for the board to wake up on, in MCU time 53 * (seconds since last MCU reset) 54 * @front_button_poweron: the front button should power on the device after it is powered off 55 * @wdt: watchdog driver structure 56 * @trng: RNG driver structure 57 * @trng_entropy_ready: RNG entropy ready completion 58 */ 59 struct omnia_mcu { 60 struct i2c_client *client; 61 const char *type; 62 u32 features; 63 64 u64 board_serial_number; 65 u8 board_first_mac[ETH_ALEN]; 66 u8 board_revision; 67 68 #ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO 69 struct gpio_chip gc; 70 struct mutex lock; 71 unsigned long mask, rising, falling, both, cached, is_cached; 72 struct delayed_work button_release_emul_work; 73 unsigned long last_status; 74 bool button_pressed_emul; 75 #endif 76 77 #ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP 78 struct rtc_device *rtcdev; 79 u32 rtc_alarm; 80 bool front_button_poweron; 81 #endif 82 83 #ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG 84 struct watchdog_device wdt; 85 #endif 86 87 #ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG 88 struct hwrng trng; 89 struct completion trng_entropy_ready; 90 #endif 91 }; 92 93 #ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO 94 extern const u8 omnia_int_to_gpio_idx[32]; 95 extern const struct attribute_group omnia_mcu_gpio_group; 96 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu); 97 #else 98 static inline int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu) 99 { 100 return 0; 101 } 102 #endif 103 104 #ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP 105 extern const struct attribute_group omnia_mcu_poweroff_group; 106 int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu); 107 #else 108 static inline int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu) 109 { 110 return 0; 111 } 112 #endif 113 114 #ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG 115 int omnia_mcu_register_trng(struct omnia_mcu *mcu); 116 #else 117 static inline int omnia_mcu_register_trng(struct omnia_mcu *mcu) 118 { 119 return 0; 120 } 121 #endif 122 123 #ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG 124 int omnia_mcu_register_watchdog(struct omnia_mcu *mcu); 125 #else 126 static inline int omnia_mcu_register_watchdog(struct omnia_mcu *mcu) 127 { 128 return 0; 129 } 130 #endif 131 132 #endif /* __TURRIS_OMNIA_MCU_H */ 133