Zephyr API Documentation  3.5.0
A Scalable Open Source RTOS
3.5.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
7#ifndef ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
8#define ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
9
17#include <zephyr/types.h>
18#include <zephyr/device.h>
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
46#define SMBUS_CMD_QUICK 0b000
47
69#define SMBUS_CMD_BYTE 0b001
70
95#define SMBUS_CMD_BYTE_DATA 0b010
96
123#define SMBUS_CMD_WORD_DATA 0b011
124
142#define SMBUS_CMD_PROC_CALL 0b100
143
173#define SMBUS_CMD_BLOCK 0b101
174
193#define SMBUS_CMD_BLOCK_PROC 0b111
197#define SMBUS_BLOCK_BYTES_MAX 32
198
207#define SMBUS_MODE_CONTROLLER BIT(0)
208
210#define SMBUS_MODE_PEC BIT(1)
211
213#define SMBUS_MODE_HOST_NOTIFY BIT(2)
214
216#define SMBUS_MODE_SMBALERT BIT(3)
217
233#define SMBUS_ADDRESS_ARA 0x0c
234
248};
249
253#define SMBUS_MSG_RW_MASK BIT(0)
256struct smbus_callback;
257
265typedef void (*smbus_callback_handler_t)(const struct device *dev,
266 struct smbus_callback *cb,
267 uint8_t addr);
268
281
284
287};
288
294 const struct device *bus;
297};
298
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
323#define SMBUS_DT_SPEC_INST_GET(inst) SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
324
332typedef int (*smbus_api_configure_t)(const struct device *dev,
333 uint32_t dev_config);
334typedef int (*smbus_api_get_config_t)(const struct device *dev,
335 uint32_t *dev_config);
336typedef int (*smbus_api_quick_t)(const struct device *dev,
337 uint16_t addr, enum smbus_direction);
338typedef int (*smbus_api_byte_write_t)(const struct device *dev,
339 uint16_t addr, uint8_t byte);
340typedef int (*smbus_api_byte_read_t)(const struct device *dev,
341 uint16_t addr, uint8_t *byte);
342typedef int (*smbus_api_byte_data_write_t)(const struct device *dev,
343 uint16_t addr, uint8_t cmd,
344 uint8_t byte);
345typedef int (*smbus_api_byte_data_read_t)(const struct device *dev,
346 uint16_t addr, uint8_t cmd,
347 uint8_t *byte);
348typedef int (*smbus_api_word_data_write_t)(const struct device *dev,
349 uint16_t addr, uint8_t cmd,
350 uint16_t word);
351typedef int (*smbus_api_word_data_read_t)(const struct device *dev,
352 uint16_t addr, uint8_t cmd,
353 uint16_t *word);
354typedef 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);
357typedef int (*smbus_api_block_write_t)(const struct device *dev,
358 uint16_t addr, uint8_t cmd,
359 uint8_t count, uint8_t *buf);
360typedef int (*smbus_api_block_read_t)(const struct device *dev,
361 uint16_t addr, uint8_t cmd,
362 uint8_t *count, uint8_t *buf);
363typedef 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);
367typedef int (*smbus_api_smbalert_cb_t)(const struct device *dev,
368 struct smbus_callback *cb);
369typedef 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
396#if defined(CONFIG_SMBUS_STATS) || defined(__DOXYGEN__)
397
398#include <zephyr/stats/stats.h>
399
402STATS_SECT_START(smbus)
403STATS_SECT_ENTRY32(bytes_read)
404STATS_SECT_ENTRY32(bytes_written)
405STATS_SECT_ENTRY32(command_count)
407
408STATS_NAME_START(smbus)
409STATS_NAME(smbus, bytes_read)
410STATS_NAME(smbus, bytes_written)
411STATS_NAME(smbus, command_count)
412STATS_NAME_END(smbus);
413
414struct smbus_device_state {
415 struct device_state devstate;
416 struct stats_smbus stats;
417};
418
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
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
456static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
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
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
513static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
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
539#define SMBUS_DEVICE_DT_INST_DEFINE(inst, ...) \
540 SMBUS_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
541
552__syscall int smbus_configure(const struct device *dev, uint32_t dev_config);
553
554static 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
583__syscall int smbus_get_config(const struct device *dev, uint32_t *dev_config);
584
585static 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
609__syscall int smbus_smbalert_set_cb(const struct device *dev,
610 struct smbus_callback *cb);
611
612static 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
636__syscall int smbus_smbalert_remove_cb(const struct device *dev,
637 struct smbus_callback *cb);
638
639static 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
663__syscall int smbus_host_notify_set_cb(const struct device *dev,
664 struct smbus_callback *cb);
665
666static 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
690__syscall int smbus_host_notify_remove_cb(const struct device *dev,
691 struct smbus_callback *cb);
692
693static 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
722__syscall int smbus_quick(const struct device *dev, uint16_t addr,
723 enum smbus_direction direction);
724
725static 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
757__syscall int smbus_byte_write(const struct device *dev, uint16_t addr,
758 uint8_t byte);
759
760static 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
788__syscall int smbus_byte_read(const struct device *dev, uint16_t addr,
789 uint8_t *byte);
790
791static 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
820__syscall int smbus_byte_data_write(const struct device *dev, uint16_t addr,
821 uint8_t cmd, uint8_t byte);
822
823static 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
853__syscall int smbus_byte_data_read(const struct device *dev, uint16_t addr,
854 uint8_t cmd, uint8_t *byte);
855
856static 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
886__syscall int smbus_word_data_write(const struct device *dev, uint16_t addr,
887 uint8_t cmd, uint16_t word);
888
889static 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
919__syscall int smbus_word_data_read(const struct device *dev, uint16_t addr,
920 uint8_t cmd, uint16_t *word);
921
922static 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
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
957static 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
988__syscall int smbus_block_write(const struct device *dev, uint16_t addr,
989 uint8_t cmd, uint8_t count, uint8_t *buf);
990
991static 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
1026__syscall int smbus_block_read(const struct device *dev, uint16_t addr,
1027 uint8_t cmd, uint8_t *count, uint8_t *buf);
1028
1029static 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
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
1068static 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
1092#include <syscalls/smbus.h>
1093
1094#endif /* ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ */
static ssize_t recv(int sock, void *buf, size_t max_len, int flags)
POSIX wrapper for zsock_recv.
Definition: socket.h:809
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:456
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_host_notify_set_cb(const struct device *dev, struct smbus_callback *cb)
Add Host Notify callback for a SMBus host controller.
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.
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.
int smbus_smbalert_set_cb(const struct device *dev, struct smbus_callback *cb)
Add SMBUSALERT callback for a SMBus host controller.
#define SMBUS_BLOCK_BYTES_MAX
Maximum number of bytes in SMBus Block protocol.
Definition: smbus.h:197
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:265
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:243
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.
@ SMBUS_MSG_WRITE
Write a message to SMBus peripheral.
Definition: smbus.h:245
@ SMBUS_MSG_READ
Read a message from SMBus peripheral.
Definition: smbus.h:247
#define CONTAINER_OF(ptr, type, field)
Get a pointer to a structure containing the element.
Definition: util.h:247
#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:354
Runtime device structure (in ROM) per driver instance.
Definition: device.h:381
const void * api
Address of the API structure exposed by the device instance.
Definition: device.h:387
struct device_state * state
Address of the common device state.
Definition: device.h:389
SMBus callback structure.
Definition: smbus.h:278
smbus_callback_handler_t handler
Actual callback function being called when relevant.
Definition: smbus.h:283
uint8_t addr
Peripheral device address.
Definition: smbus.h:286
sys_snode_t node
This should be used in driver for a callback list management.
Definition: smbus.h:280
Complete SMBus DT information.
Definition: smbus.h:292
uint16_t addr
Address of the SMBus peripheral device.
Definition: smbus.h:296
const struct device * bus
SMBus bus.
Definition: smbus.h:294