Zephyr API Documentation  3.6.0
A Scalable Open Source RTOS
3.6.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
smbus.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12#ifndef ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
13#define ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
14
22#include <errno.h>
23#include <zephyr/sys/slist.h>
24#include <zephyr/types.h>
25#include <zephyr/device.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
53#define SMBUS_CMD_QUICK 0b000
54
76#define SMBUS_CMD_BYTE 0b001
77
102#define SMBUS_CMD_BYTE_DATA 0b010
103
130#define SMBUS_CMD_WORD_DATA 0b011
131
149#define SMBUS_CMD_PROC_CALL 0b100
150
180#define SMBUS_CMD_BLOCK 0b101
181
200#define SMBUS_CMD_BLOCK_PROC 0b111
204#define SMBUS_BLOCK_BYTES_MAX 32
205
214#define SMBUS_MODE_CONTROLLER BIT(0)
215
217#define SMBUS_MODE_PEC BIT(1)
218
220#define SMBUS_MODE_HOST_NOTIFY BIT(2)
221
223#define SMBUS_MODE_SMBALERT BIT(3)
224
240#define SMBUS_ADDRESS_ARA 0x0c
241
255};
256
260#define SMBUS_MSG_RW_MASK BIT(0)
263struct smbus_callback;
264
272typedef void (*smbus_callback_handler_t)(const struct device *dev,
273 struct smbus_callback *cb,
274 uint8_t addr);
275
288
291
294};
295
301 const struct device *bus;
304};
305
316#define SMBUS_DT_SPEC_GET(node_id) \
317 { \
318 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
319 .addr = DT_REG_ADDR(node_id) \
320 }
321
330#define SMBUS_DT_SPEC_INST_GET(inst) SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
331
339typedef int (*smbus_api_configure_t)(const struct device *dev,
340 uint32_t dev_config);
341typedef int (*smbus_api_get_config_t)(const struct device *dev,
342 uint32_t *dev_config);
343typedef int (*smbus_api_quick_t)(const struct device *dev,
344 uint16_t addr, enum smbus_direction);
345typedef int (*smbus_api_byte_write_t)(const struct device *dev,
346 uint16_t addr, uint8_t byte);
347typedef int (*smbus_api_byte_read_t)(const struct device *dev,
348 uint16_t addr, uint8_t *byte);
349typedef int (*smbus_api_byte_data_write_t)(const struct device *dev,
350 uint16_t addr, uint8_t cmd,
351 uint8_t byte);
352typedef int (*smbus_api_byte_data_read_t)(const struct device *dev,
353 uint16_t addr, uint8_t cmd,
354 uint8_t *byte);
355typedef int (*smbus_api_word_data_write_t)(const struct device *dev,
356 uint16_t addr, uint8_t cmd,
357 uint16_t word);
358typedef int (*smbus_api_word_data_read_t)(const struct device *dev,
359 uint16_t addr, uint8_t cmd,
360 uint16_t *word);
361typedef int (*smbus_api_pcall_t)(const struct device *dev,
362 uint16_t addr, uint8_t cmd,
363 uint16_t send_word, uint16_t *recv_word);
364typedef int (*smbus_api_block_write_t)(const struct device *dev,
365 uint16_t addr, uint8_t cmd,
366 uint8_t count, uint8_t *buf);
367typedef int (*smbus_api_block_read_t)(const struct device *dev,
368 uint16_t addr, uint8_t cmd,
369 uint8_t *count, uint8_t *buf);
370typedef int (*smbus_api_block_pcall_t)(const struct device *dev,
371 uint16_t addr, uint8_t cmd,
372 uint8_t send_count, uint8_t *send_buf,
373 uint8_t *recv_count, uint8_t *recv_buf);
374typedef int (*smbus_api_smbalert_cb_t)(const struct device *dev,
375 struct smbus_callback *cb);
376typedef int (*smbus_api_host_notify_cb_t)(const struct device *dev,
377 struct smbus_callback *cb);
378
379__subsystem struct smbus_driver_api {
380 smbus_api_configure_t configure;
381 smbus_api_get_config_t get_config;
382 smbus_api_quick_t smbus_quick;
383 smbus_api_byte_write_t smbus_byte_write;
384 smbus_api_byte_read_t smbus_byte_read;
385 smbus_api_byte_data_write_t smbus_byte_data_write;
386 smbus_api_byte_data_read_t smbus_byte_data_read;
387 smbus_api_word_data_write_t smbus_word_data_write;
388 smbus_api_word_data_read_t smbus_word_data_read;
389 smbus_api_pcall_t smbus_pcall;
390 smbus_api_block_write_t smbus_block_write;
391 smbus_api_block_read_t smbus_block_read;
392 smbus_api_block_pcall_t smbus_block_pcall;
393 smbus_api_smbalert_cb_t smbus_smbalert_set_cb;
394 smbus_api_smbalert_cb_t smbus_smbalert_remove_cb;
395 smbus_api_host_notify_cb_t smbus_host_notify_set_cb;
396 smbus_api_host_notify_cb_t smbus_host_notify_remove_cb;
397};
398
403#if defined(CONFIG_SMBUS_STATS) || defined(__DOXYGEN__)
404
405#include <zephyr/stats/stats.h>
406
409STATS_SECT_START(smbus)
410STATS_SECT_ENTRY32(bytes_read)
411STATS_SECT_ENTRY32(bytes_written)
412STATS_SECT_ENTRY32(command_count)
414
415STATS_NAME_START(smbus)
416STATS_NAME(smbus, bytes_read)
417STATS_NAME(smbus, bytes_written)
418STATS_NAME(smbus, command_count)
419STATS_NAME_END(smbus);
420
421struct smbus_device_state {
422 struct device_state devstate;
423 struct stats_smbus stats;
424};
425
429#define Z_SMBUS_DEVICE_STATE_DEFINE(node_id, dev_name) \
430 static struct smbus_device_state Z_DEVICE_STATE_NAME(dev_name) \
431 __attribute__((__section__(".z_devstate")));
432
439#define Z_SMBUS_INIT_FN(dev_name, init_fn) \
440 static inline int \
441 UTIL_CAT(dev_name, _init)(const struct device *dev) \
442 { \
443 struct smbus_device_state *state = \
444 CONTAINER_OF(dev->state, \
445 struct smbus_device_state, \
446 devstate); \
447 stats_init(&state->stats.s_hdr, STATS_SIZE_32, 4, \
448 STATS_NAME_INIT_PARMS(smbus)); \
449 stats_register(dev->name, &(state->stats.s_hdr)); \
450 return init_fn(dev); \
451 }
452
463static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
465{
466 struct smbus_device_state *state =
467 CONTAINER_OF(dev->state, struct smbus_device_state, devstate);
468
469 STATS_INC(state->stats, command_count);
470 STATS_INCN(state->stats, bytes_read, recv);
471 STATS_INCN(state->stats, bytes_written, sent);
472}
473
502#define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
503 data_ptr, cfg_ptr, level, prio, \
504 api_ptr, ...) \
505 Z_SMBUS_DEVICE_STATE_DEFINE(node_id, \
506 Z_DEVICE_DT_DEV_NAME(node_id)); \
507 Z_SMBUS_INIT_FN(Z_DEVICE_DT_DEV_NAME(node_id), init_fn) \
508 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
509 DEVICE_DT_NAME(node_id), \
510 &UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init),\
511 pm_device, \
512 data_ptr, cfg_ptr, level, prio, \
513 api_ptr, \
514 &(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME \
515 (node_id)).devstate), \
516 __VA_ARGS__)
517
518#else /* CONFIG_SMBUS_STATS */
519
520static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
522{
523 ARG_UNUSED(dev);
524 ARG_UNUSED(sent);
525 ARG_UNUSED(recv);
526}
527
528#define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
529 data_ptr, cfg_ptr, level, prio, \
530 api_ptr, ...) \
531 DEVICE_DT_DEFINE(node_id, &init_fn, pm_device, \
532 data_ptr, cfg_ptr, level, prio, \
533 api_ptr, __VA_ARGS__)
534
535#endif /* CONFIG_SMBUS_STATS */
536
546#define SMBUS_DEVICE_DT_INST_DEFINE(inst, ...) \
547 SMBUS_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
548
559__syscall int smbus_configure(const struct device *dev, uint32_t dev_config);
560
561static inline int z_impl_smbus_configure(const struct device *dev,
562 uint32_t dev_config)
563{
564 const struct smbus_driver_api *api =
565 (const struct smbus_driver_api *)dev->api;
566
567 return api->configure(dev, dev_config);
568}
569
590__syscall int smbus_get_config(const struct device *dev, uint32_t *dev_config);
591
592static inline int z_impl_smbus_get_config(const struct device *dev,
593 uint32_t *dev_config)
594{
595 const struct smbus_driver_api *api =
596 (const struct smbus_driver_api *)dev->api;
597
598 if (api->get_config == NULL) {
599 return -ENOSYS;
600 }
601
602 return api->get_config(dev, dev_config);
603}
604
616static inline int smbus_smbalert_set_cb(const struct device *dev,
617 struct smbus_callback *cb)
618{
619 const struct smbus_driver_api *api =
620 (const struct smbus_driver_api *)dev->api;
621
622 if (api->smbus_smbalert_set_cb == NULL) {
623 return -ENOSYS;
624 }
625
626 return api->smbus_smbalert_set_cb(dev, cb);
627}
628
640__syscall int smbus_smbalert_remove_cb(const struct device *dev,
641 struct smbus_callback *cb);
642
643static inline int z_impl_smbus_smbalert_remove_cb(const struct device *dev,
644 struct smbus_callback *cb)
645{
646 const struct smbus_driver_api *api =
647 (const struct smbus_driver_api *)dev->api;
648
649 if (api->smbus_smbalert_remove_cb == NULL) {
650 return -ENOSYS;
651 }
652
653 return api->smbus_smbalert_remove_cb(dev, cb);
654}
655
667static inline int smbus_host_notify_set_cb(const struct device *dev,
668 struct smbus_callback *cb)
669{
670 const struct smbus_driver_api *api =
671 (const struct smbus_driver_api *)dev->api;
672
673 if (api->smbus_host_notify_set_cb == NULL) {
674 return -ENOSYS;
675 }
676
677 return api->smbus_host_notify_set_cb(dev, cb);
678}
679
691__syscall int smbus_host_notify_remove_cb(const struct device *dev,
692 struct smbus_callback *cb);
693
694static inline int z_impl_smbus_host_notify_remove_cb(const struct device *dev,
695 struct smbus_callback *cb)
696{
697 const struct smbus_driver_api *api =
698 (const struct smbus_driver_api *)dev->api;
699
700 if (api->smbus_host_notify_remove_cb == NULL) {
701 return -ENOSYS;
702 }
703
704 return api->smbus_host_notify_remove_cb(dev, cb);
705}
706
723__syscall int smbus_quick(const struct device *dev, uint16_t addr,
724 enum smbus_direction direction);
725
726static inline int z_impl_smbus_quick(const struct device *dev, uint16_t addr,
727 enum smbus_direction direction)
728{
729 const struct smbus_driver_api *api =
730 (const struct smbus_driver_api *)dev->api;
731
732 if (api->smbus_quick == NULL) {
733 return -ENOSYS;
734 }
735
736 if (direction != SMBUS_MSG_READ && direction != SMBUS_MSG_WRITE) {
737 return -EINVAL;
738 }
739
740 return api->smbus_quick(dev, addr, direction);
741}
742
758__syscall int smbus_byte_write(const struct device *dev, uint16_t addr,
759 uint8_t byte);
760
761static inline int z_impl_smbus_byte_write(const struct device *dev,
762 uint16_t addr, uint8_t byte)
763{
764 const struct smbus_driver_api *api =
765 (const struct smbus_driver_api *)dev->api;
766
767 if (api->smbus_byte_write == NULL) {
768 return -ENOSYS;
769 }
770
771 return api->smbus_byte_write(dev, addr, byte);
772}
773
789__syscall int smbus_byte_read(const struct device *dev, uint16_t addr,
790 uint8_t *byte);
791
792static inline int z_impl_smbus_byte_read(const struct device *dev,
793 uint16_t addr, uint8_t *byte)
794{
795 const struct smbus_driver_api *api =
796 (const struct smbus_driver_api *)dev->api;
797
798 if (api->smbus_byte_read == NULL) {
799 return -ENOSYS;
800 }
801
802 return api->smbus_byte_read(dev, addr, byte);
803}
804
821__syscall int smbus_byte_data_write(const struct device *dev, uint16_t addr,
822 uint8_t cmd, uint8_t byte);
823
824static inline int z_impl_smbus_byte_data_write(const struct device *dev,
825 uint16_t addr, uint8_t cmd,
826 uint8_t byte)
827{
828 const struct smbus_driver_api *api =
829 (const struct smbus_driver_api *)dev->api;
830
831 if (api->smbus_byte_data_write == NULL) {
832 return -ENOSYS;
833 }
834
835 return api->smbus_byte_data_write(dev, addr, cmd, byte);
836}
837
854__syscall int smbus_byte_data_read(const struct device *dev, uint16_t addr,
855 uint8_t cmd, uint8_t *byte);
856
857static inline int z_impl_smbus_byte_data_read(const struct device *dev,
858 uint16_t addr, uint8_t cmd,
859 uint8_t *byte)
860{
861 const struct smbus_driver_api *api =
862 (const struct smbus_driver_api *)dev->api;
863
864 if (api->smbus_byte_data_read == NULL) {
865 return -ENOSYS;
866 }
867
868 return api->smbus_byte_data_read(dev, addr, cmd, byte);
869}
870
887__syscall int smbus_word_data_write(const struct device *dev, uint16_t addr,
888 uint8_t cmd, uint16_t word);
889
890static inline int z_impl_smbus_word_data_write(const struct device *dev,
891 uint16_t addr, uint8_t cmd,
892 uint16_t word)
893{
894 const struct smbus_driver_api *api =
895 (const struct smbus_driver_api *)dev->api;
896
897 if (api->smbus_word_data_write == NULL) {
898 return -ENOSYS;
899 }
900
901 return api->smbus_word_data_write(dev, addr, cmd, word);
902}
903
920__syscall int smbus_word_data_read(const struct device *dev, uint16_t addr,
921 uint8_t cmd, uint16_t *word);
922
923static inline int z_impl_smbus_word_data_read(const struct device *dev,
924 uint16_t addr, uint8_t cmd,
925 uint16_t *word)
926{
927 const struct smbus_driver_api *api =
928 (const struct smbus_driver_api *)dev->api;
929
930 if (api->smbus_word_data_read == NULL) {
931 return -ENOSYS;
932 }
933
934 return api->smbus_word_data_read(dev, addr, cmd, word);
935}
936
955__syscall int smbus_pcall(const struct device *dev, uint16_t addr,
956 uint8_t cmd, uint16_t send_word, uint16_t *recv_word);
957
958static inline int z_impl_smbus_pcall(const struct device *dev,
959 uint16_t addr, uint8_t cmd,
960 uint16_t send_word, uint16_t *recv_word)
961{
962 const struct smbus_driver_api *api =
963 (const struct smbus_driver_api *)dev->api;
964
965 if (api->smbus_pcall == NULL) {
966 return -ENOSYS;
967 }
968
969 return api->smbus_pcall(dev, addr, cmd, send_word, recv_word);
970}
971
989__syscall int smbus_block_write(const struct device *dev, uint16_t addr,
990 uint8_t cmd, uint8_t count, uint8_t *buf);
991
992static inline int z_impl_smbus_block_write(const struct device *dev,
993 uint16_t addr, uint8_t cmd,
994 uint8_t count, uint8_t *buf)
995{
996 const struct smbus_driver_api *api =
997 (const struct smbus_driver_api *)dev->api;
998
999 if (api->smbus_block_write == NULL) {
1000 return -ENOSYS;
1001 }
1002
1003 if (count < 1 || count > SMBUS_BLOCK_BYTES_MAX) {
1004 return -EINVAL;
1005 }
1006
1007 return api->smbus_block_write(dev, addr, cmd, count, buf);
1008}
1009
1027__syscall int smbus_block_read(const struct device *dev, uint16_t addr,
1028 uint8_t cmd, uint8_t *count, uint8_t *buf);
1029
1030static inline int z_impl_smbus_block_read(const struct device *dev,
1031 uint16_t addr, uint8_t cmd,
1032 uint8_t *count, uint8_t *buf)
1033{
1034 const struct smbus_driver_api *api =
1035 (const struct smbus_driver_api *)dev->api;
1036
1037 if (api->smbus_block_read == NULL) {
1038 return -ENOSYS;
1039 }
1040
1041 return api->smbus_block_read(dev, addr, cmd, count, buf);
1042}
1043
1064__syscall int smbus_block_pcall(const struct device *dev,
1065 uint16_t addr, uint8_t cmd,
1066 uint8_t snd_count, uint8_t *snd_buf,
1067 uint8_t *rcv_count, uint8_t *rcv_buf);
1068
1069static inline int z_impl_smbus_block_pcall(const struct device *dev,
1070 uint16_t addr, uint8_t cmd,
1071 uint8_t snd_count, uint8_t *snd_buf,
1072 uint8_t *rcv_count, uint8_t *rcv_buf)
1073{
1074 const struct smbus_driver_api *api =
1075 (const struct smbus_driver_api *)dev->api;
1076
1077 if (api->smbus_block_pcall == NULL) {
1078 return -ENOSYS;
1079 }
1080
1081 return api->smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf,
1082 rcv_count, rcv_buf);
1083}
1084
1085#ifdef __cplusplus
1086}
1087#endif
1088
1093#include <syscalls/smbus.h>
1094
1095#endif /* ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ */
System error numbers.
static ssize_t recv(int sock, void *buf, size_t max_len, int flags)
POSIX wrapper for zsock_recv.
Definition: socket.h:888
static void cmd(uint32_t command)
Execute a display list command by co-processor engine.
Definition: ft8xx_reference_api.h:153
struct _snode sys_snode_t
Single-linked list node structure.
Definition: slist.h:39
static void smbus_xfer_stats(const struct device *dev, uint8_t sent, uint8_t recv)
Updates the SMBus stats.
Definition: smbus.h:463
int smbus_byte_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *byte)
Perform SMBus Byte Data Read operation.
int smbus_pcall(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t send_word, uint16_t *recv_word)
Perform SMBus Process Call operation.
static int smbus_host_notify_set_cb(const struct device *dev, struct smbus_callback *cb)
Add Host Notify callback for a SMBus host controller.
Definition: smbus.h:667
int smbus_configure(const struct device *dev, uint32_t dev_config)
Configure operation of a SMBus host controller.
int smbus_block_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t count, uint8_t *buf)
Perform SMBus Block Write operation.
#define SMBUS_BLOCK_BYTES_MAX
Maximum number of bytes in SMBus Block protocol.
Definition: smbus.h:204
int smbus_block_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *count, uint8_t *buf)
Perform SMBus Block Read operation.
int 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)
Perform SMBus Block Process Call operation.
void(* smbus_callback_handler_t)(const struct device *dev, struct smbus_callback *cb, uint8_t addr)
Define SMBus callback handler function signature.
Definition: smbus.h:272
int smbus_word_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t *word)
Perform SMBus Word Data Read operation.
int smbus_byte_write(const struct device *dev, uint16_t addr, uint8_t byte)
Perform SMBus Byte Write operation.
int smbus_get_config(const struct device *dev, uint32_t *dev_config)
Get configuration of a SMBus host controller.
int smbus_host_notify_remove_cb(const struct device *dev, struct smbus_callback *cb)
Remove Host Notify callback from a SMBus host controller.
int smbus_quick(const struct device *dev, uint16_t addr, enum smbus_direction direction)
Perform SMBus Quick operation.
int smbus_smbalert_remove_cb(const struct device *dev, struct smbus_callback *cb)
Remove SMBUSALERT callback from a SMBus host controller.
smbus_direction
SMBus read / write direction.
Definition: smbus.h:250
int smbus_byte_read(const struct device *dev, uint16_t addr, uint8_t *byte)
Perform SMBus Byte Read operation.
int smbus_byte_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t byte)
Perform SMBus Byte Data Write operation.
int smbus_word_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t word)
Perform SMBus Word Data Write operation.
static int smbus_smbalert_set_cb(const struct device *dev, struct smbus_callback *cb)
Add SMBUSALERT callback for a SMBus host controller.
Definition: smbus.h:616
@ SMBUS_MSG_WRITE
Write a message to SMBus peripheral.
Definition: smbus.h:252
@ SMBUS_MSG_READ
Read a message from SMBus peripheral.
Definition: smbus.h:254
#define CONTAINER_OF(ptr, type, field)
Get a pointer to a structure containing the element.
Definition: util.h:265
#define EINVAL
Invalid argument.
Definition: errno.h:61
#define ENOSYS
Function not implemented.
Definition: errno.h:83
state
Definition: parser_state.h:29
Statistics.
#define STATS_NAME_END(name__)
Definition: stats.h:391
#define STATS_NAME(name__, entry__)
Definition: stats.h:390
#define STATS_SECT_END
Ends a stats group struct definition.
Definition: stats.h:89
#define STATS_SECT_ENTRY32(var__)
Definition: stats.h:359
#define STATS_INC(group__, var__)
Definition: stats.h:364
#define STATS_NAME_START(name__)
Definition: stats.h:389
#define STATS_INCN(group__, var__, n__)
Definition: stats.h:363
#define STATS_SECT_START(group__)
Definition: stats.h:354
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
__UINT8_TYPE__ uint8_t
Definition: stdint.h:88
__UINT16_TYPE__ uint16_t
Definition: stdint.h:89
Runtime device dynamic structure (in RAM) per driver instance.
Definition: device.h:358
Runtime device structure (in ROM) per driver instance.
Definition: device.h:387
const void * api
Address of the API structure exposed by the device instance.
Definition: device.h:393
struct device_state * state
Address of the common device state.
Definition: device.h:395
SMBus callback structure.
Definition: smbus.h:285
smbus_callback_handler_t handler
Actual callback function being called when relevant.
Definition: smbus.h:290
uint8_t addr
Peripheral device address.
Definition: smbus.h:293
sys_snode_t node
This should be used in driver for a callback list management.
Definition: smbus.h:287
Complete SMBus DT information.
Definition: smbus.h:299
uint16_t addr
Address of the SMBus peripheral device.
Definition: smbus.h:303
const struct device * bus
SMBus bus.
Definition: smbus.h:301