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/interrupt.h> 16 #include <linux/mutex.h> 17 #include <linux/types.h> 18 #include <linux/watchdog.h> 19 #include <linux/workqueue.h> 20 21 enum { 22 OMNIA_MCU_CRYPTO_PUBLIC_KEY_LEN = 1 + 32, 23 OMNIA_MCU_CRYPTO_SIGNATURE_LEN = 64, 24 }; 25 26 struct i2c_client; 27 struct rtc_device; 28 29 /** 30 * struct omnia_mcu - driver private data structure 31 * @client: I2C client 32 * @type: MCU type (STM32, GD32, MKL, or unknown) 33 * @features: bitmap of features supported by the MCU firmware 34 * @board_serial_number: board serial number, if stored in MCU 35 * @board_first_mac: board first MAC address, if stored in MCU 36 * @board_revision: board revision, if stored in MCU 37 * @gc: GPIO chip 38 * @lock: mutex to protect internal GPIO chip state 39 * @mask: bitmap of masked IRQs 40 * @rising: bitmap of rising edge IRQs 41 * @falling: bitmap of falling edge IRQs 42 * @both: bitmap of both edges IRQs 43 * @cached: bitmap of cached IRQ line values (when an IRQ line is configured for 44 * both edges, we cache the corresponding GPIO values in the IRQ 45 * handler) 46 * @is_cached: bitmap of which IRQ line values are cached 47 * @button_release_emul_work: front button release emulation work, used with old MCU firmware 48 * versions which did not send button release events, only button press 49 * events 50 * @last_status: cached value of the status word, to be compared with new value to 51 * determine which interrupt events occurred, used with old MCU 52 * firmware versions which only informed that the status word changed, 53 * but not which bits of the status word changed 54 * @button_pressed_emul: the front button is still emulated to be pressed 55 * @rtcdev: RTC device, does not actually count real-time, the device is only 56 * used for the RTC alarm mechanism, so that the board can be 57 * configured to wake up from poweroff state at a specific time 58 * @rtc_alarm: RTC alarm that was set for the board to wake up on, in MCU time 59 * (seconds since last MCU reset) 60 * @front_button_poweron: the front button should power on the device after it is powered off 61 * @wdt: watchdog driver structure 62 * @trng: RNG driver structure 63 * @trng_entropy_ready: RNG entropy ready completion 64 * @msg_signed: message signed completion 65 * @sign_lock: mutex to protect message signing state 66 * @sign_requested: flag indicating that message signing was requested but not completed 67 * @sign_err: message signing error number, filled in interrupt handler 68 * @signature: message signing signature, filled in interrupt handler 69 * @board_public_key: board public key, if stored in MCU 70 */ 71 struct omnia_mcu { 72 struct i2c_client *client; 73 const char *type; 74 u32 features; 75 76 u64 board_serial_number; 77 u8 board_first_mac[ETH_ALEN]; 78 u8 board_revision; 79 80 #ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO 81 struct gpio_chip gc; 82 struct mutex lock; 83 unsigned long mask, rising, falling, both, cached, is_cached; 84 struct delayed_work button_release_emul_work; 85 unsigned long last_status; 86 bool button_pressed_emul; 87 #endif 88 89 #ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP 90 struct rtc_device *rtcdev; 91 u32 rtc_alarm; 92 bool front_button_poweron; 93 #endif 94 95 #ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG 96 struct watchdog_device wdt; 97 #endif 98 99 #ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG 100 struct hwrng trng; 101 struct completion trng_entropy_ready; 102 #endif 103 104 #ifdef CONFIG_TURRIS_OMNIA_MCU_KEYCTL 105 struct completion msg_signed; 106 struct mutex sign_lock; 107 bool sign_requested; 108 int sign_err; 109 u8 signature[OMNIA_MCU_CRYPTO_SIGNATURE_LEN]; 110 u8 board_public_key[OMNIA_MCU_CRYPTO_PUBLIC_KEY_LEN]; 111 #endif 112 }; 113 114 #ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO 115 extern const struct attribute_group omnia_mcu_gpio_group; 116 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu); 117 int omnia_mcu_request_irq(struct omnia_mcu *mcu, u32 spec, 118 irq_handler_t thread_fn, const char *devname); 119 #else 120 static inline int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu) 121 { 122 return 0; 123 } 124 #endif 125 126 #ifdef CONFIG_TURRIS_OMNIA_MCU_KEYCTL 127 int omnia_mcu_register_keyctl(struct omnia_mcu *mcu); 128 #else 129 static inline int omnia_mcu_register_keyctl(struct omnia_mcu *mcu) 130 { 131 return 0; 132 } 133 #endif 134 135 #ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP 136 extern const struct attribute_group omnia_mcu_poweroff_group; 137 int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu); 138 #else 139 static inline int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu) 140 { 141 return 0; 142 } 143 #endif 144 145 #ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG 146 int omnia_mcu_register_trng(struct omnia_mcu *mcu); 147 #else 148 static inline int omnia_mcu_register_trng(struct omnia_mcu *mcu) 149 { 150 return 0; 151 } 152 #endif 153 154 #ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG 155 int omnia_mcu_register_watchdog(struct omnia_mcu *mcu); 156 #else 157 static inline int omnia_mcu_register_watchdog(struct omnia_mcu *mcu) 158 { 159 return 0; 160 } 161 #endif 162 163 #endif /* __TURRIS_OMNIA_MCU_H */ 164