Zephyr Project API 3.7.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
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
24#include <errno.h>
25#include <zephyr/sys/slist.h>
26#include <zephyr/types.h>
27#include <zephyr/device.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
55#define SMBUS_CMD_QUICK 0b000
56
78#define SMBUS_CMD_BYTE 0b001
79
104#define SMBUS_CMD_BYTE_DATA 0b010
105
132#define SMBUS_CMD_WORD_DATA 0b011
133
151#define SMBUS_CMD_PROC_CALL 0b100
152
182#define SMBUS_CMD_BLOCK 0b101
183
202#define SMBUS_CMD_BLOCK_PROC 0b111
206#define SMBUS_BLOCK_BYTES_MAX 32
207
216#define SMBUS_MODE_CONTROLLER BIT(0)
217
219#define SMBUS_MODE_PEC BIT(1)
220
222#define SMBUS_MODE_HOST_NOTIFY BIT(2)
223
225#define SMBUS_MODE_SMBALERT BIT(3)
226
242#define SMBUS_ADDRESS_ARA 0x0c
243
258
262#define SMBUS_MSG_RW_MASK BIT(0)
265struct smbus_callback;
266
274typedef void (*smbus_callback_handler_t)(const struct device *dev,
275 struct smbus_callback *cb,
276 uint8_t addr);
277
297
303 const struct device *bus;
306};
307
318#define SMBUS_DT_SPEC_GET(node_id) \
319 { \
320 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
321 .addr = DT_REG_ADDR(node_id) \
322 }
323
332#define SMBUS_DT_SPEC_INST_GET(inst) SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
333
341typedef int (*smbus_api_configure_t)(const struct device *dev,
342 uint32_t dev_config);
343typedef int (*smbus_api_get_config_t)(const struct device *dev,
344 uint32_t *dev_config);
345typedef int (*smbus_api_quick_t)(const struct device *dev,
346 uint16_t addr, enum smbus_direction);
347typedef int (*smbus_api_byte_write_t)(const struct device *dev,
348 uint16_t addr, uint8_t byte);
349typedef int (*smbus_api_byte_read_t)(const struct device *dev,
350 uint16_t addr, uint8_t *byte);
351typedef int (*smbus_api_byte_data_write_t)(const struct device *dev,
352 uint16_t addr, uint8_t cmd,
353 uint8_t byte);
354typedef int (*smbus_api_byte_data_read_t)(const struct device *dev,
355 uint16_t addr, uint8_t cmd,
356 uint8_t *byte);
357typedef int (*smbus_api_word_data_write_t)(const struct device *dev,
358 uint16_t addr, uint8_t cmd,
359 uint16_t word);
360typedef int (*smbus_api_word_data_read_t)(const struct device *dev,
361 uint16_t addr, uint8_t cmd,
362 uint16_t *word);
363typedef int (*smbus_api_pcall_t)(const struct device *dev,
364 uint16_t addr, uint8_t cmd,
365 uint16_t send_word, uint16_t *recv_word);
366typedef int (*smbus_api_block_write_t)(const struct device *dev,
367 uint16_t addr, uint8_t cmd,
368 uint8_t count, uint8_t *buf);
369typedef int (*smbus_api_block_read_t)(const struct device *dev,
370 uint16_t addr, uint8_t cmd,
371 uint8_t *count, uint8_t *buf);
372typedef int (*smbus_api_block_pcall_t)(const struct device *dev,
373 uint16_t addr, uint8_t cmd,
374 uint8_t send_count, uint8_t *send_buf,
375 uint8_t *recv_count, uint8_t *recv_buf);
376typedef int (*smbus_api_smbalert_cb_t)(const struct device *dev,
377 struct smbus_callback *cb);
378typedef int (*smbus_api_host_notify_cb_t)(const struct device *dev,
379 struct smbus_callback *cb);
380
381__subsystem struct smbus_driver_api {
382 smbus_api_configure_t configure;
383 smbus_api_get_config_t get_config;
384 smbus_api_quick_t smbus_quick;
385 smbus_api_byte_write_t smbus_byte_write;
386 smbus_api_byte_read_t smbus_byte_read;
387 smbus_api_byte_data_write_t smbus_byte_data_write;
388 smbus_api_byte_data_read_t smbus_byte_data_read;
389 smbus_api_word_data_write_t smbus_word_data_write;
390 smbus_api_word_data_read_t smbus_word_data_read;
391 smbus_api_pcall_t smbus_pcall;
392 smbus_api_block_write_t smbus_block_write;
393 smbus_api_block_read_t smbus_block_read;
394 smbus_api_block_pcall_t smbus_block_pcall;
395 smbus_api_smbalert_cb_t smbus_smbalert_set_cb;
396 smbus_api_smbalert_cb_t smbus_smbalert_remove_cb;
397 smbus_api_host_notify_cb_t smbus_host_notify_set_cb;
398 smbus_api_host_notify_cb_t smbus_host_notify_remove_cb;
399};
400
405#if defined(CONFIG_SMBUS_STATS) || defined(__DOXYGEN__)
406
407#include <zephyr/stats/stats.h>
408
411STATS_SECT_START(smbus)
412STATS_SECT_ENTRY32(bytes_read)
413STATS_SECT_ENTRY32(bytes_written)
414STATS_SECT_ENTRY32(command_count)
416
417STATS_NAME_START(smbus)
418STATS_NAME(smbus, bytes_read)
419STATS_NAME(smbus, bytes_written)
420STATS_NAME(smbus, command_count)
421STATS_NAME_END(smbus);
422
423struct smbus_device_state {
424 struct device_state devstate;
425 struct stats_smbus stats;
426};
427
431#define Z_SMBUS_DEVICE_STATE_DEFINE(node_id, dev_name) \
432 static struct smbus_device_state Z_DEVICE_STATE_NAME(dev_name) \
433 __attribute__((__section__(".z_devstate")));
434
441#define Z_SMBUS_INIT_FN(dev_name, init_fn) \
442 static inline int \
443 UTIL_CAT(dev_name, _init)(const struct device *dev) \
444 { \
445 struct smbus_device_state *state = \
446 CONTAINER_OF(dev->state, \
447 struct smbus_device_state, \
448 devstate); \
449 stats_init(&state->stats.s_hdr, STATS_SIZE_32, 4, \
450 STATS_NAME_INIT_PARMS(smbus)); \
451 stats_register(dev->name, &(state->stats.s_hdr)); \
452 return init_fn(dev); \
453 }
454
465static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
467{
468 struct smbus_device_state *state =
469 CONTAINER_OF(dev->state, struct smbus_device_state, devstate);
470
471 STATS_INC(state->stats, command_count);
472 STATS_INCN(state->stats, bytes_read, recv);
473 STATS_INCN(state->stats, bytes_written, sent);
474}
475
504#define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
505 data_ptr, cfg_ptr, level, prio, \
506 api_ptr, ...) \
507 Z_SMBUS_DEVICE_STATE_DEFINE(node_id, \
508 Z_DEVICE_DT_DEV_NAME(node_id)); \
509 Z_SMBUS_INIT_FN(Z_DEVICE_DT_DEV_NAME(node_id), init_fn) \
510 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
511 DEVICE_DT_NAME(node_id), \
512 &UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init),\
513 pm_device, \
514 data_ptr, cfg_ptr, level, prio, \
515 api_ptr, \
516 &(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME \
517 (node_id)).devstate), \
518 __VA_ARGS__)
519
520#else /* CONFIG_SMBUS_STATS */
521
522static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
524{
525 ARG_UNUSED(dev);
526 ARG_UNUSED(sent);
527 ARG_UNUSED(recv);
528}
529
530#define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
531 data_ptr, cfg_ptr, level, prio, \
532 api_ptr, ...) \
533 DEVICE_DT_DEFINE(node_id, &init_fn, pm_device, \
534 data_ptr, cfg_ptr, level, prio, \
535 api_ptr, __VA_ARGS__)
536
537#endif /* CONFIG_SMBUS_STATS */
538
548#define SMBUS_DEVICE_DT_INST_DEFINE(inst, ...) \
549 SMBUS_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
550
561__syscall int smbus_configure(const struct device *dev, uint32_t dev_config);
562
563static inline int z_impl_smbus_configure(const struct device *dev,
564 uint32_t dev_config)
565{
566 const struct smbus_driver_api *api =
567 (const struct smbus_driver_api *)dev->api;
568
569 return api->configure(dev, dev_config);
570}
571
592__syscall int smbus_get_config(const struct device *dev, uint32_t *dev_config);
593
594static inline int z_impl_smbus_get_config(const struct device *dev,
595 uint32_t *dev_config)
596{
597 const struct smbus_driver_api *api =
598 (const struct smbus_driver_api *)dev->api;
599
600 if (api->get_config == NULL) {
601 return -ENOSYS;
602 }
603
604 return api->get_config(dev, dev_config);
605}
606
618static inline int smbus_smbalert_set_cb(const struct device *dev,
619 struct smbus_callback *cb)
620{
621 const struct smbus_driver_api *api =
622 (const struct smbus_driver_api *)dev->api;
623
624 if (api->smbus_smbalert_set_cb == NULL) {
625 return -ENOSYS;
626 }
627
628 return api->smbus_smbalert_set_cb(dev, cb);
629}
630
642__syscall int smbus_smbalert_remove_cb(const struct device *dev,
643 struct smbus_callback *cb);
644
645static inline int z_impl_smbus_smbalert_remove_cb(const struct device *dev,
646 struct smbus_callback *cb)
647{
648 const struct smbus_driver_api *api =
649 (const struct smbus_driver_api *)dev->api;
650
651 if (api->smbus_smbalert_remove_cb == NULL) {
652 return -ENOSYS;
653 }
654
655 return api->smbus_smbalert_remove_cb(dev, cb);
656}
657
669static inline int smbus_host_notify_set_cb(const struct device *dev,
670 struct smbus_callback *cb)
671{
672 const struct smbus_driver_api *api =
673 (const struct smbus_driver_api *)dev->api;
674
675 if (api->smbus_host_notify_set_cb == NULL) {
676 return -ENOSYS;
677 }
678
679 return api->smbus_host_notify_set_cb(dev, cb);
680}
681
693__syscall int smbus_host_notify_remove_cb(const struct device *dev,
694 struct smbus_callback *cb);
695
696static inline int z_impl_smbus_host_notify_remove_cb(const struct device *dev,
697 struct smbus_callback *cb)
698{
699 const struct smbus_driver_api *api =
700 (const struct smbus_driver_api *)dev->api;
701
702 if (api->smbus_host_notify_remove_cb == NULL) {
703 return -ENOSYS;
704 }
705
706 return api->smbus_host_notify_remove_cb(dev, cb);
707}
708
725__syscall int smbus_quick(const struct device *dev, uint16_t addr,
726 enum smbus_direction direction);
727
728static inline int z_impl_smbus_quick(const struct device *dev, uint16_t addr,
729 enum smbus_direction direction)
730{
731 const struct smbus_driver_api *api =
732 (const struct smbus_driver_api *)dev->api;
733
734 if (api->smbus_quick == NULL) {
735 return -ENOSYS;
736 }
737
738 if (direction != SMBUS_MSG_READ && direction != SMBUS_MSG_WRITE) {
739 return -EINVAL;
740 }
741
742 return api->smbus_quick(dev, addr, direction);
743}
744
760__syscall int smbus_byte_write(const struct device *dev, uint16_t addr,
761 uint8_t byte);
762
763static inline int z_impl_smbus_byte_write(const struct device *dev,
764 uint16_t addr, uint8_t byte)
765{
766 const struct smbus_driver_api *api =
767 (const struct smbus_driver_api *)dev->api;
768
769 if (api->smbus_byte_write == NULL) {
770 return -ENOSYS;
771 }
772
773 return api->smbus_byte_write(dev, addr, byte);
774}
775
791__syscall int smbus_byte_read(const struct device *dev, uint16_t addr,
792 uint8_t *byte);
793
794static inline int z_impl_smbus_byte_read(const struct device *dev,
795 uint16_t addr, uint8_t *byte)
796{
797 const struct smbus_driver_api *api =
798 (const struct smbus_driver_api *)dev->api;
799
800 if (api->smbus_byte_read == NULL) {
801 return -ENOSYS;
802 }
803
804 return api->smbus_byte_read(dev, addr, byte);
805}
806
823__syscall int smbus_byte_data_write(const struct device *dev, uint16_t addr,
824 uint8_t cmd, uint8_t byte);
825
826static inline int z_impl_smbus_byte_data_write(const struct device *dev,
827 uint16_t addr, uint8_t cmd,
828 uint8_t byte)
829{
830 const struct smbus_driver_api *api =
831 (const struct smbus_driver_api *)dev->api;
832
833 if (api->smbus_byte_data_write == NULL) {
834 return -ENOSYS;
835 }
836
837 return api->smbus_byte_data_write(dev, addr, cmd, byte);
838}
839
856__syscall int smbus_byte_data_read(const struct device *dev, uint16_t addr,
857 uint8_t cmd, uint8_t *byte);
858
859static inline int z_impl_smbus_byte_data_read(const struct device *dev,
860 uint16_t addr, uint8_t cmd,
861 uint8_t *byte)
862{
863 const struct smbus_driver_api *api =
864 (const struct smbus_driver_api *)dev->api;
865
866 if (api->smbus_byte_data_read == NULL) {
867 return -ENOSYS;
868 }
869
870 return api->smbus_byte_data_read(dev, addr, cmd, byte);
871}
872
889__syscall int smbus_word_data_write(const struct device *dev, uint16_t addr,
890 uint8_t cmd, uint16_t word);
891
892static inline int z_impl_smbus_word_data_write(const struct device *dev,
893 uint16_t addr, uint8_t cmd,
894 uint16_t word)
895{
896 const struct smbus_driver_api *api =
897 (const struct smbus_driver_api *)dev->api;
898
899 if (api->smbus_word_data_write == NULL) {
900 return -ENOSYS;
901 }
902
903 return api->smbus_word_data_write(dev, addr, cmd, word);
904}
905
922__syscall int smbus_word_data_read(const struct device *dev, uint16_t addr,
923 uint8_t cmd, uint16_t *word);
924
925static inline int z_impl_smbus_word_data_read(const struct device *dev,
926 uint16_t addr, uint8_t cmd,
927 uint16_t *word)
928{
929 const struct smbus_driver_api *api =
930 (const struct smbus_driver_api *)dev->api;
931
932 if (api->smbus_word_data_read == NULL) {
933 return -ENOSYS;
934 }
935
936 return api->smbus_word_data_read(dev, addr, cmd, word);
937}
938
957__syscall int smbus_pcall(const struct device *dev, uint16_t addr,
958 uint8_t cmd, uint16_t send_word, uint16_t *recv_word);
959
960static inline int z_impl_smbus_pcall(const struct device *dev,
961 uint16_t addr, uint8_t cmd,
962 uint16_t send_word, uint16_t *recv_word)
963{
964 const struct smbus_driver_api *api =
965 (const struct smbus_driver_api *)dev->api;
966
967 if (api->smbus_pcall == NULL) {
968 return -ENOSYS;
969 }
970
971 return api->smbus_pcall(dev, addr, cmd, send_word, recv_word);
972}
973
991__syscall int smbus_block_write(const struct device *dev, uint16_t addr,
993
994static inline int z_impl_smbus_block_write(const struct device *dev,
995 uint16_t addr, uint8_t cmd,
996 uint8_t count, uint8_t *buf)
997{
998 const struct smbus_driver_api *api =
999 (const struct smbus_driver_api *)dev->api;
1000
1001 if (api->smbus_block_write == NULL) {
1002 return -ENOSYS;
1003 }
1004
1005 if (count < 1 || count > SMBUS_BLOCK_BYTES_MAX) {
1006 return -EINVAL;
1007 }
1008
1009 return api->smbus_block_write(dev, addr, cmd, count, buf);
1010}
1011
1029__syscall int smbus_block_read(const struct device *dev, uint16_t addr,
1030 uint8_t cmd, uint8_t *count, uint8_t *buf);
1031
1032static inline int z_impl_smbus_block_read(const struct device *dev,
1033 uint16_t addr, uint8_t cmd,
1034 uint8_t *count, uint8_t *buf)
1035{
1036 const struct smbus_driver_api *api =
1037 (const struct smbus_driver_api *)dev->api;
1038
1039 if (api->smbus_block_read == NULL) {
1040 return -ENOSYS;
1041 }
1042
1043 return api->smbus_block_read(dev, addr, cmd, count, buf);
1044}
1045
1066__syscall int smbus_block_pcall(const struct device *dev,
1067 uint16_t addr, uint8_t cmd,
1068 uint8_t snd_count, uint8_t *snd_buf,
1069 uint8_t *rcv_count, uint8_t *rcv_buf);
1070
1071static inline int z_impl_smbus_block_pcall(const struct device *dev,
1072 uint16_t addr, uint8_t cmd,
1073 uint8_t snd_count, uint8_t *snd_buf,
1074 uint8_t *rcv_count, uint8_t *rcv_buf)
1075{
1076 const struct smbus_driver_api *api =
1077 (const struct smbus_driver_api *)dev->api;
1078
1079 if (api->smbus_block_pcall == NULL) {
1080 return -ENOSYS;
1081 }
1082
1083 return api->smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf,
1084 rcv_count, rcv_buf);
1085}
1086
1087#ifdef __cplusplus
1088}
1089#endif
1090
1095#include <zephyr/syscalls/smbus.h>
1096
1097#endif /* ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ */
ZTEST_BMEM int count
Definition main.c:33
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:922
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:465
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:669
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:206
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:274
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:252
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:618
@ SMBUS_MSG_WRITE
Write a message to SMBus peripheral.
Definition smbus.h:254
@ SMBUS_MSG_READ
Read a message from SMBus peripheral.
Definition smbus.h:256
#define CONTAINER_OF(ptr, type, field)
Get a pointer to a structure containing the element.
Definition util.h:268
#define EINVAL
Invalid argument.
Definition errno.h:60
#define ENOSYS
Function not implemented.
Definition errno.h:82
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:371
Runtime device structure (in ROM) per driver instance.
Definition device.h:403
const void * api
Address of the API structure exposed by the device instance.
Definition device.h:409
struct device_state * state
Address of the common device state.
Definition device.h:411
SMBus callback structure.
Definition smbus.h:287
smbus_callback_handler_t handler
Actual callback function being called when relevant.
Definition smbus.h:292
uint8_t addr
Peripheral device address.
Definition smbus.h:295
sys_snode_t node
This should be used in driver for a callback list management.
Definition smbus.h:289
Complete SMBus DT information.
Definition smbus.h:301
uint16_t addr
Address of the SMBus peripheral device.
Definition smbus.h:305
const struct device * bus
SMBus bus.
Definition smbus.h:303
static ZTEST_DMEM uint32_t send_buf[2]
Definition test_msgq_attrs.c:10