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_MUX_H 17 #define _SYS_I2C_MUX_H 18 19 /* 20 * This header should be used by device drivers that implement an I2C mux of 21 * some kind, regardless of whether they are controlled in-band with I2C, 22 * out-of-band, or through some other means. 23 */ 24 25 #include <sys/devops.h> 26 #include <sys/stdint.h> 27 #include <sys/stdbool.h> 28 #include <sys/i2c/client.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #define I2C_MUX_PROVIDER_V0 0 35 #define I2C_MUX_PROVIDER I2C_MUX_PROVIDER_V0 36 37 #define I2C_MUX_PORT_ALL UINT32_MAX 38 39 typedef struct i2c_mux_ops { 40 /* 41 * Name the specified port on the mux. 42 */ 43 bool (*mux_port_name_f)(void *, uint32_t, char *, size_t); 44 /* 45 * Enable the specified port. The flags argument is reserved for future 46 * use. Only one segment may be enabled at a time. If one is already 47 * active, this should replace that with the new one. 48 */ 49 bool (*mux_port_enable_f)(void *, i2c_txn_t *, uint32_t, uint32_t, 50 i2c_error_t *); 51 /* 52 * Disable the specified port. The flags argument is reserved for future 53 * use. Today the framework will only ever send I2C_MUX_PORT_ALL. That 54 * is, all ports should be disabled and the device should not send 55 * anything. 56 */ 57 bool (*mux_port_disable_f)(void *, i2c_txn_t *, uint32_t, uint32_t, 58 i2c_error_t *); 59 } i2c_mux_ops_t; 60 61 typedef struct i2c_mux_regiser { 62 uint32_t mr_vers; 63 uint32_t mr_nports; 64 dev_info_t *mr_dip; 65 void *mr_drv; 66 const i2c_mux_ops_t *mr_ops; 67 } i2c_mux_register_t; 68 69 typedef struct i2c_mux_hdl i2c_mux_hdl_t; 70 71 typedef enum { 72 I2C_MUX_REG_E_OK = 0, 73 I2C_MUX_REG_E_BAD_VERS, 74 I2C_MUX_REG_E_BAD_PORTS, 75 I2C_MUX_REG_E_BAD_DEVI, 76 I2C_MUX_REG_E_BAD_DEVI_BUS, 77 I2C_MUX_REG_E_BAD_OPS, 78 I2C_MUX_REG_E_UNSUP_DEVI, 79 I2C_MUX_REG_E_EXISTS, 80 I2C_MUX_REG_E_NEXUS, 81 I2C_MUX_REG_E_BUSY 82 } i2c_mux_reg_error_t; 83 84 extern void i2c_mux_mod_init(struct dev_ops *); 85 extern void i2c_mux_mod_fini(struct dev_ops *); 86 extern i2c_mux_reg_error_t i2c_mux_register_alloc(uint32_t, 87 i2c_mux_register_t **); 88 extern void i2c_mux_register_free(i2c_mux_register_t *); 89 90 extern i2c_mux_reg_error_t i2c_mux_register(const i2c_mux_register_t *, 91 i2c_mux_hdl_t **); 92 extern i2c_mux_reg_error_t i2c_mux_unregister(i2c_mux_hdl_t *); 93 94 /* 95 * The i2c_mux_port_name_portno() function is a default port naming function 96 * that names the port after the port number. The first function is zeros based, 97 * the second is 1s based. It is recommended that you match the device datasheet 98 * for downstream port/bus naming. 99 */ 100 extern bool i2c_mux_port_name_portno(void *, uint32_t, char *, size_t); 101 extern bool i2c_mux_port_name_portno_1s(void *, uint32_t, char *, size_t); 102 103 /* 104 * Error functions that muxes can use. 105 */ 106 extern bool i2c_io_error(i2c_error_t *, i2c_errno_t, i2c_ctrl_error_t); 107 108 #ifdef __cplusplus 109 } 110 #endif 111 112 #endif /* _SYS_I2C_MUX_H */ 113