at master 397 lines 11 kB view raw
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 */