File Index
Files and directories
Sign in
FILE

turris-omnia-mcu-interface.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/turris-omnia-mcu-interface.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * CZ.NIC's Turris Omnia MCU I2C interface commands definitions
  4 *
  5 * 2024 by Marek BehĂșn <kabel@kernel.org>
  6 */
  7
  8#ifndef __TURRIS_OMNIA_MCU_INTERFACE_H
  9#define __TURRIS_OMNIA_MCU_INTERFACE_H
 10
 11#include <linux/bitfield.h>
 12#include <linux/bitops.h>
 13#include <linux/types.h>
 14#include <linux/unaligned.h>
 15#include <asm/byteorder.h>
 16
 17enum omnia_commands_e {
 18	OMNIA_CMD_GET_STATUS_WORD		= 0x01, /* slave sends status word back */
 19	OMNIA_CMD_GENERAL_CONTROL		= 0x02,
 20	OMNIA_CMD_LED_MODE			= 0x03, /* default/user */
 21	OMNIA_CMD_LED_STATE			= 0x04, /* LED on/off */
 22	OMNIA_CMD_LED_COLOR			= 0x05, /* LED number + RED + GREEN + BLUE */
 23	OMNIA_CMD_USER_VOLTAGE			= 0x06,
 24	OMNIA_CMD_SET_BRIGHTNESS		= 0x07,
 25	OMNIA_CMD_GET_BRIGHTNESS		= 0x08,
 26	OMNIA_CMD_GET_RESET			= 0x09,
 27	OMNIA_CMD_GET_FW_VERSION_APP		= 0x0A, /* 20B git hash number */
 28	OMNIA_CMD_SET_WATCHDOG_STATE		= 0x0B, /* 0 - disable
 29							 * 1 - enable / ping
 30							 * after boot watchdog is started
 31							 * with 2 minutes timeout
 32							 */
 33
 34	/* OMNIA_CMD_WATCHDOG_STATUS		= 0x0C, not implemented anymore */
 35
 36	OMNIA_CMD_GET_WATCHDOG_STATE		= 0x0D,
 37	OMNIA_CMD_GET_FW_VERSION_BOOT		= 0x0E, /* 20B Git hash number */
 38	OMNIA_CMD_GET_FW_CHECKSUM		= 0x0F, /* 4B length, 4B checksum */
 39
 40	/* available if FEATURES_SUPPORTED bit set in status word */
 41	OMNIA_CMD_GET_FEATURES			= 0x10,
 42
 43	/* available if EXT_CMD bit set in features */
 44	OMNIA_CMD_GET_EXT_STATUS_DWORD		= 0x11,
 45	OMNIA_CMD_EXT_CONTROL			= 0x12,
 46	OMNIA_CMD_GET_EXT_CONTROL_STATUS	= 0x13,
 47
 48	/* available if NEW_INT_API bit set in features */
 49	OMNIA_CMD_GET_INT_AND_CLEAR		= 0x14,
 50	OMNIA_CMD_GET_INT_MASK			= 0x15,
 51	OMNIA_CMD_SET_INT_MASK			= 0x16,
 52
 53	/* available if FLASHING bit set in features */
 54	OMNIA_CMD_FLASH				= 0x19,
 55
 56	/* available if WDT_PING bit set in features */
 57	OMNIA_CMD_SET_WDT_TIMEOUT		= 0x20,
 58	OMNIA_CMD_GET_WDT_TIMELEFT		= 0x21,
 59
 60	/* available if POWEROFF_WAKEUP bit set in features */
 61	OMNIA_CMD_SET_WAKEUP			= 0x22,
 62	OMNIA_CMD_GET_UPTIME_AND_WAKEUP		= 0x23,
 63	OMNIA_CMD_POWER_OFF			= 0x24,
 64
 65	/* available if USB_OVC_PROT_SETTING bit set in features */
 66	OMNIA_CMD_SET_USB_OVC_PROT		= 0x25,
 67	OMNIA_CMD_GET_USB_OVC_PROT		= 0x26,
 68
 69	/* available if TRNG bit set in features */
 70	OMNIA_CMD_TRNG_COLLECT_ENTROPY		= 0x28,
 71
 72	/* available if CRYPTO bit set in features */
 73	OMNIA_CMD_CRYPTO_GET_PUBLIC_KEY		= 0x29,
 74	OMNIA_CMD_CRYPTO_SIGN_MESSAGE		= 0x2A,
 75	OMNIA_CMD_CRYPTO_COLLECT_SIGNATURE	= 0x2B,
 76
 77	/* available if BOARD_INFO it set in features */
 78	OMNIA_CMD_BOARD_INFO_GET		= 0x2C,
 79	OMNIA_CMD_BOARD_INFO_BURN		= 0x2D,
 80
 81	/* available only at address 0x2b (LED-controller) */
 82	/* available only if LED_GAMMA_CORRECTION bit set in features */
 83	OMNIA_CMD_SET_GAMMA_CORRECTION		= 0x30,
 84	OMNIA_CMD_GET_GAMMA_CORRECTION		= 0x31,
 85
 86	/* available only at address 0x2b (LED-controller) */
 87	/* available only if PER_LED_CORRECTION bit set in features */
 88	/* available only if FROM_BIT_16_INVALID bit NOT set in features */
 89	OMNIA_CMD_SET_LED_CORRECTIONS		= 0x32,
 90	OMNIA_CMD_GET_LED_CORRECTIONS		= 0x33,
 91};
 92
 93enum omnia_flashing_commands_e {
 94	OMNIA_FLASH_CMD_UNLOCK		= 0x01,
 95	OMNIA_FLASH_CMD_SIZE_AND_CSUM	= 0x02,
 96	OMNIA_FLASH_CMD_PROGRAM		= 0x03,
 97	OMNIA_FLASH_CMD_RESET		= 0x04,
 98};
 99
