#ifndef _LIBI2C_IMPL_H
#define _LIBI2C_IMPL_H
#include <locale.h>
#include <libnvpair.h>
#include <libi2c.h>
#include <sys/i2c/ioctl.h>
#ifdef __cplusplus
extern "C" {
#endif
#define I2C_ERR_LEN 1024
#define I2C_NEX_DRV "i2cnex"
typedef struct i2c_err_data {
i2c_err_t ie_err;
int32_t ie_syserr;
i2c_ctrl_error_t ie_ctrl_err;
char ie_errmsg[I2C_ERR_LEN];
size_t ie_errlen;
} i2c_err_data_t;
struct i2c_hdl {
i2c_err_data_t ih_err;
locale_t ih_c_loc;
int ih_devfd;
};
struct i2c_ctrl_disc {
di_node_t icd_devi;
di_minor_t icd_minor;
};
struct i2c_ctrl_iter {
i2c_hdl_t *ci_hdl;
di_node_t ci_root;
bool ci_done;
di_node_t ci_cur;
i2c_ctrl_disc_t ci_disc;
};
struct i2c_ctrl {
i2c_hdl_t *ctrl_hdl;
int32_t ctrl_inst;
char *ctrl_name;
char *ctrl_path;
char *ctrl_minor;
uint16_t ctrl_nstd;
uint16_t ctrl_npriv;
int ctrl_fd;
};
struct i2c_port_disc {
di_node_t pd_devi;
char pd_path[PATH_MAX];
};
struct i2c_port_iter {
i2c_hdl_t *pi_hdl;
bool pi_done;
di_node_t pi_root;
uint32_t pi_nalloc;
uint32_t pi_nports;
uint32_t pi_curport;
di_node_t *pi_ports;
i2c_port_disc_t pi_disc;
};
struct i2c_port {
i2c_hdl_t *port_hdl;
int32_t port_inst;
int port_fd;
char *port_name;
char *port_minor;
char port_path[PATH_MAX];
ui2c_port_info_t port_info;
i2c_port_type_t port_type;
};
struct i2c_port_map {
i2c_hdl_t *pm_hdl;
ui2c_port_info_t pm_info;
};
struct i2c_io_req {
i2c_port_t *io_port;
bool io_addr_valid;
i2c_addr_t io_addr;
size_t io_tx_len;
size_t io_rx_len;
const void *io_tx_buf;
void *io_rx_buf;
};
struct smbus_io_req {
i2c_port_t *sir_port;
bool sir_addr_valid;
i2c_addr_t sir_addr;
bool sir_op_valid;
smbus_op_t sir_op;
i2c_req_flags_t sir_flags;
uint8_t sir_cmd;
uint64_t sir_write;
const void *sir_writep;
size_t sir_wlen;
void *sir_readp;
size_t sir_rlen;
};
typedef enum {
I2C_DEV_ADD_REQ_FIELD_NAME = 1 << 0,
I2C_DEV_ADD_REQ_FIELD_ADDR = 1 << 1
} i2c_dev_add_req_field_t;
struct i2c_dev_add_req {
i2c_port_t *add_port;
nvlist_t *add_nvl;
uint32_t add_need;
};
typedef struct {
di_minor_t dmi_minor;
di_node_t dmi_node;
} dev_map_info_t;
typedef struct {
di_node_t dpi_port;
bool dpi_scanned;
bool dpi_7bit_done;
bool dpi_10bit_done;
uint16_t dpi_curidx;
dev_map_info_t dpi_7b[1 << 7];
dev_map_info_t dpi_10b[1 << 10];
} dev_port_info_t;
struct i2c_dev_disc {
const dev_map_info_t *idd_map;
const dev_port_info_t *idd_port;
char idd_path[PATH_MAX];
};
struct i2c_dev_iter {
i2c_hdl_t *di_hdl;
bool di_done;
i2c_port_iter_t *di_iter;
const i2c_port_disc_t *di_curport;
dev_port_info_t di_info;
i2c_dev_disc_t di_disc;
};
struct i2c_dev_info {
char *dinfo_name;
char dinfo_path[PATH_MAX];
char *dinfo_driver;
char *dinfo_minor;
int dinfo_inst;
uint32_t dinfo_naddrs;
i2c_addr_t *dinfo_addrs;
ui2c_dev_info_t dinfo_info;
};
struct i2c_prop_info {
i2c_hdl_t *pinfo_hdl;
ui2c_prop_info_t pinfo_info;
bool pinfo_sup;
};
struct i2c_mux_disc {
di_node_t md_devi;
di_minor_t md_minor;
char md_path[PATH_MAX];
ui2c_mux_info_t md_info;
};
struct i2c_mux_iter {
i2c_hdl_t *mi_hdl;
di_node_t mi_root;
di_node_t mi_cur;
bool mi_done;
i2c_mux_disc_t mi_disc;
};
extern bool i2c_error(i2c_hdl_t *, i2c_err_t, int32_t, const char *, ...)
__PRINTFLIKE(4);
extern bool i2c_success(i2c_hdl_t *);
extern bool i2c_ioctl_syserror(i2c_hdl_t *, int, const char *);
extern bool i2c_ioctl_error(i2c_hdl_t *, const i2c_error_t *, const char *);
extern bool i2c_nvlist_error(i2c_hdl_t *, int, const char *);
extern bool i2c_addr_validate(i2c_hdl_t *, const i2c_addr_t *);
extern bool i2c_name_validate(i2c_hdl_t *, const char *, const char *);
typedef enum {
I2C_NODE_T_CTRL,
I2C_NODE_T_PORT,
I2C_NODE_T_DEV,
I2C_NODE_T_MUX,
I2C_NODE_T_OTHER
} i2c_node_type_t;
extern i2c_node_type_t i2c_node_type(di_node_t);
extern di_minor_t i2c_node_minor(di_node_t);
extern bool i2c_node_is_type(di_node_t, i2c_node_type_t);
extern bool i2c_node_to_path(i2c_hdl_t *, di_node_t, char *, size_t);
extern bool i2c_kernel_address_parse(i2c_hdl_t *, const char *, i2c_addr_t *);
extern bool i2c_reg_to_addr(i2c_hdl_t *, di_node_t, i2c_addr_t *, uint32_t);
extern bool i2c_addr_equal(const i2c_addr_t *, const i2c_addr_t *);
extern di_node_t i2c_path_find_ctrl(di_node_t, const char *);
extern di_node_t i2c_path_find_mux(di_node_t);
extern di_node_t i2c_path_find_port(di_node_t, const char *);
extern di_node_t i2c_path_find_device(i2c_hdl_t *, di_node_t, const char *);
extern bool i2c_path_parse(i2c_hdl_t *, const char *, di_node_t, di_node_t *,
i2c_node_type_t *, i2c_err_t);
#ifdef __cplusplus
}
#endif
#endif