|
root / base / usr / src / uts / common / sys / i2c / controller.h
controller.h C 148 lines 4.3 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2025 Oxide Computer Company
 */

#ifndef _SYS_I2C_CONTROLLER_H
#define	_SYS_I2C_CONTROLLER_H

/*
 * This file contains the definitions that I2C, I3C, and SMBus controller
 * drivers should use to interface with the system's i2c stack.
 */

#include <sys/devops.h>
#include <sys/i2c/i2c.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Current version of the interface expected by the i2c controller provider.
 */
#define	I2C_CTRL_PROVIDER_V0	0
#define	I2C_CTRL_PROVIDER	I2C_CTRL_PROVIDER_V0

typedef struct i2c_prop_info i2c_prop_info_t;

typedef struct i2c_ctrl_ops {
	bool (*i2c_port_name_f)(void *, uint32_t, char *, size_t);
	void (*i2c_io_smbus_f)(void *, uint32_t, smbus_req_t *);
	void (*i2c_io_i2c_f)(void *, uint32_t, i2c_req_t *);
	i2c_errno_t (*i2c_prop_info_f)(void *, i2c_prop_t, i2c_prop_info_t *);
	i2c_errno_t (*i2c_prop_get_f)(void *, i2c_prop_t, void *, size_t);
	i2c_errno_t (*i2c_prop_set_f)(void *, i2c_prop_t, const void *, size_t);
} i2c_ctrl_ops_t;

typedef struct i2c_ctrl_register {
	uint32_t ic_vers;
	i2c_ctrl_type_t ic_type;
	const char *ic_name;
	uint32_t ic_nports;
	dev_info_t *ic_dip;
	void *ic_drv;
	const i2c_ctrl_ops_t *ic_ops;
} i2c_ctrl_register_t;

/*
 * Opaque structures for registration handles.
 */
typedef struct i2c_ctrl_hdl i2c_ctrl_hdl_t;

typedef enum {
	I2C_CTRL_REG_E_OK	= 0,
	I2C_CTRL_REG_E_BAD_VERS,
	I2C_CTRL_REG_E_NULL_ARG,
	I2C_CTRL_REG_E_BAD_OPS,
	I2C_CTRL_REG_E_NEED_PORT_NAME_FUNC,
	I2C_CTRL_REG_E_NEED_PROP_GET_FUNC,
	I2C_CTRL_REG_E_NEED_PROP_INFO_FUNC,
	I2C_CTRL_REG_E_BAD_CTRL_TYPE,
	I2C_CTRL_REG_E_UNSUP_CTRL_TYPE,
	I2C_CTRL_REG_E_BAD_DIP,
	I2C_CTRL_REG_E_BAD_NPORTS,
	I2C_CTRL_REG_E_BAD_NAME,
	I2C_CTRL_REG_E_INTERNAL,
	I2C_CTRL_REG_E_BAD_MOD_TYPE,
	I2C_CTRL_REG_E_NEXUS,
	I2C_CTRL_REG_E_NOT_UNIQUE,
	I2C_CTRL_REG_E_REQ_PROP,
	I2C_CTLR_REG_E_BAD_PROP_VAL
} i2c_ctrl_reg_error_t;

extern void i2c_ctrl_mod_init(struct dev_ops *);
extern void i2c_ctrl_mod_fini(struct dev_ops *);
extern i2c_ctrl_reg_error_t i2c_ctrl_register_alloc(uint32_t,
    i2c_ctrl_register_t **);
extern void i2c_ctrl_register_free(i2c_ctrl_register_t *);

extern i2c_ctrl_reg_error_t i2c_ctrl_register(const i2c_ctrl_register_t *,
    i2c_ctrl_hdl_t **);
extern i2c_ctrl_reg_error_t i2c_ctrl_unregister(i2c_ctrl_hdl_t *);

/*
 * The i2c_ctrl_port_name_portno() function is the default controller port
 * naming function that names the port after the controller. For systems where
 * ther isn't a complex I/O Mux element or some other naming case, this should
 * be what they use.
 */
extern bool i2c_ctrl_port_name_portno(void *, uint32_t, char *, size_t);

/*
 * Various functions that can be called to set the results of I/O commands.
 */
extern void i2c_ctrl_io_success(i2c_error_t *);
extern void i2c_ctrl_io_error(i2c_error_t *, i2c_errno_t, i2c_ctrl_error_t);

/*
 * Property information interfaces.
 */
extern void i2c_prop_info_set_perm(i2c_prop_info_t *, i2c_prop_perm_t);
extern void i2c_prop_info_set_def_u32(i2c_prop_info_t *, uint32_t);
extern void i2c_prop_info_set_range_u32(i2c_prop_info_t *, uint32_t, uint32_t);
extern void i2c_prop_info_set_pos_bit32(i2c_prop_info_t *, uint32_t);

/*
 * Ways for a driver to discover timeout parameters to use.
 */
typedef enum {
	/*
	 * This is the amount of time that a given I/O command should take
	 * before the request is timed out.
	 */
	I2C_CTRL_TO_IO,
	/*
	 * This is the amount of time to busy-wait while polling the controller
	 * for I/O to advance.
	 */
	I2C_CTRL_TO_POLL_CTRL,
	/*
	 * This is the amount of time to wait for the bus to be clear for use
	 * before beginning a transaction.
	 */
	I2C_CTRL_TO_BUS_ACT,
	/*
	 * This is the amount of time to wait for an abort to complete.
	 */
	I2C_CTRL_TO_ABORT
} i2c_ctrl_timeout_t;
extern uint32_t i2c_ctrl_timeout_count(i2c_ctrl_hdl_t *, i2c_ctrl_timeout_t);
extern uint32_t i2c_ctrl_timeout_delay_us(i2c_ctrl_hdl_t *, i2c_ctrl_timeout_t);

#ifdef __cplusplus
}
#endif

#endif /* _SYS_I2C_CONTROLLER_H */