100enum omnia_sts_word_e {
101	OMNIA_STS_MCU_TYPE_MASK			= GENMASK(1, 0),
102	OMNIA_STS_MCU_TYPE_STM32		= FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 0),
103	OMNIA_STS_MCU_TYPE_GD32			= FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 1),
104	OMNIA_STS_MCU_TYPE_MKL			= FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 2),
105	OMNIA_STS_FEATURES_SUPPORTED		= BIT(2),
106	OMNIA_STS_USER_REGULATOR_NOT_SUPPORTED	= BIT(3),
107	OMNIA_STS_CARD_DET			= BIT(4),
108	OMNIA_STS_MSATA_IND			= BIT(5),
109	OMNIA_STS_USB30_OVC			= BIT(6),
110	OMNIA_STS_USB31_OVC			= BIT(7),
111	OMNIA_STS_USB30_PWRON			= BIT(8),
112	OMNIA_STS_USB31_PWRON			= BIT(9),
113	OMNIA_STS_ENABLE_4V5			= BIT(10),
114	OMNIA_STS_BUTTON_MODE			= BIT(11),
115	OMNIA_STS_BUTTON_PRESSED		= BIT(12),
116	OMNIA_STS_BUTTON_COUNTER_MASK		= GENMASK(15, 13),
117};
118
119enum omnia_ctl_byte_e {
120	OMNIA_CTL_LIGHT_RST	= BIT(0),
121	OMNIA_CTL_HARD_RST	= BIT(1),
122	/* BIT(2) is currently reserved */
123	OMNIA_CTL_USB30_PWRON	= BIT(3),
124	OMNIA_CTL_USB31_PWRON	= BIT(4),
125	OMNIA_CTL_ENABLE_4V5	= BIT(5),
126	OMNIA_CTL_BUTTON_MODE	= BIT(6),
127	OMNIA_CTL_BOOTLOADER	= BIT(7),
128};
129
130enum omnia_features_e {
131	OMNIA_FEAT_PERIPH_MCU		= BIT(0),
132	OMNIA_FEAT_EXT_CMDS		= BIT(1),
133	OMNIA_FEAT_WDT_PING		= BIT(2),
134	OMNIA_FEAT_LED_STATE_EXT_MASK	= GENMASK(4, 3),
135	OMNIA_FEAT_LED_STATE_EXT	= FIELD_PREP_CONST(OMNIA_FEAT_LED_STATE_EXT_MASK, 1),
136	OMNIA_FEAT_LED_STATE_EXT_V32	= FIELD_PREP_CONST(OMNIA_FEAT_LED_STATE_EXT_MASK, 2),
137	OMNIA_FEAT_LED_GAMMA_CORRECTION	= BIT(5),
138	OMNIA_FEAT_NEW_INT_API		= BIT(6),
139	OMNIA_FEAT_BOOTLOADER		= BIT(7),
140	OMNIA_FEAT_FLASHING		= BIT(8),
141	OMNIA_FEAT_NEW_MESSAGE_API	= BIT(9),
142	OMNIA_FEAT_BRIGHTNESS_INT	= BIT(10),
143	OMNIA_FEAT_POWEROFF_WAKEUP	= BIT(11),
144	OMNIA_FEAT_CAN_OLD_MESSAGE_API	= BIT(12),
145	OMNIA_FEAT_TRNG			= BIT(13),
146	OMNIA_FEAT_CRYPTO		= BIT(14),
147	OMNIA_FEAT_BOARD_INFO		= BIT(15),
148
149	/*
150	 * Orginally the features command replied only 16 bits. If more were
151	 * read, either the I2C transaction failed or 0xff bytes were sent.
152	 * Therefore to consider bits 16 - 31 valid, one bit (20) was reserved
153	 * to be zero.
154	 */
155
156	/* Bits 16 - 19 correspond to bits 0 - 3 of status word */
157	OMNIA_FEAT_MCU_TYPE_MASK		= GENMASK(17, 16),
158	OMNIA_FEAT_MCU_TYPE_STM32		= FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 0),
159	OMNIA_FEAT_MCU_TYPE_GD32		= FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 1),
160	OMNIA_FEAT_MCU_TYPE_MKL			= FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 2),
161	OMNIA_FEAT_FEATURES_SUPPORTED		= BIT(18),
162	OMNIA_FEAT_USER_REGULATOR_NOT_SUPPORTED	= BIT(19),
163
164	/* must not be set */
165	OMNIA_FEAT_FROM_BIT_16_INVALID	= BIT(20),
166
167	OMNIA_FEAT_PER_LED_CORRECTION	= BIT(21),
168	OMNIA_FEAT_USB_OVC_PROT_SETTING	= BIT(22),
169};
170
171enum omnia_ext_sts_dword_e {
172	OMNIA_EXT_STS_SFP_nDET		= BIT(0),
173	OMNIA_EXT_STS_LED_STATES_MASK	= GENMASK(31, 12),
174	OMNIA_EXT_STS_WLAN0_MSATA_LED	= BIT(12),
175	OMNIA_EXT_STS_WLAN1_LED		= BIT(13),
176	OMNIA_EXT_STS_WLAN2_LED		= BIT(14),
177	OMNIA_EXT_STS_WPAN0_LED		= BIT(15),
178	OMNIA_EXT_STS_WPAN1_LED		= BIT(16),
179	OMNIA_EXT_STS_WPAN2_LED		= BIT(17),
180	OMNIA_EXT_STS_WAN_LED0		= BIT(18),
181	OMNIA_EXT_STS_WAN_LED1		= BIT(19),
182	OMNIA_EXT_STS_LAN0_LED0		= BIT(20),
183	OMNIA_EXT_STS_LAN0_LED1		= BIT(21),
184	OMNIA_EXT_STS_LAN1_LED0		= BIT(22),
185	OMNIA_EXT_STS_LAN1_LED1		= BIT(23),
186	OMNIA_EXT_STS_LAN2_LED0		= BIT(24),
187	OMNIA_EXT_STS_LAN2_LED1		= BIT(25),
188	OMNIA_EXT_STS_LAN3_LED0		= BIT(26),
189	OMNIA_EXT_STS_LAN3_LED1		= BIT(27),
190	OMNIA_EXT_STS_LAN4_LED0		= BIT(28),
191	OMNIA_EXT_STS_LAN4_LED1		= BIT(29),
192	OMNIA_EXT_STS_LAN5_LED0		= BIT(30),
193	OMNIA_EXT_STS_LAN5_LED1		= BIT(31),
194};
195
196enum omnia_ext_ctl_e {
197	OMNIA_EXT_CTL_nRES_MMC		= BIT(0),
198	OMNIA_EXT_CTL_nRES_LAN		= BIT(1),
199	OMNIA_EXT_CTL_nRES_PHY		= BIT(2),
200	OMNIA_EXT_CTL_nPERST0		= BIT(3),
201	OMNIA_EXT_CTL_nPERST1		= BIT(4),
202	OMNIA_EXT_CTL_nPERST2		= BIT(5),
203	OMNIA_EXT_CTL_PHY_SFP		= BIT(6),
204	OMNIA_EXT_CTL_PHY_SFP_AUTO	= BIT(7),
205	OMNIA_EXT_CTL_nVHV_CTRL		= BIT(8),
206};
207
208enum omnia_int_e {
209	OMNIA_INT_CARD_DET		= BIT(0),
210	OMNIA_INT_MSATA_IND		= BIT(1),
211	OMNIA_INT_USB30_OVC		= BIT(2),
212	OMNIA_INT_USB31_OVC		= BIT(3),
213	OMNIA_INT_BUTTON_PRESSED	= BIT(4),
214	OMNIA_INT_SFP_nDET		= BIT(5),
215	OMNIA_INT_BRIGHTNESS_CHANGED	= BIT(6),
216	OMNIA_INT_TRNG			= BIT(7),
217	OMNIA_INT_MESSAGE_SIGNED	= BIT(8),
218
219	OMNIA_INT_LED_STATES_MASK	= GENMASK(31, 12),
220	OMNIA_INT_WLAN0_MSATA_LED	= BIT(12),
221	OMNIA_INT_WLAN1_LED		= BIT(13),
222	OMNIA_INT_WLAN2_LED		= BIT(14),
223	OMNIA_INT_WPAN0_LED		= BIT(15),
224	OMNIA_INT_WPAN1_LED		= BIT(16),
225	OMNIA_INT_WPAN2_LED		= BIT(17),
226	OMNIA_INT_WAN_LED0		= BIT(18),
227	OMNIA_INT_WAN_LED1		= BIT(19),
228	OMNIA_INT_LAN0_LED0		= BIT(20),
229	OMNIA_INT_LAN0_LED1		= BIT(21),
230	OMNIA_INT_LAN1_LED0		= BIT(22),
231	OMNIA_INT_LAN1_LED1		= BIT(23),
232	OMNIA_INT_LAN2_LED0		= BIT(24),
233	OMNIA_INT_LAN2_LED1		= BIT(25),
234	OMNIA_INT_LAN3_LED0		= BIT(26),
235	OMNIA_INT_LAN3_LED1		= BIT(27),
236	OMNIA_INT_LAN4_LED0		= BIT(28),
237	OMNIA_INT_LAN4_LED1		= BIT(29),
238	OMNIA_INT_LAN5_LED0		= BIT(30),
239	OMNIA_INT_LAN5_LED1		= BIT(31),
240};
241
242enum omnia_cmd_led_mode_e {
243	OMNIA_CMD_LED_MODE_LED_MASK	= GENMASK(3, 0),
244	OMNIA_CMD_LED_MODE_USER		= BIT(4),
245};
246
247#define OMNIA_CMD_LED_MODE_LED(_l)	FIELD_PREP(OMNIA_CMD_LED_MODE_LED_MASK, _l)
248
249enum omnia_cmd_led_state_e {
250	OMNIA_CMD_LED_STATE_LED_MASK	= GENMASK(3, 0),
251	OMNIA_CMD_LED_STATE_ON		= BIT(4),
252};
253
254#define OMNIA_CMD_LED_STATE_LED(_l)	FIELD_PREP(OMNIA_CMD_LED_STATE_LED_MASK, _l)
255
256enum omnia_cmd_poweroff_e {
257	OMNIA_CMD_POWER_OFF_POWERON_BUTTON	= BIT(0),
258	OMNIA_CMD_POWER_OFF_MAGIC		= 0xdead,
259};
260
261enum omnia_cmd_usb_ovc_prot_e {
262	OMNIA_CMD_xET_USB_OVC_PROT_PORT_MASK	= GENMASK(3, 0),
263	OMNIA_CMD_xET_USB_OVC_PROT_ENABLE	= BIT(4),
264};
265
266/* Command execution functions */
267
268struct i2c_client;
269
270int omnia_cmd_write_read(const struct i2c_client *client,
271			 void *cmd, unsigned int cmd_len,
272			 void *reply, unsigned int reply_len);
273
274static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
275				  unsigned int len)
276{
277	return omnia_cmd_write_read(client, cmd, len, NULL, 0);
278}
279
280static inline int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd,
281				     u8 val)
282{
283	u8 buf[2] = { cmd, val };
284
285	return omnia_cmd_write(client, buf, sizeof(buf));
286}
287
288static inline int omnia_cmd_write_u16(const struct i2c_client *client, u8 cmd,
289				      u16 val)
290{
291	u8 buf[3];
292
293	buf[0] = cmd;
294	put_unaligned_le16(val, &buf[1]);
295
296	return omnia_cmd_write(client, buf, sizeof(buf));
297}
298
299static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
300				      u32 val)
301{
302	u8 buf[5];
303
304	buf[0] = cmd;
305	put_unaligned_le32(val, &buf[1]);
306
307	return omnia_cmd_write(client, buf, sizeof(buf));
308}
309
310static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
311				 void *reply, unsigned int len)
312{
313	return omnia_cmd_write_read(client, &cmd, 1, reply, len);
314}
315
316static inline unsigned int
317omnia_compute_reply_length(unsigned long mask, bool interleaved,
318			   unsigned int offset)
319{
320	if (!mask)
321		return 0;
322
323	return ((__fls(mask) >> 3) << interleaved) + 1 + offset;
324}
325
326/* Returns 0 on success */
327static inline int omnia_cmd_read_bits(const struct i2c_client *client, u8 cmd,
328				      unsigned long bits, unsigned long *dst)
329{
330	__le32 reply;
331	int err;
332
333	if (!bits) {
334		*dst = 0;
335		return 0;
336	}
337
338	err = omnia_cmd_read(client, cmd, &reply,
339			     omnia_compute_reply_length(bits, false, 0));
340	if (err)
341		return err;
342
343	*dst = le32_to_cpu(reply) & bits;
344
345	return 0;
346}
347
348static inline int omnia_cmd_read_bit(const struct i2c_client *client, u8 cmd,
349				     unsigned long bit)
350{
351	unsigned long reply;
352	int err;
353
354	err = omnia_cmd_read_bits(client, cmd, bit, &reply);
355	if (err)
356		return err;
357
358	return !!reply;
359}
360
361static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
362				     u32 *dst)
363{
364	__le32 reply;
365	int err;
366
367	err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
368	if (err)
369		return err;
370
371	*dst = le32_to_cpu(reply);
372
373	return 0;
374}
375
376static inline int omnia_cmd_read_u16(const struct i2c_client *client, u8 cmd,
377				     u16 *dst)
378{
379	__le16 reply;
380	int err;
381
382	err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
383	if (err)
384		return err;
385
386	*dst = le16_to_cpu(reply);
387
388	return 0;
389}
390
391static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
392				    u8 *reply)
393{
394	return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
395}
396
397#endif /* __TURRIS_OMNIA_MCU_INTERFACE_H */
~/ Read-only file preview.