xref: /illumos-gate/usr/src/uts/common/sys/i2c/ioctl.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_IOCTL_H
17 #define	_SYS_I2C_IOCTL_H
18 
19 /*
20  * Userland i2c requests.
21  */
22 
23 #include <sys/types.h>
24 #include <sys/i2c/i2c.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /*
31  * This is a private property to aid nexus type discovery.
32  */
33 #define	I2C_NEXUS_TYPE_PROP	"i2c-nexus-type"
34 #define	I2C_NEXUS_TYPE_PORT	"port"
35 #define	I2C_NEXUS_TYPE_CTRL	"controller"
36 #define	I2C_NEXUS_TYPE_MUX	"mux"
37 
38 /*
39  * Base user ioctl type.
40  */
41 #define	UI2C_IOCTL	(('i' << 24) | ('2' << 16) | ('c' << 8))
42 
43 #define	UI2C_IOCTL_CTRL_NPROPS		(UI2C_IOCTL | 0x00)
44 typedef struct ui2c_ctrl_nprops {
45 	uint16_t ucp_nstd;
46 	uint16_t ucp_npriv;
47 } ui2c_ctrl_nprops_t;
48 
49 #define	UI2C_IOCTL_CTRL_PROP_INFO	(UI2C_IOCTL | 0x01)
50 
51 /*
52  * Get information about a property.
53  */
54 typedef struct ui2c_prop_info {
55 	i2c_error_t upi_error;
56 	uint32_t upi_prop;
57 	uint32_t upi_type;
58 	uint32_t upi_perm;
59 	uint32_t upi_def_len;
60 	uint32_t upi_pos_len;
61 	char upi_name[I2C_PROP_NAME_MAX];
62 	uint8_t upi_def[I2C_PROP_SIZE_MAX];
63 	uint8_t upi_pos[I2C_PROP_SIZE_MAX];
64 } ui2c_prop_info_t;
65 
66 #define	UI2C_IOCTL_CTRL_PROP_GET	(UI2C_IOCTL | 0x02)
67 #define	UI2C_IOCTL_CTRL_PROP_SET	(UI2C_IOCTL | 0x03)
68 
69 /*
70  * Get and set a property. up_size is used to indicate how many bytes in
71  * up_value are valid on a property set and is filled in on a property get.
72  */
73 typedef struct ui2c_prop {
74 	i2c_error_t up_error;
75 	uint32_t up_prop;
76 	uint32_t up_size;
77 	uint8_t up_value[I2C_PROP_SIZE_MAX];
78 } ui2c_prop_t;
79 
80 /*
81  * These ioctls are used to add and remove an i2c device from the system. The
82  * device will be added or removed directly under the port that the ioctl is
83  * performed upon, this may be a controller or a mux. When adding a device, the
84  * address must by unique within the port and any upstream ports. See
85  * uts/common/io/i2c/i2cnex/i2cnex_addr.c for more background.
86  *
87  * When adding a structure, the nvlist is used. When removing it, we just pass
88  * an address in using the second structure. The nvlist is due to the assumption
89  * that things are going to get more complex eventually and need to include
90  * things like properties. Either way, the intent is that this is private to
91  * libi2c and it can change.
92  */
93 #define	UI2C_IOCTL_DEVICE_ADD		(UI2C_IOCTL | 0x04)
94 #define	UI2C_IOCTL_DEVICE_REMOVE	(UI2C_IOCTL | 0x05)
95 
96 #define	UI2C_IOCTL_NVL_MAX_SIZE	0x4000		/* 16 KiB */
97 #define	UI2C_IOCTL_NVL_ADDR	"address"	/* uint16_t */
98 #define	UI2C_IOCTL_NVL_TYPE	"type"		/* uint16_t */
99 #define	UI2C_IOCTL_NVL_NAME	"name"		/* string */
100 #define	UI2C_IOCTL_NVL_COMPAT	"compat"	/* string[] (optional) */
101 #define	UI2C_IOCTL_NVL_NCOMPAT_MAX	32	/* max compat[] length */
102 
103 typedef struct ui2c_dev {
104 	i2c_error_t uda_error;
105 	uintptr_t uda_nvl;
106 	size_t uda_nvl_len;
107 } ui2c_dev_add_t;
108 
109 typedef struct ui2c_dev_rem {
110 	i2c_error_t udr_error;
111 	i2c_addr_t udr_addr;
112 } ui2c_dev_rem_t;
113 
114 /*
115  * These commands are used to issue a request. Today, these can target any port.
116  * If the port is downstream of a mux, the mux will be set up appropriately to
117  * reach that port. These use the shared i2c_req_t and smbus_req_t found in
118  * <sys/i2c/i2c.h>.
119  *
120  * In the future, we may want to have this work on a device. If we did, it would
121  * be the same thing, but constrain the address in question to one that a
122  * device actually had from the kernel's perspective.
123  */
124 #define	UI2C_IOCTL_I2C_REQ		(UI2C_IOCTL | 0x06)
125 #define	UI2C_IOCTL_SMBUS_REQ		(UI2C_IOCTL | 0x07)
126 
127 /*
128  * Get information about a port and the addresses that exist underneath it.
129  */
130 #define	UI2C_IOCTL_PORT_INFO		(UI2C_IOCTL | 0x08)
131 
132 typedef struct ui2c_port_addr_info {
133 	bool pai_downstream;
134 	uint8_t pai_ndevs;
135 	major_t pai_major;
136 	uint16_t pai_pad;
137 } ui2c_port_addr_info_t;
138 
139 typedef struct ui2c_port_info {
140 	i2c_error_t upo_error;
141 	uint32_t upo_portno;
142 	uint32_t upo_ndevs;
143 	uint32_t upo_ndevs_ds;
144 	ui2c_port_addr_info_t upo_7b[1 << 7];
145 } ui2c_port_info_t;
146 
147 /*
148  * Get information about about a device and the kinds of addresses it uses.
149  */
150 #define	UI2C_IOCTL_DEV_INFO		(UI2C_IOCTL | 0x09)
151 
152 typedef enum ui2c_dev_flags {
153 	UI2C_DEV_F_MUX = 1 << 0
154 } ui2c_dev_flags_t;
155 
156 typedef struct ui2c_dev_info {
157 	i2c_error_t udi_error;
158 	i2c_addr_t udi_primary;
159 	uint32_t udi_flags;
160 	uint8_t udi_7b[1 << 7];
161 } ui2c_dev_info_t;
162 
163 /*
164  * Get information about a mux.
165  */
166 #define	UI2C_IOCTL_MUX_INFO		(UI2C_IOCTL | 0x0a)
167 
168 typedef struct ui2c_mux_info {
169 	i2c_error_t umi_error;
170 	uint32_t umi_nports;
171 } ui2c_mux_info_t;
172 
173 #if defined(_KERNEL) && defined(_SYSCALL32)
174 #pragma pack(4)
175 typedef struct {
176 	i2c_error_t uda_error;
177 	uintptr32_t uda_nvl;
178 	size32_t uda_nvl_len;
179 } ui2c_dev_add32_t;
180 
181 #pragma pack() /* pack(4) */
182 #endif	/* _KERNEL && _SYSCALL32 */
183 
184 #ifdef __cplusplus
185 }
186 #endif
187 
188 #endif /* _SYS_I2C_IOCTL_H */
189