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