2024-07-01 13:30:04 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
/*
|
|
|
|
* CZ.NIC's Turris Omnia MCU driver
|
|
|
|
*
|
|
|
|
* 2024 by Marek Behún <kabel@kernel.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __TURRIS_OMNIA_MCU_H
|
|
|
|
#define __TURRIS_OMNIA_MCU_H
|
|
|
|
|
2024-07-01 13:30:08 +02:00
|
|
|
#include <linux/completion.h>
|
2024-07-01 13:30:05 +02:00
|
|
|
#include <linux/gpio/driver.h>
|
2024-07-01 13:30:08 +02:00
|
|
|
#include <linux/hw_random.h>
|
2024-07-01 13:30:04 +02:00
|
|
|
#include <linux/if_ether.h>
|
2025-02-04 14:14:11 +01:00
|
|
|
#include <linux/interrupt.h>
|
2024-07-01 13:30:05 +02:00
|
|
|
#include <linux/mutex.h>
|
2024-07-01 13:30:04 +02:00
|
|
|
#include <linux/types.h>
|
2024-07-01 13:30:07 +02:00
|
|
|
#include <linux/watchdog.h>
|
2024-07-01 13:30:05 +02:00
|
|
|
#include <linux/workqueue.h>
|
2024-07-01 13:30:04 +02:00
|
|
|
|
2025-02-04 14:14:13 +01:00
|
|
|
enum {
|
|
|
|
OMNIA_MCU_CRYPTO_PUBLIC_KEY_LEN = 1 + 32,
|
|
|
|
OMNIA_MCU_CRYPTO_SIGNATURE_LEN = 64,
|
|
|
|
};
|
|
|
|
|
2024-07-01 13:30:04 +02:00
|
|
|
struct i2c_client;
|
2024-07-01 13:30:06 +02:00
|
|
|
struct rtc_device;
|
2024-07-01 13:30:04 +02:00
|
|
|
|
2024-11-11 11:39:57 +01:00
|
|
|
/**
|
|
|
|
* struct omnia_mcu - driver private data structure
|
|
|
|
* @client: I2C client
|
|
|
|
* @type: MCU type (STM32, GD32, MKL, or unknown)
|
|
|
|
* @features: bitmap of features supported by the MCU firmware
|
|
|
|
* @board_serial_number: board serial number, if stored in MCU
|
|
|
|
* @board_first_mac: board first MAC address, if stored in MCU
|
|
|
|
* @board_revision: board revision, if stored in MCU
|
|
|
|
* @gc: GPIO chip
|
|
|
|
* @lock: mutex to protect internal GPIO chip state
|
|
|
|
* @mask: bitmap of masked IRQs
|
|
|
|
* @rising: bitmap of rising edge IRQs
|
|
|
|
* @falling: bitmap of falling edge IRQs
|
|
|
|
* @both: bitmap of both edges IRQs
|
|
|
|
* @cached: bitmap of cached IRQ line values (when an IRQ line is configured for
|
|
|
|
* both edges, we cache the corresponding GPIO values in the IRQ
|
|
|
|
* handler)
|
|
|
|
* @is_cached: bitmap of which IRQ line values are cached
|
|
|
|
* @button_release_emul_work: front button release emulation work, used with old MCU firmware
|
|
|
|
* versions which did not send button release events, only button press
|
|
|
|
* events
|
|
|
|
* @last_status: cached value of the status word, to be compared with new value to
|
|
|
|
* determine which interrupt events occurred, used with old MCU
|
|
|
|
* firmware versions which only informed that the status word changed,
|
|
|
|
* but not which bits of the status word changed
|
|
|
|
* @button_pressed_emul: the front button is still emulated to be pressed
|
|
|
|
* @rtcdev: RTC device, does not actually count real-time, the device is only
|
|
|
|
* used for the RTC alarm mechanism, so that the board can be
|
|
|
|
* configured to wake up from poweroff state at a specific time
|
|
|
|
* @rtc_alarm: RTC alarm that was set for the board to wake up on, in MCU time
|
|
|
|
* (seconds since last MCU reset)
|
|
|
|
* @front_button_poweron: the front button should power on the device after it is powered off
|
|
|
|
* @wdt: watchdog driver structure
|
|
|
|
* @trng: RNG driver structure
|
|
|
|
* @trng_entropy_ready: RNG entropy ready completion
|
2025-02-04 14:14:13 +01:00
|
|
|
* @msg_signed: message signed completion
|
|
|
|
* @sign_lock: mutex to protect message signing state
|
|
|
|
* @sign_requested: flag indicating that message signing was requested but not completed
|
|
|
|
* @sign_err: message signing error number, filled in interrupt handler
|
|
|
|
* @signature: message signing signature, filled in interrupt handler
|
|
|
|
* @board_public_key: board public key, if stored in MCU
|
2024-11-11 11:39:57 +01:00
|
|
|
*/
|
2024-07-01 13:30:04 +02:00
|
|
|
struct omnia_mcu {
|
|
|
|
struct i2c_client *client;
|
|
|
|
const char *type;
|
|
|
|
u32 features;
|
|
|
|
|
|
|
|
u64 board_serial_number;
|
|
|
|
u8 board_first_mac[ETH_ALEN];
|
|
|
|
u8 board_revision;
|
2024-07-01 13:30:05 +02:00
|
|
|
|
2024-07-19 10:57:56 +02:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO
|
2024-07-01 13:30:05 +02:00
|
|
|
struct gpio_chip gc;
|
|
|
|
struct mutex lock;
|
|
|
|
unsigned long mask, rising, falling, both, cached, is_cached;
|
|
|
|
struct delayed_work button_release_emul_work;
|
|
|
|
unsigned long last_status;
|
|
|
|
bool button_pressed_emul;
|
2024-07-19 10:57:56 +02:00
|
|
|
#endif
|
2024-07-01 13:30:06 +02:00
|
|
|
|
2024-07-19 10:57:55 +02:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP
|
2024-07-01 13:30:06 +02:00
|
|
|
struct rtc_device *rtcdev;
|
|
|
|
u32 rtc_alarm;
|
|
|
|
bool front_button_poweron;
|
2024-07-19 10:57:55 +02:00
|
|
|
#endif
|
2024-07-01 13:30:07 +02:00
|
|
|
|
2024-07-19 10:57:53 +02:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG
|
2024-07-01 13:30:07 +02:00
|
|
|
struct watchdog_device wdt;
|
2024-07-19 10:57:53 +02:00
|
|
|
#endif
|
2024-07-01 13:30:08 +02:00
|
|
|
|
2024-07-19 10:57:54 +02:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG
|
2024-07-01 13:30:08 +02:00
|
|
|
struct hwrng trng;
|
|
|
|
struct completion trng_entropy_ready;
|
2024-07-19 10:57:54 +02:00
|
|
|
#endif
|
2025-02-04 14:14:13 +01:00
|
|
|
|
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_KEYCTL
|
|
|
|
struct completion msg_signed;
|
|
|
|
struct mutex sign_lock;
|
|
|
|
bool sign_requested;
|
|
|
|
int sign_err;
|
|
|
|
u8 signature[OMNIA_MCU_CRYPTO_SIGNATURE_LEN];
|
|
|
|
u8 board_public_key[OMNIA_MCU_CRYPTO_PUBLIC_KEY_LEN];
|
|
|
|
#endif
|
2024-07-01 13:30:04 +02:00
|
|
|
};
|
|
|
|
|
2024-07-19 10:57:56 +02:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO
|
2024-07-01 13:30:05 +02:00
|
|
|
extern const struct attribute_group omnia_mcu_gpio_group;
|
|
|
|
int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
|
2025-02-04 14:14:11 +01:00
|
|
|
int omnia_mcu_request_irq(struct omnia_mcu *mcu, u32 spec,
|
|
|
|
irq_handler_t thread_fn, const char *devname);
|
2024-07-19 10:57:56 +02:00
|
|
|
#else
|
|
|
|
static inline int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2024-07-19 10:57:55 +02:00
|
|
|
|
2025-02-04 14:14:13 +01:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_KEYCTL
|
|
|
|
int omnia_mcu_register_keyctl(struct omnia_mcu *mcu);
|
|
|
|
#else
|
|
|
|
static inline int omnia_mcu_register_keyctl(struct omnia_mcu *mcu)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-07-19 10:57:55 +02:00
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP
|
|
|
|
extern const struct attribute_group omnia_mcu_poweroff_group;
|
2024-07-01 13:30:06 +02:00
|
|
|
int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
|
2024-07-19 10:57:55 +02:00
|
|
|
#else
|
|
|
|
static inline int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2024-07-19 10:57:54 +02:00
|
|
|
|
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG
|
2024-07-01 13:30:08 +02:00
|
|
|
int omnia_mcu_register_trng(struct omnia_mcu *mcu);
|
2024-07-19 10:57:54 +02:00
|
|
|
#else
|
|
|
|
static inline int omnia_mcu_register_trng(struct omnia_mcu *mcu)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2024-07-19 10:57:53 +02:00
|
|
|
|
|
|
|
#ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG
|
2024-07-01 13:30:07 +02:00
|
|
|
int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
|
2024-07-19 10:57:53 +02:00
|
|
|
#else
|
|
|
|
static inline int omnia_mcu_register_watchdog(struct omnia_mcu *mcu)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2024-07-01 13:30:05 +02:00
|
|
|
|
2024-07-01 13:30:04 +02:00
|
|
|
#endif /* __TURRIS_OMNIA_MCU_H */
|