summaryrefslogtreecommitdiff
path: root/include/ioexpander.h
blob: 4cd19303855c7a34771fdb6fa3a5be3442ee850e (plain)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * Copyright 2019 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef __CROS_EC_IOEXPANDER_H
#define __CROS_EC_IOEXPANDER_H

enum ioex_signal;	/* from gpio_signal.h */

/* IO expander signal definition structure */
struct ioex_info {
	/* Signal name */
	const char *name;

	/* IO expander port number */
	uint16_t ioex;

	/* IO port number in IO expander */
	uint16_t port;

	/* Bitmask on that port (1 << N) */
	uint32_t mask;

	/* Flags - the same as the GPIO flags */
	uint32_t flags;
};

/* Signal information from board.c.  Must match order from enum ioex_signal. */
extern const struct ioex_info ioex_list[];
extern void (* const ioex_irq_handlers[])(enum ioex_signal signal);
extern const int ioex_ih_count;

/* Get ioex_info structure for specified signal */
#define IOEX_GET_INFO(signal) (ioex_list + (signal) - IOEX_SIGNAL_START)

struct ioexpander_drv {
	/* Initialize IO expander chip/driver */
	int (*init)(int ioex);
	/* Get the current level of the IOEX pin */
	int (*get_level)(int ioex, int port, int mask, int *val);
	/* Set the level of the IOEX pin */
	int (*set_level)(int ioex, int port, int mask, int val);
	/* Get flags for the IOEX pin */
	int (*get_flags_by_mask)(int ioex, int port, int mask, int *flags);
	/* Set flags for the IOEX pin */
	int (*set_flags_by_mask)(int ioex, int port, int mask, int flags);
	/* Enable/disable interrupt for the IOEX pin */
	int (*enable_interrupt)(int ioex, int port, int mask, int enable);
#ifdef CONFIG_IO_EXPANDER_SUPPORT_GET_PORT
	/* Read levels for whole IOEX port */
	int (*get_port)(int ioex, int port, int *val);
#endif
};

/* IO expander chip disabled. No I2C communication will be attempted. */
#define IOEX_FLAGS_DISABLED	BIT(0)

struct ioexpander_config_t {
	/* Physical I2C port connects to the IO expander chip. */
	int i2c_host_port;
	/* I2C address */
	int i2c_addr_flags;
	/*
	 * Pointer to the specific IO expander chip's ops defined in
	 * the struct ioexpander_drv.
	 */
	const struct ioexpander_drv *drv;
	/* Config flags for this IO expander chip. See IOEX_FLAGS_* */
	uint32_t flags;
};

extern struct ioexpander_config_t ioex_config[];

/*
 * Enable the interrupt for the IOEX signal
 *
 * @param signal	IOEX signal to enable the interrupt
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_enable_interrupt(enum ioex_signal signal);

/*
 * Disable the interrupt for the IOEX signal
 *
 * @param signal	IOEX signal to disable the interrupt
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_disable_interrupt(enum ioex_signal signal);

/*
 * Get flags for the IOEX signal
 *
 * @param signal	IOEX signal to get flags for
 * @param flags		Pointer to the keep the flags read
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_get_flags(enum ioex_signal signal, int *flags);

/*
 * Set flags for the IOEX signal
 *
 * @param signal	IOEX signal to set flags for
 * @param flags		New flags for the IOEX signal
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_set_flags(enum ioex_signal signal, int flags);

/*
 * Get the current level of the IOEX signal
 *
 * @param signal	IOEX signal to get the level
 * @param val		Pointer to the keep the level read
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_get_level(enum ioex_signal signal, int *val);

/*
 * Set the level of the IOEX signal
 *
 * @param signal	IOEX signal to set the level
 * @param value		New level for the IOEX signal
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_set_level(enum ioex_signal signal, int value);

#ifdef CONFIG_IO_EXPANDER_SUPPORT_GET_PORT
/*
 * Get the current levels on the IOEX port
 *
 * @param ioex		Number of I/O expander
 * @param port		Number of port in ioex
 * @param val		Pointer to variable where port will be read
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_get_port(int ioex, int port, int *val);
#endif

/*
 * Initialize IO expander chip/driver
 *
 * @param ioex		IO expander chip's port number
 * @return			EC_SUCCESS if successful, non-zero if error.
 */
int ioex_init(int ioex);

/*
 * Get the name for the IOEX signal
 *
 * @param signal	IOEX signal to get the name
 * @returns name of the given IOEX signal
 */
const char *ioex_get_name(enum ioex_signal signal);

/*
 * Check if signal is an IO expander signal or GPIO signal.
 *
 * @param signal	GPIO or IOEX signal
 * @return		1 if signal is IOEX else return 0
 */
int signal_is_ioex(int signal);

#endif /* __CROS_EC_IOEXPANDER_H */