1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2025 Oxide Computer Company 14 */ 15 16 #ifndef _SYS_I2C_IOCTL_H 17 #define _SYS_I2C_IOCTL_H 18 19 /* 20 * Userland i2c requests. 21 */ 22 23 #include <sys/types.h> 24 #include <sys/i2c/i2c.h> 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 /* 31 * This is a private property to aid nexus type discovery. 32 */ 33 #define I2C_NEXUS_TYPE_PROP "i2c-nexus-type" 34 #define I2C_NEXUS_TYPE_PORT "port" 35 #define I2C_NEXUS_TYPE_CTRL "controller" 36 #define I2C_NEXUS_TYPE_MUX "mux" 37 38 /* 39 * Base user ioctl type. 40 */ 41 #define UI2C_IOCTL (('i' << 24) | ('2' << 16) | ('c' << 8)) 42 43 #define UI2C_IOCTL_CTRL_NPROPS (UI2C_IOCTL | 0x00) 44 typedef struct ui2c_ctrl_nprops { 45 uint16_t ucp_nstd; 46 uint16_t ucp_npriv; 47 } ui2c_ctrl_nprops_t; 48 49 #define UI2C_IOCTL_CTRL_PROP_INFO (UI2C_IOCTL | 0x01) 50 51 /* 52 * Get information about a property. 53 */ 54 typedef struct ui2c_prop_info { 55 i2c_error_t upi_error; 56 uint32_t upi_prop; 57 uint32_t upi_type; 58 uint32_t upi_perm; 59 uint32_t upi_def_len; 60 uint32_t upi_pos_len; 61 char upi_name[I2C_PROP_NAME_MAX]; 62 uint8_t upi_def[I2C_PROP_SIZE_MAX]; 63 uint8_t upi_pos[I2C_PROP_SIZE_MAX]; 64 } ui2c_prop_info_t; 65 66 #define UI2C_IOCTL_CTRL_PROP_GET (UI2C_IOCTL | 0x02) 67 #define UI2C_IOCTL_CTRL_PROP_SET (UI2C_IOCTL | 0x03) 68 69 /* 70 * Get and set a property. up_size is used to indicate how many bytes in 71 * up_value are valid on a property set and is filled in on a property get. 72 */ 73 typedef struct ui2c_prop { 74 i2c_error_t up_error; 75 uint32_t up_prop; 76 uint32_t up_size; 77 uint8_t up_value[I2C_PROP_SIZE_MAX]; 78 } ui2c_prop_t; 79 80 /* 81 * These ioctls are used to add and remove an i2c device from the system. The 82 * device will be added or removed directly under the port that the ioctl is 83 * performed upon, this may be a controller or a mux. When adding a device, the 84 * address must by unique within the port and any upstream ports. See 85 * uts/common/io/i2c/i2cnex/i2cnex_addr.c for more background. 86 * 87 * When adding a structure, the nvlist is used. When removing it, we just pass 88 * an address in using the second structure. The nvlist is due to the assumption 89 * that things are going to get more complex eventually and need to include 90 * things like properties. Either way, the intent is that this is private to 91 * libi2c and it can change. 92 */ 93 #define UI2C_IOCTL_DEVICE_ADD (UI2C_IOCTL | 0x04) 94 #define UI2C_IOCTL_DEVICE_REMOVE (UI2C_IOCTL | 0x05) 95 96 #define UI2C_IOCTL_NVL_MAX_SIZE 0x4000 /* 16 KiB */ 97 #define UI2C_IOCTL_NVL_ADDR "address" /* uint16_t */ 98 #define UI2C_IOCTL_NVL_TYPE "type" /* uint16_t */ 99 #define UI2C_IOCTL_NVL_NAME "name" /* string */ 100 #define UI2C_IOCTL_NVL_COMPAT "compat" /* string[] (optional) */ 101 #define UI2C_IOCTL_NVL_NCOMPAT_MAX 32 /* max compat[] length */ 102 103 typedef struct ui2c_dev { 104 i2c_error_t uda_error; 105 uintptr_t uda_nvl; 106 size_t uda_nvl_len; 107 } ui2c_dev_add_t; 108 109 typedef struct ui2c_dev_rem { 110 i2c_error_t udr_error; 111 i2c_addr_t udr_addr; 112 } ui2c_dev_rem_t; 113 114 /* 115 * These commands are used to issue a request. Today, these can target any port. 116 * If the port is downstream of a mux, the mux will be set up appropriately to 117 * reach that port. These use the shared i2c_req_t and smbus_req_t found in 118 * <sys/i2c/i2c.h>. 119 * 120 * In the future, we may want to have this work on a device. If we did, it would 121 * be the same thing, but constrain the address in question to one that a 122 * device actually had from the kernel's perspective. 123 */ 124 #define UI2C_IOCTL_I2C_REQ (UI2C_IOCTL | 0x06) 125 #define UI2C_IOCTL_SMBUS_REQ (UI2C_IOCTL | 0x07) 126 127 /* 128 * Get information about a port and the addresses that exist underneath it. 129 */ 130 #define UI2C_IOCTL_PORT_INFO (UI2C_IOCTL | 0x08) 131 132 typedef struct ui2c_port_addr_info { 133 bool pai_downstream; 134 uint8_t pai_ndevs; 135 major_t pai_major; 136 uint16_t pai_pad; 137 } ui2c_port_addr_info_t; 138 139 typedef struct ui2c_port_info { 140 i2c_error_t upo_error; 141 uint32_t upo_portno; 142 uint32_t upo_ndevs; 143 uint32_t upo_ndevs_ds; 144 ui2c_port_addr_info_t upo_7b[1 << 7]; 145 } ui2c_port_info_t; 146 147 /* 148 * Get information about about a device and the kinds of addresses it uses. 149 */ 150 #define UI2C_IOCTL_DEV_INFO (UI2C_IOCTL | 0x09) 151 152 typedef enum ui2c_dev_flags { 153 UI2C_DEV_F_MUX = 1 << 0 154 } ui2c_dev_flags_t; 155 156 typedef struct ui2c_dev_info { 157 i2c_error_t udi_error; 158 i2c_addr_t udi_primary; 159 uint32_t udi_flags; 160 uint8_t udi_7b[1 << 7]; 161 } ui2c_dev_info_t; 162 163 /* 164 * Get information about a mux. 165 */ 166 #define UI2C_IOCTL_MUX_INFO (UI2C_IOCTL | 0x0a) 167 168 typedef struct ui2c_mux_info { 169 i2c_error_t umi_error; 170 uint32_t umi_nports; 171 } ui2c_mux_info_t; 172 173 #if defined(_KERNEL) && defined(_SYSCALL32) 174 #pragma pack(4) 175 typedef struct { 176 i2c_error_t uda_error; 177 uintptr32_t uda_nvl; 178 size32_t uda_nvl_len; 179 } ui2c_dev_add32_t; 180 181 #pragma pack() /* pack(4) */ 182 #endif /* _KERNEL && _SYSCALL32 */ 183 184 #ifdef __cplusplus 185 } 186 #endif 187 188 #endif /* _SYS_I2C_IOCTL_H */ 189