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