diff options
Diffstat (limited to 'include/linux/i3c/ccc.h')
-rw-r--r-- | include/linux/i3c/ccc.h | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h new file mode 100644 index 000000000000..73b0982cc519 --- /dev/null +++ b/include/linux/i3c/ccc.h | |||
@@ -0,0 +1,385 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) 2018 Cadence Design Systems Inc. | ||
4 | * | ||
5 | * Author: Boris Brezillon <boris.brezillon@bootlin.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef I3C_CCC_H | ||
9 | #define I3C_CCC_H | ||
10 | |||
11 | #include <linux/bitops.h> | ||
12 | #include <linux/i3c/device.h> | ||
13 | |||
14 | /* I3C CCC (Common Command Codes) related definitions */ | ||
15 | #define I3C_CCC_DIRECT BIT(7) | ||
16 | |||
17 | #define I3C_CCC_ID(id, broadcast) \ | ||
18 | ((id) | ((broadcast) ? 0 : I3C_CCC_DIRECT)) | ||
19 | |||
20 | /* Commands valid in both broadcast and unicast modes */ | ||
21 | #define I3C_CCC_ENEC(broadcast) I3C_CCC_ID(0x0, broadcast) | ||
22 | #define I3C_CCC_DISEC(broadcast) I3C_CCC_ID(0x1, broadcast) | ||
23 | #define I3C_CCC_ENTAS(as, broadcast) I3C_CCC_ID(0x2 + (as), broadcast) | ||
24 | #define I3C_CCC_RSTDAA(broadcast) I3C_CCC_ID(0x6, broadcast) | ||
25 | #define I3C_CCC_SETMWL(broadcast) I3C_CCC_ID(0x9, broadcast) | ||
26 | #define I3C_CCC_SETMRL(broadcast) I3C_CCC_ID(0xa, broadcast) | ||
27 | #define I3C_CCC_SETXTIME(broadcast) ((broadcast) ? 0x28 : 0x98) | ||
28 | #define I3C_CCC_VENDOR(id, broadcast) ((id) + ((broadcast) ? 0x61 : 0xe0)) | ||
29 | |||
30 | /* Broadcast-only commands */ | ||
31 | #define I3C_CCC_ENTDAA I3C_CCC_ID(0x7, true) | ||
32 | #define I3C_CCC_DEFSLVS I3C_CCC_ID(0x8, true) | ||
33 | #define I3C_CCC_ENTTM I3C_CCC_ID(0xb, true) | ||
34 | #define I3C_CCC_ENTHDR(x) I3C_CCC_ID(0x20 + (x), true) | ||
35 | |||
36 | /* Unicast-only commands */ | ||
37 | #define I3C_CCC_SETDASA I3C_CCC_ID(0x7, false) | ||
38 | #define I3C_CCC_SETNEWDA I3C_CCC_ID(0x8, false) | ||
39 | #define I3C_CCC_GETMWL I3C_CCC_ID(0xb, false) | ||
40 | #define I3C_CCC_GETMRL I3C_CCC_ID(0xc, false) | ||
41 | #define I3C_CCC_GETPID I3C_CCC_ID(0xd, false) | ||
42 | #define I3C_CCC_GETBCR I3C_CCC_ID(0xe, false) | ||
43 | #define I3C_CCC_GETDCR I3C_CCC_ID(0xf, false) | ||
44 | #define I3C_CCC_GETSTATUS I3C_CCC_ID(0x10, false) | ||
45 | #define I3C_CCC_GETACCMST I3C_CCC_ID(0x11, false) | ||
46 | #define I3C_CCC_SETBRGTGT I3C_CCC_ID(0x13, false) | ||
47 | #define I3C_CCC_GETMXDS I3C_CCC_ID(0x14, false) | ||
48 | #define I3C_CCC_GETHDRCAP I3C_CCC_ID(0x15, false) | ||
49 | #define I3C_CCC_GETXTIME I3C_CCC_ID(0x19, false) | ||
50 | |||
51 | #define I3C_CCC_EVENT_SIR BIT(0) | ||
52 | #define I3C_CCC_EVENT_MR BIT(1) | ||
53 | #define I3C_CCC_EVENT_HJ BIT(3) | ||
54 | |||
55 | /** | ||
56 | * struct i3c_ccc_events - payload passed to ENEC/DISEC CCC | ||
57 | * | ||
58 | * @events: bitmask of I3C_CCC_EVENT_xxx events. | ||
59 | * | ||
60 | * Depending on the CCC command, the specific events coming from all devices | ||
61 | * (broadcast version) or a specific device (unicast version) will be | ||
62 | * enabled (ENEC) or disabled (DISEC). | ||
63 | */ | ||
64 | struct i3c_ccc_events { | ||
65 | u8 events; | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * struct i3c_ccc_mwl - payload passed to SETMWL/GETMWL CCC | ||
70 | * | ||
71 | * @len: maximum write length in bytes | ||
72 | * | ||
73 | * The maximum write length is only applicable to SDR private messages or | ||
74 | * extended Write CCCs (like SETXTIME). | ||
75 | */ | ||
76 | struct i3c_ccc_mwl { | ||
77 | __be16 len; | ||
78 | }; | ||
79 | |||
80 | /** | ||
81 | * struct i3c_ccc_mrl - payload passed to SETMRL/GETMRL CCC | ||
82 | * | ||
83 | * @len: maximum read length in bytes | ||
84 | * @ibi_len: maximum IBI payload length | ||
85 | * | ||
86 | * The maximum read length is only applicable to SDR private messages or | ||
87 | * extended Read CCCs (like GETXTIME). | ||
88 | * The IBI length is only valid if the I3C slave is IBI capable | ||
89 | * (%I3C_BCR_IBI_REQ_CAP is set). | ||
90 | */ | ||
91 | struct i3c_ccc_mrl { | ||
92 | __be16 read_len; | ||
93 | u8 ibi_len; | ||
94 | } __packed; | ||
95 | |||
96 | /** | ||
97 | * struct i3c_ccc_dev_desc - I3C/I2C device descriptor used for DEFSLVS | ||
98 | * | ||
99 | * @dyn_addr: dynamic address assigned to the I3C slave or 0 if the entry is | ||
100 | * describing an I2C slave. | ||
101 | * @dcr: DCR value (not applicable to entries describing I2C devices) | ||
102 | * @lvr: LVR value (not applicable to entries describing I3C devices) | ||
103 | * @bcr: BCR value or 0 if this entry is describing an I2C slave | ||
104 | * @static_addr: static address or 0 if the device does not have a static | ||
105 | * address | ||
106 | * | ||
107 | * The DEFSLVS command should be passed an array of i3c_ccc_dev_desc | ||
108 | * descriptors (one entry per I3C/I2C dev controlled by the master). | ||
109 | */ | ||
110 | struct i3c_ccc_dev_desc { | ||
111 | u8 dyn_addr; | ||
112 | union { | ||
113 | u8 dcr; | ||
114 | u8 lvr; | ||
115 | }; | ||
116 | u8 bcr; | ||
117 | u8 static_addr; | ||
118 | }; | ||
119 | |||
120 | /** | ||
121 | * struct i3c_ccc_defslvs - payload passed to DEFSLVS CCC | ||
122 | * | ||
123 | * @count: number of dev descriptors | ||
124 | * @master: descriptor describing the current master | ||
125 | * @slaves: array of descriptors describing slaves controlled by the | ||
126 | * current master | ||
127 | * | ||
128 | * Information passed to the broadcast DEFSLVS to propagate device | ||
129 | * information to all masters currently acting as slaves on the bus. | ||
130 | * This is only meaningful if you have more than one master. | ||
131 | */ | ||
132 | struct i3c_ccc_defslvs { | ||
133 | u8 count; | ||
134 | struct i3c_ccc_dev_desc master; | ||
135 | struct i3c_ccc_dev_desc slaves[0]; | ||
136 | } __packed; | ||
137 | |||
138 | /** | ||
139 | * enum i3c_ccc_test_mode - enum listing all available test modes | ||
140 | * | ||
141 | * @I3C_CCC_EXIT_TEST_MODE: exit test mode | ||
142 | * @I3C_CCC_VENDOR_TEST_MODE: enter vendor test mode | ||
143 | */ | ||
144 | enum i3c_ccc_test_mode { | ||
145 | I3C_CCC_EXIT_TEST_MODE, | ||
146 | I3C_CCC_VENDOR_TEST_MODE, | ||
147 | }; | ||
148 | |||
149 | /** | ||
150 | * struct i3c_ccc_enttm - payload passed to ENTTM CCC | ||
151 | * | ||
152 | * @mode: one of the &enum i3c_ccc_test_mode modes | ||
153 | * | ||
154 | * Information passed to the ENTTM CCC to instruct an I3C device to enter a | ||
155 | * specific test mode. | ||
156 | */ | ||
157 | struct i3c_ccc_enttm { | ||
158 | u8 mode; | ||
159 | }; | ||
160 | |||
161 | /** | ||
162 | * struct i3c_ccc_setda - payload passed to SETNEWDA and SETDASA CCCs | ||
163 | * | ||
164 | * @addr: dynamic address to assign to an I3C device | ||
165 | * | ||
166 | * Information passed to the SETNEWDA and SETDASA CCCs to assign/change the | ||
167 | * dynamic address of an I3C device. | ||
168 | */ | ||
169 | struct i3c_ccc_setda { | ||
170 | u8 addr; | ||
171 | }; | ||
172 | |||
173 | /** | ||
174 | * struct i3c_ccc_getpid - payload passed to GETPID CCC | ||
175 | * | ||
176 | * @pid: 48 bits PID in big endian | ||
177 | */ | ||
178 | struct i3c_ccc_getpid { | ||
179 | u8 pid[6]; | ||
180 | }; | ||
181 | |||
182 | /** | ||
183 | * struct i3c_ccc_getbcr - payload passed to GETBCR CCC | ||
184 | * | ||
185 | * @bcr: BCR (Bus Characteristic Register) value | ||
186 | */ | ||
187 | struct i3c_ccc_getbcr { | ||
188 | u8 bcr; | ||
189 | }; | ||
190 | |||
191 | /** | ||
192 | * struct i3c_ccc_getdcr - payload passed to GETDCR CCC | ||
193 | * | ||
194 | * @dcr: DCR (Device Characteristic Register) value | ||
195 | */ | ||
196 | struct i3c_ccc_getdcr { | ||
197 | u8 dcr; | ||
198 | }; | ||
199 | |||
200 | #define I3C_CCC_STATUS_PENDING_INT(status) ((status) & GENMASK(3, 0)) | ||
201 | #define I3C_CCC_STATUS_PROTOCOL_ERROR BIT(5) | ||
202 | #define I3C_CCC_STATUS_ACTIVITY_MODE(status) \ | ||
203 | (((status) & GENMASK(7, 6)) >> 6) | ||
204 | |||
205 | /** | ||
206 | * struct i3c_ccc_getstatus - payload passed to GETSTATUS CCC | ||
207 | * | ||
208 | * @status: status of the I3C slave (see I3C_CCC_STATUS_xxx macros for more | ||
209 | * information). | ||
210 | */ | ||
211 | struct i3c_ccc_getstatus { | ||
212 | __be16 status; | ||
213 | }; | ||
214 | |||
215 | /** | ||
216 | * struct i3c_ccc_getaccmst - payload passed to GETACCMST CCC | ||
217 | * | ||
218 | * @newmaster: address of the master taking bus ownership | ||
219 | */ | ||
220 | struct i3c_ccc_getaccmst { | ||
221 | u8 newmaster; | ||
222 | }; | ||
223 | |||
224 | /** | ||
225 | * struct i3c_ccc_bridged_slave_desc - bridged slave descriptor | ||
226 | * | ||
227 | * @addr: dynamic address of the bridged device | ||
228 | * @id: ID of the slave device behind the bridge | ||
229 | */ | ||
230 | struct i3c_ccc_bridged_slave_desc { | ||
231 | u8 addr; | ||
232 | __be16 id; | ||
233 | } __packed; | ||
234 | |||
235 | /** | ||
236 | * struct i3c_ccc_setbrgtgt - payload passed to SETBRGTGT CCC | ||
237 | * | ||
238 | * @count: number of bridged slaves | ||
239 | * @bslaves: bridged slave descriptors | ||
240 | */ | ||
241 | struct i3c_ccc_setbrgtgt { | ||
242 | u8 count; | ||
243 | struct i3c_ccc_bridged_slave_desc bslaves[0]; | ||
244 | } __packed; | ||
245 | |||
246 | /** | ||
247 | * enum i3c_sdr_max_data_rate - max data rate values for private SDR transfers | ||
248 | */ | ||
249 | enum i3c_sdr_max_data_rate { | ||
250 | I3C_SDR0_FSCL_MAX, | ||
251 | I3C_SDR1_FSCL_8MHZ, | ||
252 | I3C_SDR2_FSCL_6MHZ, | ||
253 | I3C_SDR3_FSCL_4MHZ, | ||
254 | I3C_SDR4_FSCL_2MHZ, | ||
255 | }; | ||
256 | |||
257 | /** | ||
258 | * enum i3c_tsco - clock to data turn-around | ||
259 | */ | ||
260 | enum i3c_tsco { | ||
261 | I3C_TSCO_8NS, | ||
262 | I3C_TSCO_9NS, | ||
263 | I3C_TSCO_10NS, | ||
264 | I3C_TSCO_11NS, | ||
265 | I3C_TSCO_12NS, | ||
266 | }; | ||
267 | |||
268 | #define I3C_CCC_MAX_SDR_FSCL_MASK GENMASK(2, 0) | ||
269 | #define I3C_CCC_MAX_SDR_FSCL(x) ((x) & I3C_CCC_MAX_SDR_FSCL_MASK) | ||
270 | |||
271 | /** | ||
272 | * struct i3c_ccc_getmxds - payload passed to GETMXDS CCC | ||
273 | * | ||
274 | * @maxwr: write limitations | ||
275 | * @maxrd: read limitations | ||
276 | * @maxrdturn: maximum read turn-around expressed micro-seconds and | ||
277 | * little-endian formatted | ||
278 | */ | ||
279 | struct i3c_ccc_getmxds { | ||
280 | u8 maxwr; | ||
281 | u8 maxrd; | ||
282 | u8 maxrdturn[3]; | ||
283 | } __packed; | ||
284 | |||
285 | #define I3C_CCC_HDR_MODE(mode) BIT(mode) | ||
286 | |||
287 | /** | ||
288 | * struct i3c_ccc_gethdrcap - payload passed to GETHDRCAP CCC | ||
289 | * | ||
290 | * @modes: bitmap of supported HDR modes | ||
291 | */ | ||
292 | struct i3c_ccc_gethdrcap { | ||
293 | u8 modes; | ||
294 | } __packed; | ||
295 | |||
296 | /** | ||
297 | * enum i3c_ccc_setxtime_subcmd - SETXTIME sub-commands | ||
298 | */ | ||
299 | enum i3c_ccc_setxtime_subcmd { | ||
300 | I3C_CCC_SETXTIME_ST = 0x7f, | ||
301 | I3C_CCC_SETXTIME_DT = 0xbf, | ||
302 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE0 = 0xdf, | ||
303 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE1 = 0xef, | ||
304 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE2 = 0xf7, | ||
305 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE3 = 0xfb, | ||
306 | I3C_CCC_SETXTIME_ASYNC_TRIGGER = 0xfd, | ||
307 | I3C_CCC_SETXTIME_TPH = 0x3f, | ||
308 | I3C_CCC_SETXTIME_TU = 0x9f, | ||
309 | I3C_CCC_SETXTIME_ODR = 0x8f, | ||
310 | }; | ||
311 | |||
312 | /** | ||
313 | * struct i3c_ccc_setxtime - payload passed to SETXTIME CCC | ||
314 | * | ||
315 | * @subcmd: one of the sub-commands ddefined in &enum i3c_ccc_setxtime_subcmd | ||
316 | * @data: sub-command payload. Amount of data is determined by | ||
317 | * &i3c_ccc_setxtime->subcmd | ||
318 | */ | ||
319 | struct i3c_ccc_setxtime { | ||
320 | u8 subcmd; | ||
321 | u8 data[0]; | ||
322 | } __packed; | ||
323 | |||
324 | #define I3C_CCC_GETXTIME_SYNC_MODE BIT(0) | ||
325 | #define I3C_CCC_GETXTIME_ASYNC_MODE(x) BIT((x) + 1) | ||
326 | #define I3C_CCC_GETXTIME_OVERFLOW BIT(7) | ||
327 | |||
328 | /** | ||
329 | * struct i3c_ccc_getxtime - payload retrieved from GETXTIME CCC | ||
330 | * | ||
331 | * @supported_modes: bitmap describing supported XTIME modes | ||
332 | * @state: current status (enabled mode and overflow status) | ||
333 | * @frequency: slave's internal oscillator frequency in 500KHz steps | ||
334 | * @inaccuracy: slave's internal oscillator inaccuracy in 0.1% steps | ||
335 | */ | ||
336 | struct i3c_ccc_getxtime { | ||
337 | u8 supported_modes; | ||
338 | u8 state; | ||
339 | u8 frequency; | ||
340 | u8 inaccuracy; | ||
341 | } __packed; | ||
342 | |||
343 | /** | ||
344 | * struct i3c_ccc_cmd_payload - CCC payload | ||
345 | * | ||
346 | * @len: payload length | ||
347 | * @data: payload data. This buffer must be DMA-able | ||
348 | */ | ||
349 | struct i3c_ccc_cmd_payload { | ||
350 | u16 len; | ||
351 | void *data; | ||
352 | }; | ||
353 | |||
354 | /** | ||
355 | * struct i3c_ccc_cmd_dest - CCC command destination | ||
356 | * | ||
357 | * @addr: can be an I3C device address or the broadcast address if this is a | ||
358 | * broadcast CCC | ||
359 | * @payload: payload to be sent to this device or broadcasted | ||
360 | */ | ||
361 | struct i3c_ccc_cmd_dest { | ||
362 | u8 addr; | ||
363 | struct i3c_ccc_cmd_payload payload; | ||
364 | }; | ||
365 | |||
366 | /** | ||
367 | * struct i3c_ccc_cmd - CCC command | ||
368 | * | ||
369 | * @rnw: true if the CCC should retrieve data from the device. Only valid for | ||
370 | * unicast commands | ||
371 | * @id: CCC command id | ||
372 | * @ndests: number of destinations. Should always be one for broadcast commands | ||
373 | * @dests: array of destinations and associated payload for this CCC. Most of | ||
374 | * the time, only one destination is provided | ||
375 | * @err: I3C error code | ||
376 | */ | ||
377 | struct i3c_ccc_cmd { | ||
378 | u8 rnw; | ||
379 | u8 id; | ||
380 | unsigned int ndests; | ||
381 | struct i3c_ccc_cmd_dest *dests; | ||
382 | enum i3c_error_code err; | ||
383 | }; | ||
384 | |||
385 | #endif /* I3C_CCC_H */ | ||