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