summaryrefslogtreecommitdiff
path: root/drivers/platform/cznic/turris-omnia-mcu.h
blob: 088541be3f4cc045cbce5b5aaeaac8eb6162a8d3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* 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

#include <linux/completion.h>
#include <linux/gpio/driver.h>
#include <linux/hw_random.h>
#include <linux/if_ether.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/workqueue.h>

struct i2c_client;
struct rtc_device;

/**
 * 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
 */
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;

#ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO
	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;
#endif

#ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP
	struct rtc_device *rtcdev;
	u32 rtc_alarm;
	bool front_button_poweron;
#endif

#ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG
	struct watchdog_device wdt;
#endif

#ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG
	struct hwrng trng;
	struct completion trng_entropy_ready;
#endif
};

#ifdef CONFIG_TURRIS_OMNIA_MCU_GPIO
extern const u8 omnia_int_to_gpio_idx[32];
extern const struct attribute_group omnia_mcu_gpio_group;
int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
#else
static inline int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu)
{
	return 0;
}
#endif

#ifdef CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP
extern const struct attribute_group omnia_mcu_poweroff_group;
int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
#else
static inline int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu)
{
	return 0;
}
#endif

#ifdef CONFIG_TURRIS_OMNIA_MCU_TRNG
int omnia_mcu_register_trng(struct omnia_mcu *mcu);
#else
static inline int omnia_mcu_register_trng(struct omnia_mcu *mcu)
{
	return 0;
}
#endif

#ifdef CONFIG_TURRIS_OMNIA_MCU_WATCHDOG
int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
#else
static inline int omnia_mcu_register_watchdog(struct omnia_mcu *mcu)
{
	return 0;
}
#endif

#endif /* __TURRIS_OMNIA_MCU_H */