Commit | Line | Data |
---|---|---|
3a379bbc BB |
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_DEV_H | |
9 | #define I3C_DEV_H | |
10 | ||
11 | #include <linux/bitops.h> | |
12 | #include <linux/device.h> | |
13 | #include <linux/i2c.h> | |
14 | #include <linux/kconfig.h> | |
15 | #include <linux/mod_devicetable.h> | |
16 | #include <linux/module.h> | |
17 | ||
18 | /** | |
19 | * enum i3c_error_code - I3C error codes | |
20 | * | |
007ed790 RD |
21 | * @I3C_ERROR_UNKNOWN: unknown error, usually means the error is not I3C |
22 | * related | |
23 | * @I3C_ERROR_M0: M0 error | |
24 | * @I3C_ERROR_M1: M1 error | |
25 | * @I3C_ERROR_M2: M2 error | |
26 | * | |
3a379bbc BB |
27 | * These are the standard error codes as defined by the I3C specification. |
28 | * When -EIO is returned by the i3c_device_do_priv_xfers() or | |
29 | * i3c_device_send_hdr_cmds() one can check the error code in | |
30 | * &struct_i3c_priv_xfer.err or &struct i3c_hdr_cmd.err to get a better idea of | |
31 | * what went wrong. | |
32 | * | |
3a379bbc BB |
33 | */ |
34 | enum i3c_error_code { | |
35 | I3C_ERROR_UNKNOWN = 0, | |
36 | I3C_ERROR_M0 = 1, | |
37 | I3C_ERROR_M1, | |
38 | I3C_ERROR_M2, | |
39 | }; | |
40 | ||
41 | /** | |
42 | * enum i3c_hdr_mode - HDR mode ids | |
43 | * @I3C_HDR_DDR: DDR mode | |
44 | * @I3C_HDR_TSP: TSP mode | |
45 | * @I3C_HDR_TSL: TSL mode | |
46 | */ | |
47 | enum i3c_hdr_mode { | |
48 | I3C_HDR_DDR, | |
49 | I3C_HDR_TSP, | |
50 | I3C_HDR_TSL, | |
51 | }; | |
52 | ||
53 | /** | |
54 | * struct i3c_priv_xfer - I3C SDR private transfer | |
55 | * @rnw: encodes the transfer direction. true for a read, false for a write | |
56 | * @len: transfer length in bytes of the transfer | |
57 | * @data: input/output buffer | |
58 | * @data.in: input buffer. Must point to a DMA-able buffer | |
59 | * @data.out: output buffer. Must point to a DMA-able buffer | |
60 | * @err: I3C error code | |
61 | */ | |
62 | struct i3c_priv_xfer { | |
63 | u8 rnw; | |
64 | u16 len; | |
65 | union { | |
66 | void *in; | |
67 | const void *out; | |
68 | } data; | |
69 | enum i3c_error_code err; | |
70 | }; | |
71 | ||
72 | /** | |
73 | * enum i3c_dcr - I3C DCR values | |
74 | * @I3C_DCR_GENERIC_DEVICE: generic I3C device | |
75 | */ | |
76 | enum i3c_dcr { | |
77 | I3C_DCR_GENERIC_DEVICE = 0, | |
78 | }; | |
79 | ||
80 | #define I3C_PID_MANUF_ID(pid) (((pid) & GENMASK_ULL(47, 33)) >> 33) | |
81 | #define I3C_PID_RND_LOWER_32BITS(pid) (!!((pid) & BIT_ULL(32))) | |
82 | #define I3C_PID_RND_VAL(pid) ((pid) & GENMASK_ULL(31, 0)) | |
83 | #define I3C_PID_PART_ID(pid) (((pid) & GENMASK_ULL(31, 16)) >> 16) | |
84 | #define I3C_PID_INSTANCE_ID(pid) (((pid) & GENMASK_ULL(15, 12)) >> 12) | |
85 | #define I3C_PID_EXTRA_INFO(pid) ((pid) & GENMASK_ULL(11, 0)) | |
86 | ||
87 | #define I3C_BCR_DEVICE_ROLE(bcr) ((bcr) & GENMASK(7, 6)) | |
88 | #define I3C_BCR_I3C_SLAVE (0 << 6) | |
89 | #define I3C_BCR_I3C_MASTER (1 << 6) | |
90 | #define I3C_BCR_HDR_CAP BIT(5) | |
91 | #define I3C_BCR_BRIDGE BIT(4) | |
92 | #define I3C_BCR_OFFLINE_CAP BIT(3) | |
93 | #define I3C_BCR_IBI_PAYLOAD BIT(2) | |
94 | #define I3C_BCR_IBI_REQ_CAP BIT(1) | |
95 | #define I3C_BCR_MAX_DATA_SPEED_LIM BIT(0) | |
96 | ||
97 | /** | |
98 | * struct i3c_device_info - I3C device information | |
99 | * @pid: Provisional ID | |
100 | * @bcr: Bus Characteristic Register | |
101 | * @dcr: Device Characteristic Register | |
102 | * @static_addr: static/I2C address | |
103 | * @dyn_addr: dynamic address | |
104 | * @hdr_cap: supported HDR modes | |
105 | * @max_read_ds: max read speed information | |
106 | * @max_write_ds: max write speed information | |
107 | * @max_ibi_len: max IBI payload length | |
108 | * @max_read_turnaround: max read turn-around time in micro-seconds | |
109 | * @max_read_len: max private SDR read length in bytes | |
110 | * @max_write_len: max private SDR write length in bytes | |
111 | * | |
112 | * These are all basic information that should be advertised by an I3C device. | |
113 | * Some of them are optional depending on the device type and device | |
114 | * capabilities. | |
115 | * For each I3C slave attached to a master with | |
116 | * i3c_master_add_i3c_dev_locked(), the core will send the relevant CCC command | |
117 | * to retrieve these data. | |
118 | */ | |
119 | struct i3c_device_info { | |
120 | u64 pid; | |
121 | u8 bcr; | |
122 | u8 dcr; | |
123 | u8 static_addr; | |
124 | u8 dyn_addr; | |
125 | u8 hdr_cap; | |
126 | u8 max_read_ds; | |
127 | u8 max_write_ds; | |
128 | u8 max_ibi_len; | |
129 | u32 max_read_turnaround; | |
130 | u16 max_read_len; | |
131 | u16 max_write_len; | |
132 | }; | |
133 | ||
134 | /* | |
135 | * I3C device internals are kept hidden from I3C device users. It's just | |
136 | * simpler to refactor things when everything goes through getter/setters, and | |
137 | * I3C device drivers should not have to worry about internal representation | |
138 | * anyway. | |
139 | */ | |
140 | struct i3c_device; | |
141 | ||
142 | /* These macros should be used to i3c_device_id entries. */ | |
143 | #define I3C_MATCH_MANUF_AND_PART (I3C_MATCH_MANUF | I3C_MATCH_PART) | |
144 | ||
145 | #define I3C_DEVICE(_manufid, _partid, _drvdata) \ | |
146 | { \ | |
147 | .match_flags = I3C_MATCH_MANUF_AND_PART, \ | |
148 | .manuf_id = _manufid, \ | |
149 | .part_id = _partid, \ | |
150 | .data = _drvdata, \ | |
151 | } | |
152 | ||
153 | #define I3C_DEVICE_EXTRA_INFO(_manufid, _partid, _info, _drvdata) \ | |
154 | { \ | |
155 | .match_flags = I3C_MATCH_MANUF_AND_PART | \ | |
156 | I3C_MATCH_EXTRA_INFO, \ | |
157 | .manuf_id = _manufid, \ | |
158 | .part_id = _partid, \ | |
159 | .extra_info = _info, \ | |
160 | .data = _drvdata, \ | |
161 | } | |
162 | ||
163 | #define I3C_CLASS(_dcr, _drvdata) \ | |
164 | { \ | |
165 | .match_flags = I3C_MATCH_DCR, \ | |
166 | .dcr = _dcr, \ | |
167 | } | |
168 | ||
169 | /** | |
170 | * struct i3c_driver - I3C device driver | |
171 | * @driver: inherit from device_driver | |
172 | * @probe: I3C device probe method | |
173 | * @remove: I3C device remove method | |
174 | * @id_table: I3C device match table. Will be used by the framework to decide | |
175 | * which device to bind to this driver | |
176 | */ | |
177 | struct i3c_driver { | |
178 | struct device_driver driver; | |
179 | int (*probe)(struct i3c_device *dev); | |
dd926703 | 180 | void (*remove)(struct i3c_device *dev); |
3a379bbc BB |
181 | const struct i3c_device_id *id_table; |
182 | }; | |
183 | ||
184 | static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv) | |
185 | { | |
186 | return container_of(drv, struct i3c_driver, driver); | |
187 | } | |
188 | ||
189 | struct device *i3cdev_to_dev(struct i3c_device *i3cdev); | |
fa838c8c GKH |
190 | |
191 | /** | |
192 | * dev_to_i3cdev() - Returns the I3C device containing @dev | |
007ed790 | 193 | * @__dev: device object |
fa838c8c GKH |
194 | * |
195 | * Return: a pointer to an I3C device object. | |
196 | */ | |
197 | #define dev_to_i3cdev(__dev) container_of_const(__dev, struct i3c_device, dev) | |
3a379bbc | 198 | |
934d24a5 VS |
199 | const struct i3c_device_id * |
200 | i3c_device_match_id(struct i3c_device *i3cdev, | |
201 | const struct i3c_device_id *id_table); | |
202 | ||
3a379bbc BB |
203 | static inline void i3cdev_set_drvdata(struct i3c_device *i3cdev, |
204 | void *data) | |
205 | { | |
206 | struct device *dev = i3cdev_to_dev(i3cdev); | |
207 | ||
208 | dev_set_drvdata(dev, data); | |
209 | } | |
210 | ||
211 | static inline void *i3cdev_get_drvdata(struct i3c_device *i3cdev) | |
212 | { | |
213 | struct device *dev = i3cdev_to_dev(i3cdev); | |
214 | ||
215 | return dev_get_drvdata(dev); | |
216 | } | |
217 | ||
218 | int i3c_driver_register_with_owner(struct i3c_driver *drv, | |
219 | struct module *owner); | |
220 | void i3c_driver_unregister(struct i3c_driver *drv); | |
221 | ||
222 | #define i3c_driver_register(__drv) \ | |
223 | i3c_driver_register_with_owner(__drv, THIS_MODULE) | |
224 | ||
225 | /** | |
226 | * module_i3c_driver() - Register a module providing an I3C driver | |
227 | * @__drv: the I3C driver to register | |
228 | * | |
229 | * Provide generic init/exit functions that simply register/unregister an I3C | |
230 | * driver. | |
231 | * Should be used by any driver that does not require extra init/cleanup steps. | |
232 | */ | |
233 | #define module_i3c_driver(__drv) \ | |
234 | module_driver(__drv, i3c_driver_register, i3c_driver_unregister) | |
235 | ||
236 | /** | |
237 | * i3c_i2c_driver_register() - Register an i2c and an i3c driver | |
238 | * @i3cdrv: the I3C driver to register | |
239 | * @i2cdrv: the I2C driver to register | |
240 | * | |
241 | * This function registers both @i2cdev and @i3cdev, and fails if one of these | |
242 | * registrations fails. This is mainly useful for devices that support both I2C | |
243 | * and I3C modes. | |
244 | * Note that when CONFIG_I3C is not enabled, this function only registers the | |
245 | * I2C driver. | |
246 | * | |
247 | * Return: 0 if both registrations succeeds, a negative error code otherwise. | |
248 | */ | |
249 | static inline int i3c_i2c_driver_register(struct i3c_driver *i3cdrv, | |
250 | struct i2c_driver *i2cdrv) | |
251 | { | |
252 | int ret; | |
253 | ||
254 | ret = i2c_add_driver(i2cdrv); | |
255 | if (ret || !IS_ENABLED(CONFIG_I3C)) | |
256 | return ret; | |
257 | ||
258 | ret = i3c_driver_register(i3cdrv); | |
259 | if (ret) | |
260 | i2c_del_driver(i2cdrv); | |
261 | ||
262 | return ret; | |
263 | } | |
264 | ||
265 | /** | |
266 | * i3c_i2c_driver_unregister() - Unregister an i2c and an i3c driver | |
267 | * @i3cdrv: the I3C driver to register | |
268 | * @i2cdrv: the I2C driver to register | |
269 | * | |
270 | * This function unregisters both @i3cdrv and @i2cdrv. | |
271 | * Note that when CONFIG_I3C is not enabled, this function only unregisters the | |
272 | * @i2cdrv. | |
273 | */ | |
274 | static inline void i3c_i2c_driver_unregister(struct i3c_driver *i3cdrv, | |
275 | struct i2c_driver *i2cdrv) | |
276 | { | |
277 | if (IS_ENABLED(CONFIG_I3C)) | |
278 | i3c_driver_unregister(i3cdrv); | |
279 | ||
280 | i2c_del_driver(i2cdrv); | |
281 | } | |
282 | ||
283 | /** | |
284 | * module_i3c_i2c_driver() - Register a module providing an I3C and an I2C | |
285 | * driver | |
286 | * @__i3cdrv: the I3C driver to register | |
287 | * @__i2cdrv: the I3C driver to register | |
288 | * | |
289 | * Provide generic init/exit functions that simply register/unregister an I3C | |
290 | * and an I2C driver. | |
291 | * This macro can be used even if CONFIG_I3C is disabled, in this case, only | |
292 | * the I2C driver will be registered. | |
293 | * Should be used by any driver that does not require extra init/cleanup steps. | |
294 | */ | |
295 | #define module_i3c_i2c_driver(__i3cdrv, __i2cdrv) \ | |
296 | module_driver(__i3cdrv, \ | |
297 | i3c_i2c_driver_register, \ | |
01744ce9 NKC |
298 | i3c_i2c_driver_unregister, \ |
299 | __i2cdrv) | |
3a379bbc BB |
300 | |
301 | int i3c_device_do_priv_xfers(struct i3c_device *dev, | |
302 | struct i3c_priv_xfer *xfers, | |
303 | int nxfers); | |
304 | ||
672825cd JC |
305 | int i3c_device_do_setdasa(struct i3c_device *dev); |
306 | ||
162736b0 | 307 | void i3c_device_get_info(const struct i3c_device *dev, struct i3c_device_info *info); |
3a379bbc BB |
308 | |
309 | struct i3c_ibi_payload { | |
310 | unsigned int len; | |
311 | const void *data; | |
312 | }; | |
313 | ||
314 | /** | |
315 | * struct i3c_ibi_setup - IBI setup object | |
316 | * @max_payload_len: maximum length of the payload associated to an IBI. If one | |
317 | * IBI appears to have a payload that is bigger than this | |
318 | * number, the IBI will be rejected. | |
319 | * @num_slots: number of pre-allocated IBI slots. This should be chosen so that | |
320 | * the system never runs out of IBI slots, otherwise you'll lose | |
321 | * IBIs. | |
322 | * @handler: IBI handler, every time an IBI is received. This handler is called | |
323 | * in a workqueue context. It is allowed to sleep and send new | |
324 | * messages on the bus, though it's recommended to keep the | |
325 | * processing done there as fast as possible to avoid delaying | |
326 | * processing of other queued on the same workqueue. | |
327 | * | |
328 | * Temporary structure used to pass information to i3c_device_request_ibi(). | |
329 | * This object can be allocated on the stack since i3c_device_request_ibi() | |
330 | * copies every bit of information and do not use it after | |
331 | * i3c_device_request_ibi() has returned. | |
332 | */ | |
333 | struct i3c_ibi_setup { | |
334 | unsigned int max_payload_len; | |
335 | unsigned int num_slots; | |
336 | void (*handler)(struct i3c_device *dev, | |
337 | const struct i3c_ibi_payload *payload); | |
338 | }; | |
339 | ||
340 | int i3c_device_request_ibi(struct i3c_device *dev, | |
341 | const struct i3c_ibi_setup *setup); | |
342 | void i3c_device_free_ibi(struct i3c_device *dev); | |
343 | int i3c_device_enable_ibi(struct i3c_device *dev); | |
344 | int i3c_device_disable_ibi(struct i3c_device *dev); | |
345 | ||
346 | #endif /* I3C_DEV_H */ |