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