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