|
root / base / usr / src / uts / common / sys / i2c / mux.h
mux.h C 113 lines 3.2 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
/*
 * 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_MUX_H
#define	_SYS_I2C_MUX_H

/*
 * This header should be used by device drivers that implement an I2C mux of
 * some kind, regardless of whether they are controlled in-band with I2C,
 * out-of-band, or through some other means.
 */

#include <sys/devops.h>
#include <sys/stdint.h>
#include <sys/stdbool.h>
#include <sys/i2c/client.h>

#ifdef __cplusplus
extern "C" {
#endif

#define	I2C_MUX_PROVIDER_V0	0
#define	I2C_MUX_PROVIDER	I2C_MUX_PROVIDER_V0

#define	I2C_MUX_PORT_ALL	UINT32_MAX

typedef struct i2c_mux_ops {
	/*
	 * Name the specified port on the mux.
	 */
	bool (*mux_port_name_f)(void *, uint32_t, char *, size_t);
	/*
	 * Enable the specified port. The flags argument is reserved for future
	 * use. Only one segment may be enabled at a time. If one is already
	 * active, this should replace that with the new one.
	 */
	bool (*mux_port_enable_f)(void *, i2c_txn_t *, uint32_t, uint32_t,
	    i2c_error_t *);
	/*
	 * Disable the specified port. The flags argument is reserved for future
	 * use. Today the framework will only ever send I2C_MUX_PORT_ALL. That
	 * is, all ports should be disabled and the device should not send
	 * anything.
	 */
	bool (*mux_port_disable_f)(void *, i2c_txn_t *, uint32_t, uint32_t,
	    i2c_error_t *);
} i2c_mux_ops_t;

typedef struct i2c_mux_regiser {
	uint32_t mr_vers;
	uint32_t mr_nports;
	dev_info_t *mr_dip;
	void *mr_drv;
	const i2c_mux_ops_t *mr_ops;
} i2c_mux_register_t;

typedef struct i2c_mux_hdl i2c_mux_hdl_t;

typedef enum {
	I2C_MUX_REG_E_OK	 = 0,
	I2C_MUX_REG_E_BAD_VERS,
	I2C_MUX_REG_E_BAD_PORTS,
	I2C_MUX_REG_E_BAD_DEVI,
	I2C_MUX_REG_E_BAD_DEVI_BUS,
	I2C_MUX_REG_E_BAD_OPS,
	I2C_MUX_REG_E_UNSUP_DEVI,
	I2C_MUX_REG_E_EXISTS,
	I2C_MUX_REG_E_NEXUS,
	I2C_MUX_REG_E_BUSY
} i2c_mux_reg_error_t;

extern void i2c_mux_mod_init(struct dev_ops *);
extern void i2c_mux_mod_fini(struct dev_ops *);
extern i2c_mux_reg_error_t i2c_mux_register_alloc(uint32_t,
    i2c_mux_register_t **);
extern void i2c_mux_register_free(i2c_mux_register_t *);

extern i2c_mux_reg_error_t i2c_mux_register(const i2c_mux_register_t *,
    i2c_mux_hdl_t **);
extern i2c_mux_reg_error_t i2c_mux_unregister(i2c_mux_hdl_t *);

/*
 * The i2c_mux_port_name_portno() function is a default port naming function
 * that names the port after the port number. The first function is zeros based,
 * the second is 1s based. It is recommended that you match the device datasheet
 * for downstream port/bus naming.
 */
extern bool i2c_mux_port_name_portno(void *, uint32_t, char *, size_t);
extern bool i2c_mux_port_name_portno_1s(void *, uint32_t, char *, size_t);

/*
 * Error functions that muxes can use.
 */
extern bool i2c_io_error(i2c_error_t *, i2c_errno_t, i2c_ctrl_error_t);

#ifdef __cplusplus
}
#endif

#endif /* _SYS_I2C_MUX_H */