]> Git Repo - linux.git/blob - drivers/platform/cznic/turris-omnia-mcu.h
ACPI: CPPC: Adjust debug messages in amd_set_max_freq_ratio() to warn
[linux.git] / drivers / platform / cznic / turris-omnia-mcu.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * CZ.NIC's Turris Omnia MCU driver
4  *
5  * 2024 by Marek BehĂșn <[email protected]>
6  */
7
8 #ifndef __TURRIS_OMNIA_MCU_H
9 #define __TURRIS_OMNIA_MCU_H
10
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 <asm/unaligned.h>
22
23 struct i2c_client;
24 struct rtc_device;
25
26 struct omnia_mcu {
27         struct i2c_client *client;
28         const char *type;
29         u32 features;
30
31         /* board information */
32         u64 board_serial_number;
33         u8 board_first_mac[ETH_ALEN];
34         u8 board_revision;
35
36         /* GPIO chip */
37         struct gpio_chip gc;
38         struct mutex lock;
39         unsigned long mask, rising, falling, both, cached, is_cached;
40         /* Old MCU firmware handling needs the following */
41         struct delayed_work button_release_emul_work;
42         unsigned long last_status;
43         bool button_pressed_emul;
44
45         /* RTC device for configuring wake-up */
46         struct rtc_device *rtcdev;
47         u32 rtc_alarm;
48         bool front_button_poweron;
49
50         /* MCU watchdog */
51         struct watchdog_device wdt;
52
53         /* true random number generator */
54         struct hwrng trng;
55         struct completion trng_entropy_ready;
56 };
57
58 int omnia_cmd_write_read(const struct i2c_client *client,
59                          void *cmd, unsigned int cmd_len,
60                          void *reply, unsigned int reply_len);
61
62 static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
63                                   unsigned int len)
64 {
65         return omnia_cmd_write_read(client, cmd, len, NULL, 0);
66 }
67
68 static inline int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd,
69                                      u8 val)
70 {
71         u8 buf[2] = { cmd, val };
72
73         return omnia_cmd_write(client, buf, sizeof(buf));
74 }
75
76 static inline int omnia_cmd_write_u16(const struct i2c_client *client, u8 cmd,
77                                       u16 val)
78 {
79         u8 buf[3];
80
81         buf[0] = cmd;
82         put_unaligned_le16(val, &buf[1]);
83
84         return omnia_cmd_write(client, buf, sizeof(buf));
85 }
86
87 static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
88                                       u32 val)
89 {
90         u8 buf[5];
91
92         buf[0] = cmd;
93         put_unaligned_le32(val, &buf[1]);
94
95         return omnia_cmd_write(client, buf, sizeof(buf));
96 }
97
98 static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
99                                  void *reply, unsigned int len)
100 {
101         return omnia_cmd_write_read(client, &cmd, 1, reply, len);
102 }
103
104 static inline unsigned int
105 omnia_compute_reply_length(unsigned long mask, bool interleaved,
106                            unsigned int offset)
107 {
108         if (!mask)
109                 return 0;
110
111         return ((__fls(mask) >> 3) << interleaved) + 1 + offset;
112 }
113
114 /* Returns 0 on success */
115 static inline int omnia_cmd_read_bits(const struct i2c_client *client, u8 cmd,
116                                       unsigned long bits, unsigned long *dst)
117 {
118         __le32 reply;
119         int err;
120
121         if (!bits) {
122                 *dst = 0;
123                 return 0;
124         }
125
126         err = omnia_cmd_read(client, cmd, &reply,
127                              omnia_compute_reply_length(bits, false, 0));
128         if (err)
129                 return err;
130
131         *dst = le32_to_cpu(reply) & bits;
132
133         return 0;
134 }
135
136 static inline int omnia_cmd_read_bit(const struct i2c_client *client, u8 cmd,
137                                      unsigned long bit)
138 {
139         unsigned long reply;
140         int err;
141
142         err = omnia_cmd_read_bits(client, cmd, bit, &reply);
143         if (err)
144                 return err;
145
146         return !!reply;
147 }
148
149 static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
150                                      u32 *dst)
151 {
152         __le32 reply;
153         int err;
154
155         err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
156         if (err)
157                 return err;
158
159         *dst = le32_to_cpu(reply);
160
161         return 0;
162 }
163
164 static inline int omnia_cmd_read_u16(const struct i2c_client *client, u8 cmd,
165                                      u16 *dst)
166 {
167         __le16 reply;
168         int err;
169
170         err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
171         if (err)
172                 return err;
173
174         *dst = le16_to_cpu(reply);
175
176         return 0;
177 }
178
179 static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
180                                     u8 *reply)
181 {
182         return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
183 }
184
185 extern const u8 omnia_int_to_gpio_idx[32];
186 extern const struct attribute_group omnia_mcu_gpio_group;
187 extern const struct attribute_group omnia_mcu_poweroff_group;
188
189 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
190 int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
191 int omnia_mcu_register_trng(struct omnia_mcu *mcu);
192 int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
193
194 #endif /* __TURRIS_OMNIA_MCU_H */
This page took 0.04575 seconds and 4 git commands to generate.