1 /* SPDX-License-Identifier: GPL-2.0 */
3 * CZ.NIC's Turris Omnia MCU driver
8 #ifndef __TURRIS_OMNIA_MCU_H
9 #define __TURRIS_OMNIA_MCU_H
11 #include <linux/bitops.h>
12 #include <linux/completion.h>
13 #include <linux/gpio/driver.h>
14 #include <linux/hw_random.h>
15 #include <linux/if_ether.h>
16 #include <linux/mutex.h>
17 #include <linux/types.h>
18 #include <linux/watchdog.h>
19 #include <linux/workqueue.h>
20 #include <asm/byteorder.h>
21 #include <linux/unaligned.h>
27 * struct omnia_mcu - driver private data structure
29 * @type: MCU type (STM32, GD32, MKL, or unknown)
30 * @features: bitmap of features supported by the MCU firmware
31 * @board_serial_number: board serial number, if stored in MCU
32 * @board_first_mac: board first MAC address, if stored in MCU
33 * @board_revision: board revision, if stored in MCU
35 * @lock: mutex to protect internal GPIO chip state
36 * @mask: bitmap of masked IRQs
37 * @rising: bitmap of rising edge IRQs
38 * @falling: bitmap of falling edge IRQs
39 * @both: bitmap of both edges IRQs
40 * @cached: bitmap of cached IRQ line values (when an IRQ line is configured for
41 * both edges, we cache the corresponding GPIO values in the IRQ
43 * @is_cached: bitmap of which IRQ line values are cached
44 * @button_release_emul_work: front button release emulation work, used with old MCU firmware
45 * versions which did not send button release events, only button press
47 * @last_status: cached value of the status word, to be compared with new value to
48 * determine which interrupt events occurred, used with old MCU
49 * firmware versions which only informed that the status word changed,
50 * but not which bits of the status word changed
51 * @button_pressed_emul: the front button is still emulated to be pressed
52 * @rtcdev: RTC device, does not actually count real-time, the device is only
53 * used for the RTC alarm mechanism, so that the board can be
54 * configured to wake up from poweroff state at a specific time
55 * @rtc_alarm: RTC alarm that was set for the board to wake up on, in MCU time
56 * (seconds since last MCU reset)
57 * @front_button_poweron: the front button should power on the device after it is powered off
58 * @wdt: watchdog driver structure
59 * @trng: RNG driver structure
60 * @trng_entropy_ready: RNG entropy ready completion
63 struct i2c_client *client;
67 u64 board_serial_number;
68 u8 board_first_mac[ETH_ALEN];
71 #ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO
74 unsigned long mask, rising, falling, both, cached, is_cached;
75 struct delayed_work button_release_emul_work;
76 unsigned long last_status;
77 bool button_pressed_emul;
80 #ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP
81 struct rtc_device *rtcdev;
83 bool front_button_poweron;
86 #ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG
87 struct watchdog_device wdt;
90 #ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG
92 struct completion trng_entropy_ready;
96 int omnia_cmd_write_read(const struct i2c_client *client,
97 void *cmd, unsigned int cmd_len,
98 void *reply, unsigned int reply_len);
100 static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
103 return omnia_cmd_write_read(client, cmd, len, NULL, 0);
106 static inline int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd,
109 u8 buf[2] = { cmd, val };
111 return omnia_cmd_write(client, buf, sizeof(buf));
114 static inline int omnia_cmd_write_u16(const struct i2c_client *client, u8 cmd,
120 put_unaligned_le16(val, &buf[1]);
122 return omnia_cmd_write(client, buf, sizeof(buf));
125 static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
131 put_unaligned_le32(val, &buf[1]);
133 return omnia_cmd_write(client, buf, sizeof(buf));
136 static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
137 void *reply, unsigned int len)
139 return omnia_cmd_write_read(client, &cmd, 1, reply, len);
142 static inline unsigned int
143 omnia_compute_reply_length(unsigned long mask, bool interleaved,
149 return ((__fls(mask) >> 3) << interleaved) + 1 + offset;
152 /* Returns 0 on success */
153 static inline int omnia_cmd_read_bits(const struct i2c_client *client, u8 cmd,
154 unsigned long bits, unsigned long *dst)
164 err = omnia_cmd_read(client, cmd, &reply,
165 omnia_compute_reply_length(bits, false, 0));
169 *dst = le32_to_cpu(reply) & bits;
174 static inline int omnia_cmd_read_bit(const struct i2c_client *client, u8 cmd,
180 err = omnia_cmd_read_bits(client, cmd, bit, &reply);
187 static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
193 err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
197 *dst = le32_to_cpu(reply);
202 static inline int omnia_cmd_read_u16(const struct i2c_client *client, u8 cmd,
208 err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
212 *dst = le16_to_cpu(reply);
217 static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
220 return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
223 #ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO
224 extern const u8 omnia_int_to_gpio_idx[32];
225 extern const struct attribute_group omnia_mcu_gpio_group;
226 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
228 static inline int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu)
234 #ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP
235 extern const struct attribute_group omnia_mcu_poweroff_group;
236 int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
238 static inline int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu)
244 #ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG
245 int omnia_mcu_register_trng(struct omnia_mcu *mcu);
247 static inline int omnia_mcu_register_trng(struct omnia_mcu *mcu)
253 #ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG
254 int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
256 static inline int omnia_mcu_register_watchdog(struct omnia_mcu *mcu)
262 #endif /* __TURRIS_OMNIA_MCU_H */