Line data Source code
1 1 : /*
2 : * Copyright (c) 2022 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @ingroup smbus_interface
10 : * @brief Main header file for SMBus (System Management Bus) driver API.
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
14 : #define ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
15 :
16 : /**
17 : * @brief Interfaces for System Management Bus (SMBus).
18 : * @defgroup smbus_interface SMBus
19 : * @since 3.4
20 : * @version 0.1.0
21 : * @ingroup io_interfaces
22 : * @{
23 : */
24 :
25 : #include <errno.h>
26 : #include <zephyr/sys/slist.h>
27 : #include <zephyr/types.h>
28 : #include <zephyr/device.h>
29 :
30 : #ifdef __cplusplus
31 : extern "C" {
32 : #endif
33 :
34 : /**
35 : * @name SMBus Protocol commands
36 : * @{
37 : *
38 : * SMBus Specification defines the following SMBus protocols operations
39 : */
40 :
41 : /**
42 : * SMBus Quick protocol is a very simple command with no data sent or
43 : * received. Peripheral may denote only R/W bit, which can still be
44 : * used for the peripheral management, for example to switch peripheral
45 : * On/Off. Quick protocol can also be used for peripheral devices
46 : * scanning.
47 : *
48 : * @code
49 : * 0 1
50 : * 0 1 2 3 4 5 6 7 8 9 0
51 : * +-+-+-+-+-+-+-+-+-+-+-+
52 : * |S| Periph Addr |D|A|P|
53 : * +-+-+-+-+-+-+-+-+-+-+-+
54 : * @endcode
55 : */
56 1 : #define SMBUS_CMD_QUICK 0b000
57 :
58 : /**
59 : * SMBus Byte protocol can send or receive one byte of data.
60 : *
61 : * @code
62 : * Byte Write
63 : *
64 : * 0 1 2
65 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
66 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 : * |S| Periph Addr |W|A| Command code |A|P|
68 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 : *
70 : * Byte Read
71 : *
72 : * 0 1 2
73 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
74 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 : * |S| Periph Addr |R|A| Byte received |N|P|
76 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 : * @endcode
78 : */
79 1 : #define SMBUS_CMD_BYTE 0b001
80 :
81 : /**
82 : * SMBus Byte Data protocol sends the first byte (command) followed
83 : * by read or write one byte.
84 : *
85 : * @code
86 : * Byte Data Write
87 : *
88 : * 0 1 2
89 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
90 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
91 : * |S| Periph Addr |W|A| Command code |A| Data Write |A|P|
92 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
93 : *
94 : * Byte Data Read
95 : *
96 : * 0 1 2
97 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
98 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99 : * |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|A|
100 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101 : * | Data Read |N|P|
102 : * +-+-+-+-+-+-+-+-+-+-+
103 : * @endcode
104 : */
105 1 : #define SMBUS_CMD_BYTE_DATA 0b010
106 :
107 : /**
108 : * SMBus Word Data protocol sends the first byte (command) followed
109 : * by read or write two bytes.
110 : *
111 : * @code
112 : * Word Data Write
113 : *
114 : * 0 1 2
115 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
116 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117 : * |S| Periph Addr |W|A| Command code |A| Data Write Low|A|
118 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119 : * | Data Write Hi |A|P|
120 : * +-+-+-+-+-+-+-+-+-+-+
121 : *
122 : * Word Data Read
123 : *
124 : * 0 1 2
125 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
126 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127 : * |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|
128 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129 : * |A| Data Read Low |A| Data Read Hi |N|P|
130 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131 : * @endcode
132 : */
133 1 : #define SMBUS_CMD_WORD_DATA 0b011
134 :
135 : /**
136 : * SMBus Process Call protocol is Write Word followed by
137 : * Read Word. It is named so because the command sends data and waits
138 : * for the peripheral to return a reply.
139 : *
140 : * @code
141 : * 0 1 2
142 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
143 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144 : * |S| Periph Addr |W|A| Command code |A| Data Write Low|A|
145 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146 : * | Data Write Hi |A|S| Periph Addr |R|A| Data Read Low |A|
147 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148 : * | Data Read Hi |N|P|
149 : * +-+-+-+-+-+-+-+-+-+-+
150 : * @endcode
151 : */
152 1 : #define SMBUS_CMD_PROC_CALL 0b100
153 :
154 : /**
155 : * SMBus Block protocol reads or writes a block of data up to 32 bytes.
156 : * The Count byte specifies the amount of data.
157 : *
158 : * @code
159 : *
160 : * SMBus Block Write
161 : *
162 : * 0 1 2
163 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
164 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165 : * |S| Periph Addr |W|A| Command code |A| Send Count=N |A|
166 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167 : * | Data Write 1 |A| ... |A| Data Write N |A|P|
168 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
169 : *
170 : * SMBus Block Read
171 : *
172 : * 0 1 2
173 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
174 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
175 : * |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|
176 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
177 : * |A| Recv Count=N |A| Data Read 1 |A| ... |A|
178 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179 : * | Data Read N |N|P|
180 : * +-+-+-+-+-+-+-+-+-+-+
181 : * @endcode
182 : */
183 1 : #define SMBUS_CMD_BLOCK 0b101
184 :
185 : /**
186 : * SMBus Block Write - Block Read Process Call protocol is
187 : * Block Write followed by Block Read.
188 : *
189 : * @code
190 : * 0 1 2
191 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
192 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
193 : * |S| Periph Addr |W|A| Command code |A| Count = N |A|
194 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
195 : * | Data Write 1 |A| ... |A| Data Write N |A|S|
196 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
197 : * | Periph Addr |R|A| Recv Count=N |A| Data Read 1 |A| |
198 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199 : * | ... |A| Data Read N |N|P|
200 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201 : * @endcode
202 : */
203 1 : #define SMBUS_CMD_BLOCK_PROC 0b111
204 : /** @} */
205 :
206 : /** Maximum number of bytes in SMBus Block protocol */
207 1 : #define SMBUS_BLOCK_BYTES_MAX 32
208 :
209 : /**
210 : * @name SMBus device functionality
211 : * @{
212 : *
213 : * The following parameters describe the functionality of the SMBus device
214 : */
215 :
216 : /** Peripheral to act as Controller. */
217 1 : #define SMBUS_MODE_CONTROLLER BIT(0)
218 :
219 : /** Support Packet Error Code (PEC) checking */
220 1 : #define SMBUS_MODE_PEC BIT(1)
221 :
222 : /** Support Host Notify functionality */
223 1 : #define SMBUS_MODE_HOST_NOTIFY BIT(2)
224 :
225 : /** Support SMBALERT signal functionality */
226 1 : #define SMBUS_MODE_SMBALERT BIT(3)
227 :
228 : /** @} */
229 :
230 : /**
231 : * @name SMBus special reserved addresses
232 : * @{
233 : *
234 : * The following addresses are reserved by SMBus specification
235 : */
236 :
237 : /**
238 : * @brief Alert Response Address (ARA)
239 : *
240 : * A broadcast address used by the system host as part of the
241 : * Alert Response Protocol.
242 : */
243 1 : #define SMBUS_ADDRESS_ARA 0x0c
244 :
245 : /** @} */
246 :
247 : /**
248 : * @name SMBus read / write direction
249 : * @{
250 : */
251 :
252 : /** @brief SMBus read / write direction */
253 1 : enum smbus_direction {
254 : /** Write a message to SMBus peripheral */
255 : SMBUS_MSG_WRITE = 0,
256 : /** Read a message from SMBus peripheral */
257 : SMBUS_MSG_READ = 1,
258 : };
259 :
260 : /** @} */
261 :
262 : /** @cond INTERNAL_HIDDEN */
263 : #define SMBUS_MSG_RW_MASK BIT(0)
264 : /** @endcond */
265 :
266 : struct smbus_callback;
267 :
268 : /**
269 : * @brief Define SMBus callback handler function signature.
270 : *
271 : * @param dev Pointer to the device structure for the SMBus driver instance.
272 : * @param cb Structure smbus_callback owning this handler.
273 : * @param addr Address of the SMBus peripheral device.
274 : */
275 1 : typedef void (*smbus_callback_handler_t)(const struct device *dev,
276 : struct smbus_callback *cb,
277 : uint8_t addr);
278 :
279 : /**
280 : * @brief SMBus callback structure
281 : *
282 : * Used to register a callback in the driver instance callback list.
283 : * As many callbacks as needed can be added as long as each of them
284 : * is a unique pointer of struct smbus_callback.
285 : *
286 : * Note: Such struct should not be allocated on stack.
287 : */
288 1 : struct smbus_callback {
289 : /** This should be used in driver for a callback list management */
290 1 : sys_snode_t node;
291 :
292 : /** Actual callback function being called when relevant */
293 1 : smbus_callback_handler_t handler;
294 :
295 : /** Peripheral device address */
296 1 : uint8_t addr;
297 : };
298 :
299 : /**
300 : * @brief Complete SMBus DT information
301 : */
302 1 : struct smbus_dt_spec {
303 : /** SMBus bus */
304 1 : const struct device *bus;
305 : /** Address of the SMBus peripheral device */
306 1 : uint16_t addr;
307 : };
308 :
309 : /**
310 : * @brief Structure initializer for smbus_dt_spec from devicetree
311 : *
312 : * This helper macro expands to a static initializer for a <tt>struct
313 : * smbus_dt_spec</tt> by reading the relevant bus and address data from
314 : * the devicetree.
315 : *
316 : * @param node_id Devicetree node identifier for the SMBus device whose
317 : * struct smbus_dt_spec to create an initializer for
318 : */
319 1 : #define SMBUS_DT_SPEC_GET(node_id) \
320 : { \
321 : .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
322 : .addr = DT_REG_ADDR(node_id) \
323 : }
324 :
325 : /**
326 : * @brief Structure initializer for smbus_dt_spec from devicetree instance
327 : *
328 : * This is equivalent to
329 : * <tt>SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))</tt>.
330 : *
331 : * @param inst Devicetree instance number
332 : */
333 1 : #define SMBUS_DT_SPEC_INST_GET(inst) SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
334 :
335 : /**
336 : * @cond INTERNAL_HIDDEN
337 : *
338 : * These are for internal use only, so skip these in
339 : * public documentation.
340 : */
341 :
342 : typedef int (*smbus_api_configure_t)(const struct device *dev,
343 : uint32_t dev_config);
344 : typedef int (*smbus_api_get_config_t)(const struct device *dev,
345 : uint32_t *dev_config);
346 : typedef int (*smbus_api_quick_t)(const struct device *dev,
347 : uint16_t addr, enum smbus_direction);
348 : typedef int (*smbus_api_byte_write_t)(const struct device *dev,
349 : uint16_t addr, uint8_t byte);
350 : typedef int (*smbus_api_byte_read_t)(const struct device *dev,
351 : uint16_t addr, uint8_t *byte);
352 : typedef int (*smbus_api_byte_data_write_t)(const struct device *dev,
353 : uint16_t addr, uint8_t cmd,
354 : uint8_t byte);
355 : typedef int (*smbus_api_byte_data_read_t)(const struct device *dev,
356 : uint16_t addr, uint8_t cmd,
357 : uint8_t *byte);
358 : typedef int (*smbus_api_word_data_write_t)(const struct device *dev,
359 : uint16_t addr, uint8_t cmd,
360 : uint16_t word);
361 : typedef int (*smbus_api_word_data_read_t)(const struct device *dev,
362 : uint16_t addr, uint8_t cmd,
363 : uint16_t *word);
364 : typedef int (*smbus_api_pcall_t)(const struct device *dev,
365 : uint16_t addr, uint8_t cmd,
366 : uint16_t send_word, uint16_t *recv_word);
367 : typedef int (*smbus_api_block_write_t)(const struct device *dev,
368 : uint16_t addr, uint8_t cmd,
369 : uint8_t count, uint8_t *buf);
370 : typedef int (*smbus_api_block_read_t)(const struct device *dev,
371 : uint16_t addr, uint8_t cmd,
372 : uint8_t *count, uint8_t *buf);
373 : typedef int (*smbus_api_block_pcall_t)(const struct device *dev,
374 : uint16_t addr, uint8_t cmd,
375 : uint8_t send_count, uint8_t *send_buf,
376 : uint8_t *recv_count, uint8_t *recv_buf);
377 : typedef int (*smbus_api_smbalert_cb_t)(const struct device *dev,
378 : struct smbus_callback *cb);
379 : typedef int (*smbus_api_host_notify_cb_t)(const struct device *dev,
380 : struct smbus_callback *cb);
381 :
382 : __subsystem struct smbus_driver_api {
383 : smbus_api_configure_t configure;
384 : smbus_api_get_config_t get_config;
385 : smbus_api_quick_t smbus_quick;
386 : smbus_api_byte_write_t smbus_byte_write;
387 : smbus_api_byte_read_t smbus_byte_read;
388 : smbus_api_byte_data_write_t smbus_byte_data_write;
389 : smbus_api_byte_data_read_t smbus_byte_data_read;
390 : smbus_api_word_data_write_t smbus_word_data_write;
391 : smbus_api_word_data_read_t smbus_word_data_read;
392 : smbus_api_pcall_t smbus_pcall;
393 : smbus_api_block_write_t smbus_block_write;
394 : smbus_api_block_read_t smbus_block_read;
395 : smbus_api_block_pcall_t smbus_block_pcall;
396 : smbus_api_smbalert_cb_t smbus_smbalert_set_cb;
397 : smbus_api_smbalert_cb_t smbus_smbalert_remove_cb;
398 : smbus_api_host_notify_cb_t smbus_host_notify_set_cb;
399 : smbus_api_host_notify_cb_t smbus_host_notify_remove_cb;
400 : };
401 :
402 : /**
403 : * @endcond
404 : */
405 :
406 : #if defined(CONFIG_SMBUS_STATS) || defined(__DOXYGEN__)
407 :
408 : #include <zephyr/stats/stats.h>
409 :
410 : /** @cond INTERNAL_HIDDEN */
411 :
412 : STATS_SECT_START(smbus)
413 : STATS_SECT_ENTRY32(bytes_read)
414 : STATS_SECT_ENTRY32(bytes_written)
415 : STATS_SECT_ENTRY32(command_count)
416 : STATS_SECT_END;
417 :
418 : STATS_NAME_START(smbus)
419 : STATS_NAME(smbus, bytes_read)
420 : STATS_NAME(smbus, bytes_written)
421 : STATS_NAME(smbus, command_count)
422 : STATS_NAME_END(smbus);
423 :
424 : struct smbus_device_state {
425 : struct device_state devstate;
426 : struct stats_smbus stats;
427 : };
428 :
429 : /**
430 : * @brief Define a statically allocated and section assigned smbus device state
431 : */
432 : #define Z_SMBUS_DEVICE_STATE_DEFINE(node_id, dev_name) \
433 : static struct smbus_device_state Z_DEVICE_STATE_NAME(dev_name) \
434 : __attribute__((__section__(".z_devstate")));
435 :
436 : /**
437 : * @brief Define an smbus device init wrapper function
438 : *
439 : * This does device instance specific initialization of common data
440 : * (such as stats) and calls the given init_fn
441 : */
442 : #define Z_SMBUS_INIT_FN(dev_name, init_fn) \
443 : static inline int \
444 : UTIL_CAT(dev_name, _init)(const struct device *dev) \
445 : { \
446 : struct smbus_device_state *state = \
447 : CONTAINER_OF(dev->state, \
448 : struct smbus_device_state, \
449 : devstate); \
450 : stats_init(&state->stats.s_hdr, STATS_SIZE_32, 4, \
451 : STATS_NAME_INIT_PARMS(smbus)); \
452 : stats_register(dev->name, &(state->stats.s_hdr)); \
453 : return init_fn(dev); \
454 : }
455 :
456 : /** @endcond */
457 :
458 : /**
459 : * @brief Updates the SMBus stats
460 : *
461 : * @param dev Pointer to the device structure for the SMBus driver instance
462 : * to update stats for.
463 : * @param sent Number of bytes sent
464 : * @param recv Number of bytes received
465 : */
466 1 : static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
467 : uint8_t recv)
468 : {
469 : struct smbus_device_state *state =
470 : CONTAINER_OF(dev->state, struct smbus_device_state, devstate);
471 :
472 : STATS_INC(state->stats, command_count);
473 : STATS_INCN(state->stats, bytes_read, recv);
474 : STATS_INCN(state->stats, bytes_written, sent);
475 : }
476 :
477 : /**
478 : * @brief Like DEVICE_DT_DEFINE() with SMBus specifics.
479 : *
480 : * @details Defines a device which implements the SMBus API. May
481 : * generate a custom device_state container struct and init_fn
482 : * wrapper when needed depending on SMBus @kconfig{CONFIG_SMBUS_STATS}.
483 : *
484 : * @param node_id The devicetree node identifier.
485 : *
486 : * @param init_fn Name of the init function of the driver.
487 : *
488 : * @param pm_device PM device resources reference
489 : * (NULL if device does not use PM).
490 : *
491 : * @param data_ptr Pointer to the device's private data.
492 : *
493 : * @param cfg_ptr The address to the structure containing the
494 : * configuration information for this instance of the driver.
495 : *
496 : * @param level The initialization level. See SYS_INIT() for
497 : * details.
498 : *
499 : * @param prio Priority within the selected initialization level. See
500 : * SYS_INIT() for details.
501 : *
502 : * @param api_ptr Provides an initial pointer to the API function struct
503 : * used by the driver. Can be NULL.
504 : */
505 : #define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
506 : data_ptr, cfg_ptr, level, prio, \
507 1 : api_ptr, ...) \
508 : Z_SMBUS_DEVICE_STATE_DEFINE(node_id, \
509 : Z_DEVICE_DT_DEV_NAME(node_id)); \
510 : Z_SMBUS_INIT_FN(Z_DEVICE_DT_DEV_NAME(node_id), init_fn) \
511 : Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
512 : DEVICE_DT_NAME(node_id), \
513 : &UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init),\
514 : NULL, Z_DEVICE_DT_FLAGS(node_id), pm_device, \
515 : data_ptr, cfg_ptr, level, prio, \
516 : api_ptr, \
517 : &(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME \
518 : (node_id)).devstate), \
519 : __VA_ARGS__)
520 :
521 : #else /* CONFIG_SMBUS_STATS */
522 :
523 : static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
524 : uint8_t recv)
525 : {
526 : ARG_UNUSED(dev);
527 : ARG_UNUSED(sent);
528 : ARG_UNUSED(recv);
529 : }
530 :
531 : #define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
532 : data_ptr, cfg_ptr, level, prio, \
533 : api_ptr, ...) \
534 : DEVICE_DT_DEFINE(node_id, &init_fn, pm_device, \
535 : data_ptr, cfg_ptr, level, prio, \
536 : api_ptr, __VA_ARGS__)
537 :
538 : #endif /* CONFIG_SMBUS_STATS */
539 :
540 : /**
541 : * @brief Like SMBUS_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT
542 : * compatible
543 : *
544 : * @param inst instance number. This is replaced by
545 : * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SMBUS_DEVICE_DT_DEFINE().
546 : *
547 : * @param ... other parameters as expected by SMBUS_DEVICE_DT_DEFINE().
548 : */
549 1 : #define SMBUS_DEVICE_DT_INST_DEFINE(inst, ...) \
550 : SMBUS_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
551 :
552 : /**
553 : * @brief Configure operation of a SMBus host controller.
554 : *
555 : * @param dev Pointer to the device structure for the SMBus driver instance.
556 : * @param dev_config Bit-packed 32-bit value to the device runtime configuration
557 : * for the SMBus controller.
558 : *
559 : * @retval 0 If successful.
560 : * @retval -EIO General input / output error.
561 : */
562 1 : __syscall int smbus_configure(const struct device *dev, uint32_t dev_config);
563 :
564 : static inline int z_impl_smbus_configure(const struct device *dev,
565 : uint32_t dev_config)
566 : {
567 : const struct smbus_driver_api *api =
568 : (const struct smbus_driver_api *)dev->api;
569 :
570 : return api->configure(dev, dev_config);
571 : }
572 :
573 : /**
574 : * @brief Get configuration of a SMBus host controller.
575 : *
576 : * This routine provides a way to get current configuration. It is allowed to
577 : * call the function before smbus_configure, because some SMBus ports can be
578 : * configured during init process. However, if the SMBus port is not configured,
579 : * smbus_get_config returns an error.
580 : *
581 : * smbus_get_config can return cached config or probe hardware, but it has to be
582 : * up to date with current configuration.
583 : *
584 : * @param dev Pointer to the device structure for the SMBus driver instance.
585 : * @param dev_config Pointer to return bit-packed 32-bit value of
586 : * the SMBus controller configuration.
587 : *
588 : * @retval 0 If successful.
589 : * @retval -EIO General input / output error.
590 : * @retval -ENOSYS If function smbus_get_config() is not implemented
591 : * by the driver.
592 : */
593 1 : __syscall int smbus_get_config(const struct device *dev, uint32_t *dev_config);
594 :
595 : static inline int z_impl_smbus_get_config(const struct device *dev,
596 : uint32_t *dev_config)
597 : {
598 : const struct smbus_driver_api *api =
599 : (const struct smbus_driver_api *)dev->api;
600 :
601 : if (api->get_config == NULL) {
602 : return -ENOSYS;
603 : }
604 :
605 : return api->get_config(dev, dev_config);
606 : }
607 :
608 : /**
609 : * @brief Add SMBUSALERT callback for a SMBus host controller.
610 : *
611 : * @param dev Pointer to the device structure for the SMBus driver instance.
612 : * @param cb Pointer to a callback structure.
613 : *
614 : * @retval 0 If successful.
615 : * @retval -EIO General input / output error.
616 : * @retval -ENOSYS If function smbus_smbalert_set_cb() is not implemented
617 : * by the driver.
618 : */
619 1 : static inline int smbus_smbalert_set_cb(const struct device *dev,
620 : struct smbus_callback *cb)
621 : {
622 : const struct smbus_driver_api *api =
623 : (const struct smbus_driver_api *)dev->api;
624 :
625 : if (api->smbus_smbalert_set_cb == NULL) {
626 : return -ENOSYS;
627 : }
628 :
629 : return api->smbus_smbalert_set_cb(dev, cb);
630 : }
631 :
632 : /**
633 : * @brief Remove SMBUSALERT callback from a SMBus host controller.
634 : *
635 : * @param dev Pointer to the device structure for the SMBus driver instance.
636 : * @param cb Pointer to a callback structure.
637 : *
638 : * @retval 0 If successful.
639 : * @retval -EIO General input / output error.
640 : * @retval -ENOSYS If function smbus_smbalert_remove_cb() is not implemented
641 : * by the driver.
642 : */
643 1 : __syscall int smbus_smbalert_remove_cb(const struct device *dev,
644 : struct smbus_callback *cb);
645 :
646 : static inline int z_impl_smbus_smbalert_remove_cb(const struct device *dev,
647 : struct smbus_callback *cb)
648 : {
649 : const struct smbus_driver_api *api =
650 : (const struct smbus_driver_api *)dev->api;
651 :
652 : if (api->smbus_smbalert_remove_cb == NULL) {
653 : return -ENOSYS;
654 : }
655 :
656 : return api->smbus_smbalert_remove_cb(dev, cb);
657 : }
658 :
659 : /**
660 : * @brief Add Host Notify callback for a SMBus host controller.
661 : *
662 : * @param dev Pointer to the device structure for the SMBus driver instance.
663 : * @param cb Pointer to a callback structure.
664 : *
665 : * @retval 0 If successful.
666 : * @retval -EIO General input / output error.
667 : * @retval -ENOSYS If function smbus_host_notify_set_cb() is not implemented
668 : * by the driver.
669 : */
670 1 : static inline int smbus_host_notify_set_cb(const struct device *dev,
671 : struct smbus_callback *cb)
672 : {
673 : const struct smbus_driver_api *api =
674 : (const struct smbus_driver_api *)dev->api;
675 :
676 : if (api->smbus_host_notify_set_cb == NULL) {
677 : return -ENOSYS;
678 : }
679 :
680 : return api->smbus_host_notify_set_cb(dev, cb);
681 : }
682 :
683 : /**
684 : * @brief Remove Host Notify callback from a SMBus host controller.
685 : *
686 : * @param dev Pointer to the device structure for the SMBus driver instance.
687 : * @param cb Pointer to a callback structure.
688 : *
689 : * @retval 0 If successful.
690 : * @retval -EIO General input / output error.
691 : * @retval -ENOSYS If function smbus_host_notify_remove_cb() is not implemented
692 : * by the driver.
693 : */
694 1 : __syscall int smbus_host_notify_remove_cb(const struct device *dev,
695 : struct smbus_callback *cb);
696 :
697 : static inline int z_impl_smbus_host_notify_remove_cb(const struct device *dev,
698 : struct smbus_callback *cb)
699 : {
700 : const struct smbus_driver_api *api =
701 : (const struct smbus_driver_api *)dev->api;
702 :
703 : if (api->smbus_host_notify_remove_cb == NULL) {
704 : return -ENOSYS;
705 : }
706 :
707 : return api->smbus_host_notify_remove_cb(dev, cb);
708 : }
709 :
710 : /**
711 : * @brief Perform SMBus Quick operation
712 : *
713 : * This routine provides a generic interface to perform SMBus Quick
714 : * operation.
715 : *
716 : * @param dev Pointer to the device structure for the SMBus driver instance.
717 : * driver configured in controller mode.
718 : * @param addr Address of the SMBus peripheral device.
719 : * @param direction Direction Read or Write.
720 : *
721 : * @retval 0 If successful.
722 : * @retval -EIO General input / output error.
723 : * @retval -ENOSYS If function smbus_quick() is not implemented
724 : * by the driver.
725 : */
726 1 : __syscall int smbus_quick(const struct device *dev, uint16_t addr,
727 : enum smbus_direction direction);
728 :
729 : static inline int z_impl_smbus_quick(const struct device *dev, uint16_t addr,
730 : enum smbus_direction direction)
731 : {
732 : const struct smbus_driver_api *api =
733 : (const struct smbus_driver_api *)dev->api;
734 :
735 : if (api->smbus_quick == NULL) {
736 : return -ENOSYS;
737 : }
738 :
739 : if (direction != SMBUS_MSG_READ && direction != SMBUS_MSG_WRITE) {
740 : return -EINVAL;
741 : }
742 :
743 : return api->smbus_quick(dev, addr, direction);
744 : }
745 :
746 : /**
747 : * @brief Perform SMBus Byte Write operation
748 : *
749 : * This routine provides a generic interface to perform SMBus
750 : * Byte Write operation.
751 : *
752 : * @param dev Pointer to the device structure for the SMBus driver instance.
753 : * @param addr Address of the SMBus peripheral device.
754 : * @param byte Byte to be sent to the peripheral device.
755 : *
756 : * @retval 0 If successful.
757 : * @retval -EIO General input / output error.
758 : * @retval -ENOSYS If function smbus_byte_write() is not implemented
759 : * by the driver.
760 : */
761 1 : __syscall int smbus_byte_write(const struct device *dev, uint16_t addr,
762 : uint8_t byte);
763 :
764 : static inline int z_impl_smbus_byte_write(const struct device *dev,
765 : uint16_t addr, uint8_t byte)
766 : {
767 : const struct smbus_driver_api *api =
768 : (const struct smbus_driver_api *)dev->api;
769 :
770 : if (api->smbus_byte_write == NULL) {
771 : return -ENOSYS;
772 : }
773 :
774 : return api->smbus_byte_write(dev, addr, byte);
775 : }
776 :
777 : /**
778 : * @brief Perform SMBus Byte Read operation
779 : *
780 : * This routine provides a generic interface to perform SMBus
781 : * Byte Read operation.
782 : *
783 : * @param dev Pointer to the device structure for the SMBus driver instance.
784 : * @param addr Address of the SMBus peripheral device.
785 : * @param byte Byte received from the peripheral device.
786 : *
787 : * @retval 0 If successful.
788 : * @retval -EIO General input / output error.
789 : * @retval -ENOSYS If function smbus_byte_read() is not implemented
790 : * by the driver.
791 : */
792 1 : __syscall int smbus_byte_read(const struct device *dev, uint16_t addr,
793 : uint8_t *byte);
794 :
795 : static inline int z_impl_smbus_byte_read(const struct device *dev,
796 : uint16_t addr, uint8_t *byte)
797 : {
798 : const struct smbus_driver_api *api =
799 : (const struct smbus_driver_api *)dev->api;
800 :
801 : if (api->smbus_byte_read == NULL) {
802 : return -ENOSYS;
803 : }
804 :
805 : return api->smbus_byte_read(dev, addr, byte);
806 : }
807 :
808 : /**
809 : * @brief Perform SMBus Byte Data Write operation
810 : *
811 : * This routine provides a generic interface to perform SMBus
812 : * Byte Data Write operation.
813 : *
814 : * @param dev Pointer to the device structure for the SMBus driver instance.
815 : * @param addr Address of the SMBus peripheral device.
816 : * @param cmd Command byte which is sent to peripheral device first.
817 : * @param byte Byte to be sent to the peripheral device.
818 : *
819 : * @retval 0 If successful.
820 : * @retval -EIO General input / output error.
821 : * @retval -ENOSYS If function smbus_byte_data_write() is not implemented
822 : * by the driver.
823 : */
824 1 : __syscall int smbus_byte_data_write(const struct device *dev, uint16_t addr,
825 : uint8_t cmd, uint8_t byte);
826 :
827 : static inline int z_impl_smbus_byte_data_write(const struct device *dev,
828 : uint16_t addr, uint8_t cmd,
829 : uint8_t byte)
830 : {
831 : const struct smbus_driver_api *api =
832 : (const struct smbus_driver_api *)dev->api;
833 :
834 : if (api->smbus_byte_data_write == NULL) {
835 : return -ENOSYS;
836 : }
837 :
838 : return api->smbus_byte_data_write(dev, addr, cmd, byte);
839 : }
840 :
841 : /**
842 : * @brief Perform SMBus Byte Data Read operation
843 : *
844 : * This routine provides a generic interface to perform SMBus
845 : * Byte Data Read operation.
846 : *
847 : * @param dev Pointer to the device structure for the SMBus driver instance.
848 : * @param addr Address of the SMBus peripheral device.
849 : * @param cmd Command byte which is sent to peripheral device first.
850 : * @param byte Byte received from the peripheral device.
851 : *
852 : * @retval 0 If successful.
853 : * @retval -EIO General input / output error.
854 : * @retval -ENOSYS If function smbus_byte_data_read() is not implemented
855 : * by the driver.
856 : */
857 1 : __syscall int smbus_byte_data_read(const struct device *dev, uint16_t addr,
858 : uint8_t cmd, uint8_t *byte);
859 :
860 : static inline int z_impl_smbus_byte_data_read(const struct device *dev,
861 : uint16_t addr, uint8_t cmd,
862 : uint8_t *byte)
863 : {
864 : const struct smbus_driver_api *api =
865 : (const struct smbus_driver_api *)dev->api;
866 :
867 : if (api->smbus_byte_data_read == NULL) {
868 : return -ENOSYS;
869 : }
870 :
871 : return api->smbus_byte_data_read(dev, addr, cmd, byte);
872 : }
873 :
874 : /**
875 : * @brief Perform SMBus Word Data Write operation
876 : *
877 : * This routine provides a generic interface to perform SMBus
878 : * Word Data Write operation.
879 : *
880 : * @param dev Pointer to the device structure for the SMBus driver instance.
881 : * @param addr Address of the SMBus peripheral device.
882 : * @param cmd Command byte which is sent to peripheral device first.
883 : * @param word Word (16-bit) to be sent to the peripheral device.
884 : *
885 : * @retval 0 If successful.
886 : * @retval -EIO General input / output error.
887 : * @retval -ENOSYS If function smbus_word_data_write() is not implemented
888 : * by the driver.
889 : */
890 1 : __syscall int smbus_word_data_write(const struct device *dev, uint16_t addr,
891 : uint8_t cmd, uint16_t word);
892 :
893 : static inline int z_impl_smbus_word_data_write(const struct device *dev,
894 : uint16_t addr, uint8_t cmd,
895 : uint16_t word)
896 : {
897 : const struct smbus_driver_api *api =
898 : (const struct smbus_driver_api *)dev->api;
899 :
900 : if (api->smbus_word_data_write == NULL) {
901 : return -ENOSYS;
902 : }
903 :
904 : return api->smbus_word_data_write(dev, addr, cmd, word);
905 : }
906 :
907 : /**
908 : * @brief Perform SMBus Word Data Read operation
909 : *
910 : * This routine provides a generic interface to perform SMBus
911 : * Word Data Read operation.
912 : *
913 : * @param dev Pointer to the device structure for the SMBus driver instance.
914 : * @param addr Address of the SMBus peripheral device.
915 : * @param cmd Command byte which is sent to peripheral device first.
916 : * @param word Word (16-bit) received from the peripheral device.
917 : *
918 : * @retval 0 If successful.
919 : * @retval -EIO General input / output error.
920 : * @retval -ENOSYS If function smbus_word_data_read() is not implemented
921 : * by the driver.
922 : */
923 1 : __syscall int smbus_word_data_read(const struct device *dev, uint16_t addr,
924 : uint8_t cmd, uint16_t *word);
925 :
926 : static inline int z_impl_smbus_word_data_read(const struct device *dev,
927 : uint16_t addr, uint8_t cmd,
928 : uint16_t *word)
929 : {
930 : const struct smbus_driver_api *api =
931 : (const struct smbus_driver_api *)dev->api;
932 :
933 : if (api->smbus_word_data_read == NULL) {
934 : return -ENOSYS;
935 : }
936 :
937 : return api->smbus_word_data_read(dev, addr, cmd, word);
938 : }
939 :
940 : /**
941 : * @brief Perform SMBus Process Call operation
942 : *
943 : * This routine provides a generic interface to perform SMBus
944 : * Process Call operation, which means Write 2 bytes following by
945 : * Read 2 bytes.
946 : *
947 : * @param dev Pointer to the device structure for the SMBus driver instance.
948 : * @param addr Address of the SMBus peripheral device.
949 : * @param cmd Command byte which is sent to peripheral device first.
950 : * @param send_word Word (16-bit) to be sent to the peripheral device.
951 : * @param recv_word Word (16-bit) received from the peripheral device.
952 : *
953 : * @retval 0 If successful.
954 : * @retval -EIO General input / output error.
955 : * @retval -ENOSYS If function smbus_pcall() is not implemented
956 : * by the driver.
957 : */
958 1 : __syscall int smbus_pcall(const struct device *dev, uint16_t addr,
959 : uint8_t cmd, uint16_t send_word, uint16_t *recv_word);
960 :
961 : static inline int z_impl_smbus_pcall(const struct device *dev,
962 : uint16_t addr, uint8_t cmd,
963 : uint16_t send_word, uint16_t *recv_word)
964 : {
965 : const struct smbus_driver_api *api =
966 : (const struct smbus_driver_api *)dev->api;
967 :
968 : if (api->smbus_pcall == NULL) {
969 : return -ENOSYS;
970 : }
971 :
972 : return api->smbus_pcall(dev, addr, cmd, send_word, recv_word);
973 : }
974 :
975 : /**
976 : * @brief Perform SMBus Block Write operation
977 : *
978 : * This routine provides a generic interface to perform SMBus
979 : * Block Write operation.
980 : *
981 : * @param dev Pointer to the device structure for the SMBus driver instance.
982 : * @param addr Address of the SMBus peripheral device.
983 : * @param cmd Command byte which is sent to peripheral device first.
984 : * @param count Size of the data block buffer. Maximum 32 bytes.
985 : * @param buf Data block buffer to be sent to the peripheral device.
986 : *
987 : * @retval 0 If successful.
988 : * @retval -EIO General input / output error.
989 : * @retval -ENOSYS If function smbus_block_write() is not implemented
990 : * by the driver.
991 : */
992 1 : __syscall int smbus_block_write(const struct device *dev, uint16_t addr,
993 : uint8_t cmd, uint8_t count, uint8_t *buf);
994 :
995 : static inline int z_impl_smbus_block_write(const struct device *dev,
996 : uint16_t addr, uint8_t cmd,
997 : uint8_t count, uint8_t *buf)
998 : {
999 : const struct smbus_driver_api *api =
1000 : (const struct smbus_driver_api *)dev->api;
1001 :
1002 : if (api->smbus_block_write == NULL) {
1003 : return -ENOSYS;
1004 : }
1005 :
1006 : if (count < 1 || count > SMBUS_BLOCK_BYTES_MAX) {
1007 : return -EINVAL;
1008 : }
1009 :
1010 : return api->smbus_block_write(dev, addr, cmd, count, buf);
1011 : }
1012 :
1013 : /**
1014 : * @brief Perform SMBus Block Read operation
1015 : *
1016 : * This routine provides a generic interface to perform SMBus
1017 : * Block Read operation.
1018 : *
1019 : * @param dev Pointer to the device structure for the SMBus driver instance.
1020 : * @param addr Address of the SMBus peripheral device.
1021 : * @param cmd Command byte which is sent to peripheral device first.
1022 : * @param count Size of the data peripheral sent. Maximum 32 bytes.
1023 : * @param buf Data block buffer received from the peripheral device.
1024 : *
1025 : * @retval 0 If successful.
1026 : * @retval -EIO General input / output error.
1027 : * @retval -ENOSYS If function smbus_block_read() is not implemented
1028 : * by the driver.
1029 : */
1030 1 : __syscall int smbus_block_read(const struct device *dev, uint16_t addr,
1031 : uint8_t cmd, uint8_t *count, uint8_t *buf);
1032 :
1033 : static inline int z_impl_smbus_block_read(const struct device *dev,
1034 : uint16_t addr, uint8_t cmd,
1035 : uint8_t *count, uint8_t *buf)
1036 : {
1037 : const struct smbus_driver_api *api =
1038 : (const struct smbus_driver_api *)dev->api;
1039 :
1040 : if (api->smbus_block_read == NULL) {
1041 : return -ENOSYS;
1042 : }
1043 :
1044 : return api->smbus_block_read(dev, addr, cmd, count, buf);
1045 : }
1046 :
1047 : /**
1048 : * @brief Perform SMBus Block Process Call operation
1049 : *
1050 : * This routine provides a generic interface to perform SMBus
1051 : * Block Process Call operation. This operation is basically
1052 : * Block Write followed by Block Read.
1053 : *
1054 : * @param dev Pointer to the device structure for the SMBus driver instance.
1055 : * @param addr Address of the SMBus peripheral device.
1056 : * @param cmd Command byte which is sent to peripheral device first.
1057 : * @param snd_count Size of the data block buffer to send.
1058 : * @param snd_buf Data block buffer send to the peripheral device.
1059 : * @param rcv_count Size of the data peripheral sent.
1060 : * @param rcv_buf Data block buffer received from the peripheral device.
1061 : *
1062 : * @retval 0 If successful.
1063 : * @retval -EIO General input / output error.
1064 : * @retval -ENOSYS If function smbus_block_pcall() is not implemented
1065 : * by the driver.
1066 : */
1067 1 : __syscall int smbus_block_pcall(const struct device *dev,
1068 : uint16_t addr, uint8_t cmd,
1069 : uint8_t snd_count, uint8_t *snd_buf,
1070 : uint8_t *rcv_count, uint8_t *rcv_buf);
1071 :
1072 : static inline int z_impl_smbus_block_pcall(const struct device *dev,
1073 : uint16_t addr, uint8_t cmd,
1074 : uint8_t snd_count, uint8_t *snd_buf,
1075 : uint8_t *rcv_count, uint8_t *rcv_buf)
1076 : {
1077 : const struct smbus_driver_api *api =
1078 : (const struct smbus_driver_api *)dev->api;
1079 :
1080 : if (api->smbus_block_pcall == NULL) {
1081 : return -ENOSYS;
1082 : }
1083 :
1084 : return api->smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf,
1085 : rcv_count, rcv_buf);
1086 : }
1087 :
1088 : #ifdef __cplusplus
1089 : }
1090 : #endif
1091 :
1092 : /**
1093 : * @}
1094 : */
1095 :
1096 : #include <zephyr/syscalls/smbus.h>
1097 :
1098 : #endif /* ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ */
|