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 _LIBI2C_IMPL_H 17 #define _LIBI2C_IMPL_H 18 19 /* 20 * Implementation details of libi2c. 21 */ 22 23 #include <locale.h> 24 #include <libnvpair.h> 25 #include <libi2c.h> 26 #include <sys/i2c/ioctl.h> 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /* 33 * Maximum size of an internal error message. 34 */ 35 #define I2C_ERR_LEN 1024 36 37 /* 38 * Name of the driver that we expect to be driving an instance of the i2c nexus. 39 */ 40 #define I2C_NEX_DRV "i2cnex" 41 42 typedef struct i2c_err_data { 43 i2c_err_t ie_err; 44 int32_t ie_syserr; 45 i2c_ctrl_error_t ie_ctrl_err; 46 char ie_errmsg[I2C_ERR_LEN]; 47 size_t ie_errlen; 48 } i2c_err_data_t; 49 50 struct i2c_hdl { 51 i2c_err_data_t ih_err; 52 locale_t ih_c_loc; 53 int ih_devfd; 54 }; 55 56 struct i2c_ctrl_disc { 57 di_node_t icd_devi; 58 di_minor_t icd_minor; 59 }; 60 61 struct i2c_ctrl_iter { 62 i2c_hdl_t *ci_hdl; 63 di_node_t ci_root; 64 bool ci_done; 65 di_node_t ci_cur; 66 i2c_ctrl_disc_t ci_disc; 67 }; 68 69 struct i2c_ctrl { 70 i2c_hdl_t *ctrl_hdl; 71 int32_t ctrl_inst; 72 char *ctrl_name; 73 char *ctrl_path; 74 char *ctrl_minor; 75 uint16_t ctrl_nstd; 76 uint16_t ctrl_npriv; 77 int ctrl_fd; 78 }; 79 80 struct i2c_port_disc { 81 di_node_t pd_devi; 82 char pd_path[PATH_MAX]; 83 }; 84 85 struct i2c_port_iter { 86 i2c_hdl_t *pi_hdl; 87 bool pi_done; 88 di_node_t pi_root; 89 uint32_t pi_nalloc; 90 uint32_t pi_nports; 91 uint32_t pi_curport; 92 di_node_t *pi_ports; 93 i2c_port_disc_t pi_disc; 94 }; 95 96 struct i2c_port { 97 i2c_hdl_t *port_hdl; 98 int32_t port_inst; 99 int port_fd; 100 char *port_name; 101 char *port_minor; 102 char port_path[PATH_MAX]; 103 ui2c_port_info_t port_info; 104 i2c_port_type_t port_type; 105 }; 106 107 struct i2c_port_map { 108 i2c_hdl_t *pm_hdl; 109 ui2c_port_info_t pm_info; 110 }; 111 112 struct i2c_io_req { 113 i2c_port_t *io_port; 114 bool io_addr_valid; 115 i2c_addr_t io_addr; 116 size_t io_tx_len; 117 size_t io_rx_len; 118 const void *io_tx_buf; 119 void *io_rx_buf; 120 }; 121 122 struct smbus_io_req { 123 i2c_port_t *sir_port; 124 bool sir_addr_valid; 125 i2c_addr_t sir_addr; 126 bool sir_op_valid; 127 smbus_op_t sir_op; 128 i2c_req_flags_t sir_flags; 129 uint8_t sir_cmd; 130 uint64_t sir_write; 131 const void *sir_writep; 132 size_t sir_wlen; 133 void *sir_readp; 134 size_t sir_rlen; 135 }; 136 137 typedef enum { 138 I2C_DEV_ADD_REQ_FIELD_NAME = 1 << 0, 139 I2C_DEV_ADD_REQ_FIELD_ADDR = 1 << 1 140 } i2c_dev_add_req_field_t; 141 142 struct i2c_dev_add_req { 143 i2c_port_t *add_port; 144 nvlist_t *add_nvl; 145 uint32_t add_need; 146 }; 147 148 typedef struct { 149 di_minor_t dmi_minor; 150 di_node_t dmi_node; 151 } dev_map_info_t; 152 153 typedef struct { 154 di_node_t dpi_port; 155 bool dpi_scanned; 156 bool dpi_7bit_done; 157 bool dpi_10bit_done; 158 uint16_t dpi_curidx; 159 dev_map_info_t dpi_7b[1 << 7]; 160 dev_map_info_t dpi_10b[1 << 10]; 161 } dev_port_info_t; 162 163 struct i2c_dev_disc { 164 const dev_map_info_t *idd_map; 165 const dev_port_info_t *idd_port; 166 char idd_path[PATH_MAX]; 167 }; 168 169 struct i2c_dev_iter { 170 i2c_hdl_t *di_hdl; 171 bool di_done; 172 i2c_port_iter_t *di_iter; 173 const i2c_port_disc_t *di_curport; 174 dev_port_info_t di_info; 175 i2c_dev_disc_t di_disc; 176 }; 177 178 struct i2c_dev_info { 179 char *dinfo_name; 180 char dinfo_path[PATH_MAX]; 181 char *dinfo_driver; 182 char *dinfo_minor; 183 int dinfo_inst; 184 uint32_t dinfo_naddrs; 185 i2c_addr_t *dinfo_addrs; 186 ui2c_dev_info_t dinfo_info; 187 }; 188 189 struct i2c_prop_info { 190 i2c_hdl_t *pinfo_hdl; 191 ui2c_prop_info_t pinfo_info; 192 bool pinfo_sup; 193 }; 194 195 struct i2c_mux_disc { 196 di_node_t md_devi; 197 di_minor_t md_minor; 198 char md_path[PATH_MAX]; 199 ui2c_mux_info_t md_info; 200 }; 201 202 struct i2c_mux_iter { 203 i2c_hdl_t *mi_hdl; 204 di_node_t mi_root; 205 di_node_t mi_cur; 206 bool mi_done; 207 i2c_mux_disc_t mi_disc; 208 }; 209 210 /* 211 * Common success and failure interfaces. 212 */ 213 extern bool i2c_error(i2c_hdl_t *, i2c_err_t, int32_t, const char *, ...) 214 __PRINTFLIKE(4); 215 extern bool i2c_success(i2c_hdl_t *); 216 extern bool i2c_ioctl_syserror(i2c_hdl_t *, int, const char *); 217 extern bool i2c_ioctl_error(i2c_hdl_t *, const i2c_error_t *, const char *); 218 extern bool i2c_nvlist_error(i2c_hdl_t *, int, const char *); 219 220 /* 221 * Common validation routines 222 */ 223 extern bool i2c_addr_validate(i2c_hdl_t *, const i2c_addr_t *); 224 extern bool i2c_name_validate(i2c_hdl_t *, const char *, const char *); 225 226 /* 227 * Misc. routines. 228 */ 229 typedef enum { 230 I2C_NODE_T_CTRL, 231 I2C_NODE_T_PORT, 232 I2C_NODE_T_DEV, 233 I2C_NODE_T_MUX, 234 I2C_NODE_T_OTHER 235 } i2c_node_type_t; 236 237 extern i2c_node_type_t i2c_node_type(di_node_t); 238 extern di_minor_t i2c_node_minor(di_node_t); 239 extern bool i2c_node_is_type(di_node_t, i2c_node_type_t); 240 extern bool i2c_node_to_path(i2c_hdl_t *, di_node_t, char *, size_t); 241 extern bool i2c_kernel_address_parse(i2c_hdl_t *, const char *, i2c_addr_t *); 242 extern bool i2c_reg_to_addr(i2c_hdl_t *, di_node_t, i2c_addr_t *, uint32_t); 243 extern bool i2c_addr_equal(const i2c_addr_t *, const i2c_addr_t *); 244 245 /* 246 * Various path lookup routines. 247 */ 248 extern di_node_t i2c_path_find_ctrl(di_node_t, const char *); 249 extern di_node_t i2c_path_find_mux(di_node_t); 250 extern di_node_t i2c_path_find_port(di_node_t, const char *); 251 extern di_node_t i2c_path_find_device(i2c_hdl_t *, di_node_t, const char *); 252 extern bool i2c_path_parse(i2c_hdl_t *, const char *, di_node_t, di_node_t *, 253 i2c_node_type_t *, i2c_err_t); 254 255 #ifdef __cplusplus 256 } 257 #endif 258 259 #endif /* _LIBI2C_IMPL_H */ 260