xref: /illumos-gate/usr/src/lib/libi2c/common/libi2c.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 _LIBI2C_H
17*32002227SRobert Mustacchi #define	_LIBI2C_H
18*32002227SRobert Mustacchi 
19*32002227SRobert Mustacchi /*
20*32002227SRobert Mustacchi  * This file contains an evolving set of interfaces for dealing with i2c class
21*32002227SRobert Mustacchi  * devices in the system.
22*32002227SRobert Mustacchi  */
23*32002227SRobert Mustacchi 
24*32002227SRobert Mustacchi #ifdef __cplusplus
25*32002227SRobert Mustacchi extern "C" {
26*32002227SRobert Mustacchi #endif
27*32002227SRobert Mustacchi 
28*32002227SRobert Mustacchi #include <stdbool.h>
29*32002227SRobert Mustacchi #include <libdevinfo.h>
30*32002227SRobert Mustacchi #include <stdint.h>
31*32002227SRobert Mustacchi #include <sys/i2c/i2c.h>
32*32002227SRobert Mustacchi 
33*32002227SRobert Mustacchi typedef enum {
34*32002227SRobert Mustacchi 	I2C_ERR_OK	= 0,
35*32002227SRobert Mustacchi 	/*
36*32002227SRobert Mustacchi 	 * Indicates that a command issued to a controller failed for some
37*32002227SRobert Mustacchi 	 * reason. The driver's error is available through the i2c_ctrl_err()
38*32002227SRobert Mustacchi 	 * function.
39*32002227SRobert Mustacchi 	 */
40*32002227SRobert Mustacchi 	I2C_ERR_CONTROLLER,
41*32002227SRobert Mustacchi 	/*
42*32002227SRobert Mustacchi 	 * We were passed an invalid pointer argument for an argument.
43*32002227SRobert Mustacchi 	 */
44*32002227SRobert Mustacchi 	I2C_ERR_BAD_PTR,
45*32002227SRobert Mustacchi 	/*
46*32002227SRobert Mustacchi 	 * Indicates that there was a memory allocation error. The system error
47*32002227SRobert Mustacchi 	 * contains the specific errno.
48*32002227SRobert Mustacchi 	 */
49*32002227SRobert Mustacchi 	I2C_ERR_NO_MEM,
50*32002227SRobert Mustacchi 	/*
51*32002227SRobert Mustacchi 	 * Indicates that an error occurred while trying to use the devinfo
52*32002227SRobert Mustacchi 	 * library. The system error is generally populated for this (dependent
53*32002227SRobert Mustacchi 	 * on the underlying libdevinfo call).
54*32002227SRobert Mustacchi 	 */
55*32002227SRobert Mustacchi 	I2C_ERR_LIBDEVINFO,
56*32002227SRobert Mustacchi 	/*
57*32002227SRobert Mustacchi 	 * Indicates that the devinfo node we were given doesn't correspond to
58*32002227SRobert Mustacchi 	 * the correct type of i2c device.
59*32002227SRobert Mustacchi 	 */
60*32002227SRobert Mustacchi 	I2C_ERR_BAD_DEVI,
61*32002227SRobert Mustacchi 	/*
62*32002227SRobert Mustacchi 	 * Indicates that an internal error condition occurred.
63*32002227SRobert Mustacchi 	 */
64*32002227SRobert Mustacchi 	I2C_ERR_INTERNAL,
65*32002227SRobert Mustacchi 	/*
66*32002227SRobert Mustacchi 	 * Indicates that the caller did not contain sufficient privileges for
67*32002227SRobert Mustacchi 	 * a given operation.
68*32002227SRobert Mustacchi 	 */
69*32002227SRobert Mustacchi 	I2C_ERR_PRIVS,
70*32002227SRobert Mustacchi 	/*
71*32002227SRobert Mustacchi 	 * Indicates a failure to open a device file.
72*32002227SRobert Mustacchi 	 */
73*32002227SRobert Mustacchi 	I2C_ERR_OPEN_DEV,
74*32002227SRobert Mustacchi 	/*
75*32002227SRobert Mustacchi 	 * Indicates that a means of identify a controller, port, or device
76*32002227SRobert Mustacchi 	 * (name, instance, etc.) does not match the corresponding I2C entity.
77*32002227SRobert Mustacchi 	 * This can also happen when given a path that does not end at the
78*32002227SRobert Mustacchi 	 * expected component.
79*32002227SRobert Mustacchi 	 */
80*32002227SRobert Mustacchi 	I2C_ERR_BAD_CONTROLLER,
81*32002227SRobert Mustacchi 	I2C_ERR_BAD_PORT,
82*32002227SRobert Mustacchi 	I2C_ERR_BAD_DEVICE,
83*32002227SRobert Mustacchi 	/*
84*32002227SRobert Mustacchi 	 * Indicates that the address type is invalid or that the address is not
85*32002227SRobert Mustacchi 	 * a valid address.
86*32002227SRobert Mustacchi 	 */
87*32002227SRobert Mustacchi 	I2C_ERR_BAD_ADDR_TYPE,
88*32002227SRobert Mustacchi 	I2C_ERR_BAD_ADDR,
89*32002227SRobert Mustacchi 	/*
90*32002227SRobert Mustacchi 	 * Indicates that the requested address type is not supported by the
91*32002227SRobert Mustacchi 	 * controller.
92*32002227SRobert Mustacchi 	 */
93*32002227SRobert Mustacchi 	I2C_ERR_UNSUP_ADDR_TYPE,
94*32002227SRobert Mustacchi 	/*
95*32002227SRobert Mustacchi 	 * Indicates that the address could not be used because it is reserved.
96*32002227SRobert Mustacchi 	 */
97*32002227SRobert Mustacchi 	I2C_ERR_ADDR_RSVD,
98*32002227SRobert Mustacchi 	/*
99*32002227SRobert Mustacchi 	 * Indicates that the requested address is already in use.
100*32002227SRobert Mustacchi 	 */
101*32002227SRobert Mustacchi 	I2C_ERR_ADDR_IN_USE,
102*32002227SRobert Mustacchi 	/*
103*32002227SRobert Mustacchi 	 * Indicates that the requested address does not map to anything known.
104*32002227SRobert Mustacchi 	 */
105*32002227SRobert Mustacchi 	I2C_ERR_ADDR_UNKNOWN,
106*32002227SRobert Mustacchi 	/*
107*32002227SRobert Mustacchi 	 * Indicates that the I/O length is outside of the valid range for the
108*32002227SRobert Mustacchi 	 * request. The maximum SMBus 2.0 request is 32 bytes and SMBus 3.0 is
109*32002227SRobert Mustacchi 	 * 256 bytes. The maximum I2C request is similarly today 256 bytes.
110*32002227SRobert Mustacchi 	 */
111*32002227SRobert Mustacchi 	I2C_ERR_IO_READ_LEN_RANGE,
112*32002227SRobert Mustacchi 	I2C_ERR_IO_WRITE_LEN_RANGE,
113*32002227SRobert Mustacchi 	/*
114*32002227SRobert Mustacchi 	 * These two indicate general classes of issues with I/O requests. The
115*32002227SRobert Mustacchi 	 * first indicates that a given field has not been set. For example, an
116*32002227SRobert Mustacchi 	 * address or operation type. The second indicates that the combination
117*32002227SRobert Mustacchi 	 * of I/O is not supported. For example, a zero byte read and write.
118*32002227SRobert Mustacchi 	 */
119*32002227SRobert Mustacchi 	I2C_ERR_IO_REQ_MISSING_FIELDS,
120*32002227SRobert Mustacchi 	I2C_ERR_IO_REQ_IO_INVALID,
121*32002227SRobert Mustacchi 	/*
122*32002227SRobert Mustacchi 	 * Indicates that an I2C or SMBus request was submitted to a controller
123*32002227SRobert Mustacchi 	 * that does not support that protocol and the request could not be
124*32002227SRobert Mustacchi 	 * translated by the kernel.
125*32002227SRobert Mustacchi 	 */
126*32002227SRobert Mustacchi 	I2C_ERR_CANT_XLATE_IO_REQ,
127*32002227SRobert Mustacchi 	/*
128*32002227SRobert Mustacchi 	 * Indicates that the controller or the system does not support the
129*32002227SRobert Mustacchi 	 * requested SMBus operation.
130*32002227SRobert Mustacchi 	 */
131*32002227SRobert Mustacchi 	I2C_ERR_SMBUS_OP_UNSUP,
132*32002227SRobert Mustacchi 	/*
133*32002227SRobert Mustacchi 	 * Indicates that an attempt to take the controller lock would fail due
134*32002227SRobert Mustacchi 	 * to blocking or that a signal was taking, cancelling the operation,
135*32002227SRobert Mustacchi 	 * while waiting for the controller lock.
136*32002227SRobert Mustacchi 	 */
137*32002227SRobert Mustacchi 	I2C_ERR_LOCK_WAIT_SIGNAL,
138*32002227SRobert Mustacchi 	I2C_ERR_LOCK_WOULD_BLOCK,
139*32002227SRobert Mustacchi 	/*
140*32002227SRobert Mustacchi 	 * Indicates that the kernel did not have memory available to allocate
141*32002227SRobert Mustacchi 	 * on behalf of the caller.
142*32002227SRobert Mustacchi 	 */
143*32002227SRobert Mustacchi 	I2C_ERR_NO_KERN_MEM,
144*32002227SRobert Mustacchi 	/*
145*32002227SRobert Mustacchi 	 * Indicates that a string that is being used for a device name or
146*32002227SRobert Mustacchi 	 * compatible array contains illegal characters or is too long.
147*32002227SRobert Mustacchi 	 */
148*32002227SRobert Mustacchi 	I2C_ERR_BAD_DEV_NAME,
149*32002227SRobert Mustacchi 	/*
150*32002227SRobert Mustacchi 	 * Indicates that the length of the compatible range is longer than the
151*32002227SRobert Mustacchi 	 * system will allow to be set.
152*32002227SRobert Mustacchi 	 */
153*32002227SRobert Mustacchi 	I2C_ERR_COMPAT_LEN_RANGE,
154*32002227SRobert Mustacchi 	/*
155*32002227SRobert Mustacchi 	 * Indicates that some of the required fields are missing from a device
156*32002227SRobert Mustacchi 	 * add request.
157*32002227SRobert Mustacchi 	 */
158*32002227SRobert Mustacchi 	I2C_ERR_ADD_DEV_REQ_MISSING_FIELDS,
159*32002227SRobert Mustacchi 	/*
160*32002227SRobert Mustacchi 	 * Indicates that the I2C nexus had unexpected failures while trying to
161*32002227SRobert Mustacchi 	 * manipulate devices.
162*32002227SRobert Mustacchi 	 */
163*32002227SRobert Mustacchi 	I2C_ERR_NEXUS,
164*32002227SRobert Mustacchi 	/*
165*32002227SRobert Mustacchi 	 * Indicates that a library handle was used across multiple threads
166*32002227SRobert Mustacchi 	 * incorrectly (a handle should only be used by one thread at a time)
167*32002227SRobert Mustacchi 	 * and the kernel noted that an operation was already ongoing.
168*32002227SRobert Mustacchi 	 */
169*32002227SRobert Mustacchi 	I2C_ERR_OP_IN_PROGRESS,
170*32002227SRobert Mustacchi 	/*
171*32002227SRobert Mustacchi 	 * Indicates that the property is known to the system, but it is
172*32002227SRobert Mustacchi 	 * unsupported by the device.
173*32002227SRobert Mustacchi 	 */
174*32002227SRobert Mustacchi 	I2C_ERR_PROP_UNSUP,
175*32002227SRobert Mustacchi 	/*
176*32002227SRobert Mustacchi 	 * Indicates that the property name or id is not known to the system.
177*32002227SRobert Mustacchi 	 */
178*32002227SRobert Mustacchi 	I2C_ERR_BAD_PROP,
179*32002227SRobert Mustacchi 	/*
180*32002227SRobert Mustacchi 	 * Indicates that the property cannot be set because the controller does
181*32002227SRobert Mustacchi 	 * not support setting properties. This is followed by the controller
182*32002227SRobert Mustacchi 	 * (or system) indicating that the property is read-only.
183*32002227SRobert Mustacchi 	 */
184*32002227SRobert Mustacchi 	I2C_ERR_SET_PROP_UNSUP,
185*32002227SRobert Mustacchi 	I2C_ERR_PROP_READ_ONLY,
186*32002227SRobert Mustacchi 	/*
187*32002227SRobert Mustacchi 	 * These indicate that the property buffer is too small and too large
188*32002227SRobert Mustacchi 	 * respectively. This only fires on setting a property.
189*32002227SRobert Mustacchi 	 */
190*32002227SRobert Mustacchi 	I2C_ERR_PROP_BUF_TOO_SMALL,
191*32002227SRobert Mustacchi 	I2C_ERR_PROP_BUF_TOO_BIG,
192*32002227SRobert Mustacchi 	/*
193*32002227SRobert Mustacchi 	 * Indicates that the property value is invalid.
194*32002227SRobert Mustacchi 	 */
195*32002227SRobert Mustacchi 	I2C_ERR_BAD_PROP_VAL,
196*32002227SRobert Mustacchi 	/*
197*32002227SRobert Mustacchi 	 * Indicates that there is no default value available.
198*32002227SRobert Mustacchi 	 */
199*32002227SRobert Mustacchi 	I2C_ERR_NO_PROP_DEF_VAL,
200*32002227SRobert Mustacchi 	/*
201*32002227SRobert Mustacchi 	 * Indicates that the function used to get a value from a property
202*32002227SRobert Mustacchi 	 * didn't match the type of the data.
203*32002227SRobert Mustacchi 	 */
204*32002227SRobert Mustacchi 	I2C_ERR_PROP_TYPE_MISMATCH,
205*32002227SRobert Mustacchi 	/*
206*32002227SRobert Mustacchi 	 * Indicates that a user buffer argument is too small for the resulting
207*32002227SRobert Mustacchi 	 * string transformation.
208*32002227SRobert Mustacchi 	 */
209*32002227SRobert Mustacchi 	I2C_ERR_BUF_TOO_SMALL,
210*32002227SRobert Mustacchi } i2c_err_t;
211*32002227SRobert Mustacchi 
212*32002227SRobert Mustacchi typedef struct i2c_hdl i2c_hdl_t;
213*32002227SRobert Mustacchi typedef struct i2c_ctrl i2c_ctrl_t;
214*32002227SRobert Mustacchi typedef struct i2c_ctrl_iter i2c_ctrl_iter_t;
215*32002227SRobert Mustacchi typedef struct i2c_ctrl_disc i2c_ctrl_disc_t;
216*32002227SRobert Mustacchi typedef struct i2c_prop_info i2c_prop_info_t;
217*32002227SRobert Mustacchi typedef struct i2c_port i2c_port_t;
218*32002227SRobert Mustacchi typedef struct i2c_port_iter i2c_port_iter_t;
219*32002227SRobert Mustacchi typedef struct i2c_port_disc i2c_port_disc_t;
220*32002227SRobert Mustacchi typedef struct i2c_port_map i2c_port_map_t;
221*32002227SRobert Mustacchi typedef struct i2c_dev_iter i2c_dev_iter_t;
222*32002227SRobert Mustacchi typedef struct i2c_dev_disc i2c_dev_disc_t;
223*32002227SRobert Mustacchi typedef struct i2c_dev_info i2c_dev_info_t;
224*32002227SRobert Mustacchi typedef struct i2c_dev_add_req i2c_dev_add_req_t;
225*32002227SRobert Mustacchi typedef struct i2c_mux_iter i2c_mux_iter_t;
226*32002227SRobert Mustacchi typedef struct i2c_mux_disc i2c_mux_disc_t;
227*32002227SRobert Mustacchi typedef struct i2c_io_req i2c_io_req_t;
228*32002227SRobert Mustacchi typedef struct smbus_io_req smbus_io_req_t;
229*32002227SRobert Mustacchi 
230*32002227SRobert Mustacchi typedef enum i2c_iter {
231*32002227SRobert Mustacchi 	I2C_ITER_VALID,
232*32002227SRobert Mustacchi 	I2C_ITER_DONE,
233*32002227SRobert Mustacchi 	I2C_ITER_ERROR
234*32002227SRobert Mustacchi } i2c_iter_t;
235*32002227SRobert Mustacchi 
236*32002227SRobert Mustacchi extern i2c_hdl_t *i2c_init(void);
237*32002227SRobert Mustacchi extern void i2c_fini(i2c_hdl_t *);
238*32002227SRobert Mustacchi 
239*32002227SRobert Mustacchi /*
240*32002227SRobert Mustacchi  * Error Information. Each handle (and objects created from it) has a single
241*32002227SRobert Mustacchi  * error and should only be used from one thread at any given time. An error can
242*32002227SRobert Mustacchi  * be a semantic error or a specific class of I/O error.
243*32002227SRobert Mustacchi  */
244*32002227SRobert Mustacchi extern i2c_err_t i2c_err(i2c_hdl_t *);
245*32002227SRobert Mustacchi extern i2c_ctrl_error_t i2c_ctrl_err(i2c_hdl_t *);
246*32002227SRobert Mustacchi extern int32_t i2c_syserr(i2c_hdl_t *);
247*32002227SRobert Mustacchi extern const char *i2c_errmsg(i2c_hdl_t *);
248*32002227SRobert Mustacchi extern const char *i2c_errtostr(i2c_hdl_t *, i2c_err_t);
249*32002227SRobert Mustacchi extern const char *i2c_ctrl_errtostr(i2c_hdl_t *, i2c_ctrl_error_t);
250*32002227SRobert Mustacchi 
251*32002227SRobert Mustacchi /*
252*32002227SRobert Mustacchi  * Discover and initialize i2c controllers.
253*32002227SRobert Mustacchi  *
254*32002227SRobert Mustacchi  * Information that is obtained during discovery should only be considered to
255*32002227SRobert Mustacchi  * last as long as you are handling its relative discovery entry point. This
256*32002227SRobert Mustacchi  * includes the devinfo entities.
257*32002227SRobert Mustacchi  */
258*32002227SRobert Mustacchi extern bool i2c_ctrl_discover_init(i2c_hdl_t *, i2c_ctrl_iter_t **);
259*32002227SRobert Mustacchi extern i2c_iter_t i2c_ctrl_discover_step(i2c_ctrl_iter_t *,
260*32002227SRobert Mustacchi     const i2c_ctrl_disc_t **);
261*32002227SRobert Mustacchi extern void i2c_ctrl_discover_fini(i2c_ctrl_iter_t *);
262*32002227SRobert Mustacchi typedef bool (*i2c_ctrl_disc_f)(i2c_hdl_t *, const i2c_ctrl_disc_t *, void *);
263*32002227SRobert Mustacchi extern bool i2c_ctrl_discover(i2c_hdl_t *, i2c_ctrl_disc_f, void *);
264*32002227SRobert Mustacchi 
265*32002227SRobert Mustacchi extern di_node_t i2c_ctrl_disc_devi(const i2c_ctrl_disc_t *);
266*32002227SRobert Mustacchi extern di_minor_t i2c_ctrl_disc_minor(const i2c_ctrl_disc_t *);
267*32002227SRobert Mustacchi 
268*32002227SRobert Mustacchi extern bool i2c_ctrl_init(i2c_hdl_t *, di_node_t, i2c_ctrl_t **);
269*32002227SRobert Mustacchi extern bool i2c_ctrl_init_by_path(i2c_hdl_t *, const char *, i2c_ctrl_t **);
270*32002227SRobert Mustacchi extern void i2c_ctrl_fini(i2c_ctrl_t *);
271*32002227SRobert Mustacchi extern i2c_hdl_t *i2c_ctrl_hdl(i2c_ctrl_t *);
272*32002227SRobert Mustacchi extern const char *i2c_ctrl_name(i2c_ctrl_t *);
273*32002227SRobert Mustacchi extern const char *i2c_ctrl_path(i2c_ctrl_t *);
274*32002227SRobert Mustacchi extern int32_t i2c_ctrl_instance(i2c_ctrl_t *);
275*32002227SRobert Mustacchi extern uint32_t i2c_ctrl_nprops(i2c_ctrl_t *);
276*32002227SRobert Mustacchi 
277*32002227SRobert Mustacchi /*
278*32002227SRobert Mustacchi  * Controller property information. Note, there are no discovery APIs right now
279*32002227SRobert Mustacchi  * as all properties are currently part of the framework. The system will return
280*32002227SRobert Mustacchi  * information about all known properties. If the property is not supported by
281*32002227SRobert Mustacchi  * the controller, then only a subset of information will be valid: the id,
282*32002227SRobert Mustacchi  * type, and name.
283*32002227SRobert Mustacchi  */
284*32002227SRobert Mustacchi extern const char *i2c_prop_info_name(i2c_prop_info_t *);
285*32002227SRobert Mustacchi extern i2c_prop_t i2c_prop_info_id(i2c_prop_info_t *);
286*32002227SRobert Mustacchi extern i2c_prop_type_t i2c_prop_info_type(i2c_prop_info_t *);
287*32002227SRobert Mustacchi extern bool i2c_prop_info_sup(i2c_prop_info_t *);
288*32002227SRobert Mustacchi extern i2c_prop_perm_t i2c_prop_info_perm(i2c_prop_info_t *);
289*32002227SRobert Mustacchi extern bool i2c_prop_info_def_u32(i2c_prop_info_t *, uint32_t *);
290*32002227SRobert Mustacchi extern const i2c_prop_range_t *i2c_prop_info_pos(i2c_prop_info_t *);
291*32002227SRobert Mustacchi extern bool i2c_prop_info(i2c_ctrl_t *, i2c_prop_t, i2c_prop_info_t **);
292*32002227SRobert Mustacchi extern bool i2c_prop_info_by_name(i2c_ctrl_t *, const char *,
293*32002227SRobert Mustacchi     i2c_prop_info_t **);
294*32002227SRobert Mustacchi extern void i2c_prop_info_free(i2c_prop_info_t *);
295*32002227SRobert Mustacchi 
296*32002227SRobert Mustacchi /*
297*32002227SRobert Mustacchi  * Get and set a property value.
298*32002227SRobert Mustacchi  */
299*32002227SRobert Mustacchi extern bool i2c_prop_get(i2c_ctrl_t *, i2c_prop_t, void *, size_t *);
300*32002227SRobert Mustacchi extern bool i2c_prop_set(i2c_ctrl_t *, i2c_prop_t, const void *, size_t);
301*32002227SRobert Mustacchi 
302*32002227SRobert Mustacchi /*
303*32002227SRobert Mustacchi  * Port discovery.
304*32002227SRobert Mustacchi  */
305*32002227SRobert Mustacchi extern bool i2c_port_discover_init(i2c_hdl_t *, i2c_port_iter_t **);
306*32002227SRobert Mustacchi extern i2c_iter_t i2c_port_discover_step(i2c_port_iter_t *,
307*32002227SRobert Mustacchi     const i2c_port_disc_t **);
308*32002227SRobert Mustacchi extern void i2c_port_discover_fini(i2c_port_iter_t *);
309*32002227SRobert Mustacchi typedef bool (*i2c_port_disc_f)(i2c_hdl_t *, const i2c_port_disc_t *, void *);
310*32002227SRobert Mustacchi extern bool i2c_port_discover(i2c_hdl_t *, i2c_port_disc_f, void *);
311*32002227SRobert Mustacchi 
312*32002227SRobert Mustacchi extern di_node_t i2c_port_disc_devi(const i2c_port_disc_t *);
313*32002227SRobert Mustacchi extern const char *i2c_port_disc_path(const i2c_port_disc_t *);
314*32002227SRobert Mustacchi 
315*32002227SRobert Mustacchi extern bool i2c_port_init(i2c_hdl_t *, di_node_t, i2c_port_t **);
316*32002227SRobert Mustacchi extern bool i2c_port_init_by_path(i2c_hdl_t *, const char *, i2c_port_t **);
317*32002227SRobert Mustacchi extern void i2c_port_fini(i2c_port_t *);
318*32002227SRobert Mustacchi extern const char *i2c_port_name(i2c_port_t *);
319*32002227SRobert Mustacchi extern const char *i2c_port_path(i2c_port_t *);
320*32002227SRobert Mustacchi extern uint32_t i2c_port_portno(i2c_port_t *);
321*32002227SRobert Mustacchi typedef enum {
322*32002227SRobert Mustacchi 	I2C_PORT_TYPE_CTRL,
323*32002227SRobert Mustacchi 	I2C_PORT_TYPE_MUX
324*32002227SRobert Mustacchi } i2c_port_type_t;
325*32002227SRobert Mustacchi extern i2c_port_type_t i2c_port_type(i2c_port_t *);
326*32002227SRobert Mustacchi 
327*32002227SRobert Mustacchi /*
328*32002227SRobert Mustacchi  * The port map provides information about all the addresses that are in use
329*32002227SRobert Mustacchi  * from this port's perspective. This is a point in time snapshot that is taken
330*32002227SRobert Mustacchi  * when the function is called. From there, information about a given address
331*32002227SRobert Mustacchi  * can be inquired.
332*32002227SRobert Mustacchi  */
333*32002227SRobert Mustacchi extern bool i2c_port_map_snap(i2c_port_t *, i2c_port_map_t **);
334*32002227SRobert Mustacchi extern void i2c_port_map_free(i2c_port_map_t *);
335*32002227SRobert Mustacchi 
336*32002227SRobert Mustacchi extern void i2c_port_map_ndevs(const i2c_port_map_t *, uint32_t *, uint32_t *);
337*32002227SRobert Mustacchi extern bool i2c_port_map_addr_info(const i2c_port_map_t *, const i2c_addr_t *,
338*32002227SRobert Mustacchi     uint32_t *, bool *, major_t *);
339*32002227SRobert Mustacchi 
340*32002227SRobert Mustacchi /*
341*32002227SRobert Mustacchi  * Request to add a device under the given port. This is used to add the
342*32002227SRobert Mustacchi  * specified device into the tree under the given port (whether a controller or
343*32002227SRobert Mustacchi  * mux). This will create a device and attempt to bind a driver to it. It will
344*32002227SRobert Mustacchi  * also be accessible for user access.
345*32002227SRobert Mustacchi  */
346*32002227SRobert Mustacchi extern bool i2c_device_add_req_init(i2c_port_t *, i2c_dev_add_req_t **);
347*32002227SRobert Mustacchi extern void i2c_device_add_req_fini(i2c_dev_add_req_t *);
348*32002227SRobert Mustacchi 
349*32002227SRobert Mustacchi extern bool i2c_device_add_req_set_addr(i2c_dev_add_req_t *,
350*32002227SRobert Mustacchi     const i2c_addr_t *);
351*32002227SRobert Mustacchi extern bool i2c_device_add_req_set_name(i2c_dev_add_req_t *, const char *);
352*32002227SRobert Mustacchi extern bool i2c_device_add_req_set_compatible(i2c_dev_add_req_t *,
353*32002227SRobert Mustacchi     char *const *, size_t);
354*32002227SRobert Mustacchi extern bool i2c_device_add_req_exec(i2c_dev_add_req_t *);
355*32002227SRobert Mustacchi 
356*32002227SRobert Mustacchi /*
357*32002227SRobert Mustacchi  * Remove a device, specified by address, that is directly under the given port.
358*32002227SRobert Mustacchi  */
359*32002227SRobert Mustacchi extern bool i2c_device_rem(i2c_port_t *, const i2c_addr_t *);
360*32002227SRobert Mustacchi 
361*32002227SRobert Mustacchi /*
362*32002227SRobert Mustacchi  * Discover devices.
363*32002227SRobert Mustacchi  *
364*32002227SRobert Mustacchi  * This returns information about devices that are known to the system. It does
365*32002227SRobert Mustacchi  * not go out and attempt to perform I/O to devices or try to infer what a
366*32002227SRobert Mustacchi  * device is based on the results of a scan.
367*32002227SRobert Mustacchi  */
368*32002227SRobert Mustacchi extern bool i2c_device_discover_init(i2c_hdl_t *, i2c_dev_iter_t **);
369*32002227SRobert Mustacchi extern i2c_iter_t i2c_device_discover_step(i2c_dev_iter_t *,
370*32002227SRobert Mustacchi     const i2c_dev_disc_t **);
371*32002227SRobert Mustacchi extern void i2c_device_discover_fini(i2c_dev_iter_t *);
372*32002227SRobert Mustacchi typedef bool (*i2c_dev_disc_f)(i2c_hdl_t *, const i2c_dev_disc_t *, void *);
373*32002227SRobert Mustacchi extern bool i2c_device_discover(i2c_hdl_t *, i2c_dev_disc_f, void *);
374*32002227SRobert Mustacchi 
375*32002227SRobert Mustacchi extern const char *i2c_device_disc_name(const i2c_dev_disc_t *);
376*32002227SRobert Mustacchi extern const char *i2c_device_disc_path(const i2c_dev_disc_t *);
377*32002227SRobert Mustacchi 
378*32002227SRobert Mustacchi extern di_node_t i2c_device_disc_devi(const i2c_dev_disc_t *);
379*32002227SRobert Mustacchi extern di_minor_t i2c_device_disc_devctl(const i2c_dev_disc_t *);
380*32002227SRobert Mustacchi 
381*32002227SRobert Mustacchi /*
382*32002227SRobert Mustacchi  * Get a snapshot of information about a device and its addresses.
383*32002227SRobert Mustacchi  */
384*32002227SRobert Mustacchi extern bool i2c_device_info_snap(i2c_hdl_t *, di_node_t, i2c_dev_info_t **);
385*32002227SRobert Mustacchi extern void i2c_device_info_free(i2c_dev_info_t *);
386*32002227SRobert Mustacchi 
387*32002227SRobert Mustacchi extern const char *i2c_device_info_path(const i2c_dev_info_t *);
388*32002227SRobert Mustacchi extern const char *i2c_device_info_name(const i2c_dev_info_t *);
389*32002227SRobert Mustacchi extern const char *i2c_device_info_driver(const i2c_dev_info_t *);
390*32002227SRobert Mustacchi extern int i2c_device_info_instance(const i2c_dev_info_t *);
391*32002227SRobert Mustacchi extern uint32_t i2c_device_info_naddrs(const i2c_dev_info_t *);
392*32002227SRobert Mustacchi extern const i2c_addr_t *i2c_device_info_addr(const i2c_dev_info_t *, uint32_t);
393*32002227SRobert Mustacchi extern i2c_addr_source_t i2c_device_info_addr_source(const i2c_dev_info_t *,
394*32002227SRobert Mustacchi     uint32_t);
395*32002227SRobert Mustacchi extern const i2c_addr_t *i2c_device_info_addr_primary(const i2c_dev_info_t *);
396*32002227SRobert Mustacchi 
397*32002227SRobert Mustacchi /*
398*32002227SRobert Mustacchi  * Discover muxes.
399*32002227SRobert Mustacchi  */
400*32002227SRobert Mustacchi extern bool i2c_mux_discover_init(i2c_hdl_t *, i2c_mux_iter_t **);
401*32002227SRobert Mustacchi extern i2c_iter_t i2c_mux_discover_step(i2c_mux_iter_t *,
402*32002227SRobert Mustacchi     const i2c_mux_disc_t **);
403*32002227SRobert Mustacchi extern void i2c_mux_discover_fini(i2c_mux_iter_t *);
404*32002227SRobert Mustacchi typedef bool (*i2c_mux_disc_f)(i2c_hdl_t *, const i2c_mux_disc_t *, void *);
405*32002227SRobert Mustacchi extern bool i2c_mux_discover(i2c_hdl_t *, i2c_mux_disc_f, void *);
406*32002227SRobert Mustacchi 
407*32002227SRobert Mustacchi extern const char *i2c_mux_disc_name(const i2c_mux_disc_t *);
408*32002227SRobert Mustacchi extern const char *i2c_mux_disc_path(const i2c_mux_disc_t *);
409*32002227SRobert Mustacchi extern uint32_t i2c_mux_disc_nports(const i2c_mux_disc_t *);
410*32002227SRobert Mustacchi extern di_node_t i2c_mux_disc_devi(const i2c_mux_disc_t *);
411*32002227SRobert Mustacchi extern di_minor_t i2c_mux_disc_devctl(const i2c_mux_disc_t *);
412*32002227SRobert Mustacchi 
413*32002227SRobert Mustacchi /*
414*32002227SRobert Mustacchi  * Perform I/O on a device from userland. I/O can be specific to a device, in
415*32002227SRobert Mustacchi  * which case an address is not required, or it can be specific to a port. When
416*32002227SRobert Mustacchi  * targeting a port, then an address is required; however, if the port is a port
417*32002227SRobert Mustacchi  * of a multiplexor, then all of the muxes will be implicitly activated to
418*32002227SRobert Mustacchi  * perform that I/O.
419*32002227SRobert Mustacchi  *
420*32002227SRobert Mustacchi  * I/O requests come in two different forms, an I2C style request and an SMBus
421*32002227SRobert Mustacchi  * style request. The system will translate between the two depending on the
422*32002227SRobert Mustacchi  * controllers capabilities.
423*32002227SRobert Mustacchi  */
424*32002227SRobert Mustacchi extern bool i2c_io_req_init(i2c_port_t *, i2c_io_req_t **);
425*32002227SRobert Mustacchi extern void i2c_io_req_fini(i2c_io_req_t *);
426*32002227SRobert Mustacchi 
427*32002227SRobert Mustacchi extern bool i2c_io_req_set_addr(i2c_io_req_t *, const i2c_addr_t *);
428*32002227SRobert Mustacchi extern bool i2c_io_req_set_transmit_data(i2c_io_req_t *, const void *, size_t);
429*32002227SRobert Mustacchi extern bool i2c_io_req_set_receive_buf(i2c_io_req_t *, void *, size_t);
430*32002227SRobert Mustacchi extern bool i2c_io_req_exec(i2c_io_req_t *);
431*32002227SRobert Mustacchi 
432*32002227SRobert Mustacchi extern bool smbus_io_req_init(i2c_port_t *, smbus_io_req_t  **);
433*32002227SRobert Mustacchi extern void smbus_io_req_fini(smbus_io_req_t *);
434*32002227SRobert Mustacchi 
435*32002227SRobert Mustacchi extern bool smbus_io_req_set_addr(smbus_io_req_t *, const i2c_addr_t *);
436*32002227SRobert Mustacchi extern bool smbus_io_req_set_quick_cmd(smbus_io_req_t *, bool);
437*32002227SRobert Mustacchi extern bool smbus_io_req_set_send_byte(smbus_io_req_t *, uint8_t);
438*32002227SRobert Mustacchi extern bool smbus_io_req_set_write_u8(smbus_io_req_t *, uint8_t, uint8_t);
439*32002227SRobert Mustacchi extern bool smbus_io_req_set_write_u16(smbus_io_req_t *, uint8_t, uint16_t);
440*32002227SRobert Mustacchi extern bool smbus_io_req_set_write_u32(smbus_io_req_t *, uint8_t, uint32_t);
441*32002227SRobert Mustacchi extern bool smbus_io_req_set_write_u64(smbus_io_req_t *, uint8_t, uint64_t);
442*32002227SRobert Mustacchi extern bool smbus_io_req_set_write_block(smbus_io_req_t *, uint8_t,
443*32002227SRobert Mustacchi     const void *, size_t, bool);
444*32002227SRobert Mustacchi extern bool smbus_io_req_set_recv_byte(smbus_io_req_t *, uint8_t *);
445*32002227SRobert Mustacchi extern bool smbus_io_req_set_read_u8(smbus_io_req_t *, uint8_t, uint8_t *);
446*32002227SRobert Mustacchi extern bool smbus_io_req_set_read_u16(smbus_io_req_t *, uint8_t, uint16_t *);
447*32002227SRobert Mustacchi extern bool smbus_io_req_set_read_u32(smbus_io_req_t *, uint8_t, uint32_t *);
448*32002227SRobert Mustacchi extern bool smbus_io_req_set_read_u64(smbus_io_req_t *, uint8_t, uint64_t *);
449*32002227SRobert Mustacchi extern bool smbus_io_req_set_read_block_i2c(smbus_io_req_t *, uint8_t, void *,
450*32002227SRobert Mustacchi     size_t);
451*32002227SRobert Mustacchi extern bool smbus_io_req_set_process_call(smbus_io_req_t *, uint8_t, uint16_t,
452*32002227SRobert Mustacchi     uint16_t *);
453*32002227SRobert Mustacchi extern bool smbus_io_req_exec(smbus_io_req_t *);
454*32002227SRobert Mustacchi 
455*32002227SRobert Mustacchi /*
456*32002227SRobert Mustacchi  * I2C address classification routines. Note, i2c_addr_reserved() only returns
457*32002227SRobert Mustacchi  * true if the address is reserved. If the address is invalid, it will return
458*32002227SRobert Mustacchi  * false as well.
459*32002227SRobert Mustacchi  */
460*32002227SRobert Mustacchi extern bool i2c_addr_reserved(const i2c_addr_t *);
461*32002227SRobert Mustacchi 
462*32002227SRobert Mustacchi /*
463*32002227SRobert Mustacchi  * Initialize information about a port and device based on the path. If the bool
464*32002227SRobert Mustacchi  * is set to true, then we're allowed to return with just a port and no device
465*32002227SRobert Mustacchi  * information due to the path ending at a port.
466*32002227SRobert Mustacchi  */
467*32002227SRobert Mustacchi extern bool i2c_port_dev_init_by_path(i2c_hdl_t *, const char *, bool,
468*32002227SRobert Mustacchi     i2c_port_t **, i2c_dev_info_t **);
469*32002227SRobert Mustacchi 
470*32002227SRobert Mustacchi /*
471*32002227SRobert Mustacchi  * Utility functions to parse and transform an i2c_addr_t.
472*32002227SRobert Mustacchi  */
473*32002227SRobert Mustacchi extern bool i2c_addr_parse(i2c_hdl_t *, const char *, i2c_addr_t *);
474*32002227SRobert Mustacchi extern bool i2c_addr_to_string(i2c_hdl_t *, const i2c_addr_t *, char *, size_t);
475*32002227SRobert Mustacchi 
476*32002227SRobert Mustacchi #ifdef __cplusplus
477*32002227SRobert Mustacchi }
478*32002227SRobert Mustacchi #endif
479*32002227SRobert Mustacchi 
480*32002227SRobert Mustacchi #endif /* _LIBI2C_H */
481