xref: /illumos-gate/usr/src/uts/common/sys/i2c/mux.h (revision 32002227574cf0a435dc03de622191ca53724f0a)
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