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