System Management Bus (SMBus)
Overview
System Management Bus (SMBus) is derived from I2C for communication with devices on the motherboard. A system may use SMBus to communicate with the peripherals on the motherboard without using dedicated control lines. SMBus peripherals can provide various manufacturer information, report errors, accept control parameters, etc.
Devices on the bus can operate in three roles: as a Controller that initiates transactions and controls the clock, a Peripheral that responds to transaction commands, or a Host, which is a specialized Controller, that provides the main interface to the system’s CPU. Zephyr has API for the Controller role.
SMBus peripheral devices can initiate communication with Controller with two methods:
Host Notify protocol: Peripheral device that supports the Host Notify protocol behaves as a Controller to perform the notification. It writes a three-bytes message to a special address “SMBus Host (0x08)” with own address and two bytes of relevant data.
SMBALERT# signal: Peripheral device uses special signal SMBALERT# to request attention from the Controller. The Controller needs to read one byte from the special “SMBus Alert Response Address (ARA) (0x0c)”. The peripheral device responds with a data byte containing its own address.
Currently, the API is based on SMBus Specification version 2.0
Note
See Rule A.2: Inclusive Language for information about the terminology used in this API.
SMBus Controller API
Zephyr’s SMBus controller API is used when an SMBus device controls the bus, particularly the start and stop conditions and the clock. This is the most common mode used to interact with SMBus peripherals.
Configuration Options
Related configuration options:
API Reference
- group smbus_interface
SMBus Interface.
- Since
3.4
- Version
0.1.0
SMBus read / write direction
SMBus Protocol commands
SMBus Specification defines the following SMBus protocols operations
-
SMBUS_CMD_QUICK
SMBus Quick protocol is a very simple command with no data sent or received.
Peripheral may denote only R/W bit, which can still be used for the peripheral management, for example to switch peripheral On/Off. Quick protocol can also be used for peripheral devices scanning.
0 1 0 1 2 3 4 5 6 7 8 9 0 +-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |D|A|P| +-+-+-+-+-+-+-+-+-+-+-+
-
SMBUS_CMD_BYTE
SMBus Byte protocol can send or receive one byte of data.
Byte Write 0 1 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A|P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Byte Read 0 1 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |R|A| Byte received |N|P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
SMBUS_CMD_BYTE_DATA
SMBus Byte Data protocol sends the first byte (command) followed by read or write one byte.
Byte Data Write 0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A| Data Write |A|P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Byte Data Read 0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Read |N|P| +-+-+-+-+-+-+-+-+-+-+
-
SMBUS_CMD_WORD_DATA
SMBus Word Data protocol sends the first byte (command) followed by read or write two bytes.
Word Data Write 0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A| Data Write Low|A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Write Hi |A|P| +-+-+-+-+-+-+-+-+-+-+ Word Data Read 0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |A| Data Read Low |A| Data Read Hi |N|P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
SMBUS_CMD_PROC_CALL
SMBus Process Call protocol is Write Word followed by Read Word.
It is named so because the command sends data and waits for the peripheral to return a reply.
0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A| Data Write Low|A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Write Hi |A|S| Periph Addr |R|A| Data Read Low |A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Read Hi |N|P| +-+-+-+-+-+-+-+-+-+-+
-
SMBUS_CMD_BLOCK
SMBus Block protocol reads or writes a block of data up to 32 bytes.
The Count byte specifies the amount of data.
SMBus Block Write 0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A| Send Count=N |A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Write 1 |A| ... |A| Data Write N |A|P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ SMBus Block Read 0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |A| Recv Count=N |A| Data Read 1 |A| ... |A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Read N |N|P| +-+-+-+-+-+-+-+-+-+-+
-
SMBUS_CMD_BLOCK_PROC
SMBus Block Write - Block Read Process Call protocol is Block Write followed by Block Read.
0 1 2 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |S| Periph Addr |W|A| Command code |A| Count = N |A| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Write 1 |A| ... |A| Data Write N |A|S| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Periph Addr |R|A| Recv Count=N |A| Data Read 1 |A| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... |A| Data Read N |N|P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
SMBus device functionality
The following parameters describe the functionality of the SMBus device
-
SMBUS_MODE_CONTROLLER
Peripheral to act as Controller.
-
SMBUS_MODE_PEC
Support Packet Error Code (PEC) checking.
-
SMBUS_MODE_HOST_NOTIFY
Support Host Notify functionality.
-
SMBUS_MODE_SMBALERT
Support SMBALERT signal functionality.
SMBus special reserved addresses
The following addresses are reserved by SMBus specification
-
SMBUS_ADDRESS_ARA
Alert Response Address (ARA)
A broadcast address used by the system host as part of the Alert Response Protocol.
Defines
-
SMBUS_BLOCK_BYTES_MAX
Maximum number of bytes in SMBus Block protocol.
-
SMBUS_DT_SPEC_GET(node_id)
Structure initializer for smbus_dt_spec from devicetree.
This helper macro expands to a static initializer for a
struct smbus_dt_spec
by reading the relevant bus and address data from the devicetree.- Parameters:
node_id – Devicetree node identifier for the SMBus device whose struct smbus_dt_spec to create an initializer for
-
SMBUS_DT_SPEC_INST_GET(inst)
Structure initializer for smbus_dt_spec from devicetree instance.
This is equivalent to
SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
.- Parameters:
inst – Devicetree instance number
-
SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, data_ptr, cfg_ptr, level, prio, api_ptr, ...)
Like DEVICE_DT_DEFINE() with SMBus specifics.
Defines a device which implements the SMBus API. May generate a custom device_state container struct and init_fn wrapper when needed depending on SMBus
CONFIG_SMBUS_STATS
.- Parameters:
node_id – The devicetree node identifier.
init_fn – Name of the init function of the driver.
pm_device – PM device resources reference (NULL if device does not use PM).
data_ptr – Pointer to the device’s private data.
cfg_ptr – The address to the structure containing the configuration information for this instance of the driver.
level – The initialization level. See SYS_INIT() for details.
prio – Priority within the selected initialization level. See SYS_INIT() for details.
api_ptr – Provides an initial pointer to the API function struct used by the driver. Can be NULL.
-
SMBUS_DEVICE_DT_INST_DEFINE(inst, ...)
Like SMBUS_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT compatible.
- Parameters:
inst – instance number. This is replaced by
DT_DRV_COMPAT(inst)
in the call to SMBUS_DEVICE_DT_DEFINE().... – other parameters as expected by SMBUS_DEVICE_DT_DEFINE().
Typedefs
-
typedef void (*smbus_callback_handler_t)(const struct device *dev, struct smbus_callback *cb, uint8_t addr)
Define SMBus callback handler function signature.
- Param dev:
Pointer to the device structure for the SMBus driver instance.
- Param cb:
Structure smbus_callback owning this handler.
- Param addr:
Address of the SMBus peripheral device.
Functions
-
static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent, uint8_t recv)
Updates the SMBus stats.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance to update stats for.
sent – Number of bytes sent
recv – Number of bytes received
-
int smbus_configure(const struct device *dev, uint32_t dev_config)
Configure operation of a SMBus host controller.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
dev_config – Bit-packed 32-bit value to the device runtime configuration for the SMBus controller.
- Return values:
0 – If successful.
-EIO – General input / output error.
-
int smbus_get_config(const struct device *dev, uint32_t *dev_config)
Get configuration of a SMBus host controller.
This routine provides a way to get current configuration. It is allowed to call the function before smbus_configure, because some SMBus ports can be configured during init process. However, if the SMBus port is not configured, smbus_get_config returns an error.
smbus_get_config can return cached config or probe hardware, but it has to be up to date with current configuration.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
dev_config – Pointer to return bit-packed 32-bit value of the SMBus controller configuration.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_get_config() is not implemented by the driver.
-
static inline int smbus_smbalert_set_cb(const struct device *dev, struct smbus_callback *cb)
Add SMBUSALERT callback for a SMBus host controller.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
cb – Pointer to a callback structure.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_smbalert_set_cb() is not implemented by the driver.
-
int smbus_smbalert_remove_cb(const struct device *dev, struct smbus_callback *cb)
Remove SMBUSALERT callback from a SMBus host controller.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
cb – Pointer to a callback structure.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_smbalert_remove_cb() is not implemented by the driver.
-
static inline int smbus_host_notify_set_cb(const struct device *dev, struct smbus_callback *cb)
Add Host Notify callback for a SMBus host controller.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
cb – Pointer to a callback structure.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_host_notify_set_cb() is not implemented by the driver.
-
int smbus_host_notify_remove_cb(const struct device *dev, struct smbus_callback *cb)
Remove Host Notify callback from a SMBus host controller.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
cb – Pointer to a callback structure.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_host_notify_remove_cb() is not implemented by the driver.
-
int smbus_quick(const struct device *dev, uint16_t addr, enum smbus_direction direction)
Perform SMBus Quick operation.
This routine provides a generic interface to perform SMBus Quick operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance. driver configured in controller mode.
addr – Address of the SMBus peripheral device.
direction – Direction Read or Write.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_quick() is not implemented by the driver.
-
int smbus_byte_write(const struct device *dev, uint16_t addr, uint8_t byte)
Perform SMBus Byte Write operation.
This routine provides a generic interface to perform SMBus Byte Write operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
byte – Byte to be sent to the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_byte_write() is not implemented by the driver.
-
int smbus_byte_read(const struct device *dev, uint16_t addr, uint8_t *byte)
Perform SMBus Byte Read operation.
This routine provides a generic interface to perform SMBus Byte Read operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
byte – Byte received from the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_byte_read() is not implemented by the driver.
-
int smbus_byte_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t byte)
Perform SMBus Byte Data Write operation.
This routine provides a generic interface to perform SMBus Byte Data Write operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
byte – Byte to be sent to the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_byte_data_write() is not implemented by the driver.
-
int smbus_byte_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *byte)
Perform SMBus Byte Data Read operation.
This routine provides a generic interface to perform SMBus Byte Data Read operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
byte – Byte received from the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_byte_data_read() is not implemented by the driver.
-
int smbus_word_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t word)
Perform SMBus Word Data Write operation.
This routine provides a generic interface to perform SMBus Word Data Write operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
word – Word (16-bit) to be sent to the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_word_data_write() is not implemented by the driver.
-
int smbus_word_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t *word)
Perform SMBus Word Data Read operation.
This routine provides a generic interface to perform SMBus Word Data Read operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
word – Word (16-bit) received from the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_word_data_read() is not implemented by the driver.
-
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.
This routine provides a generic interface to perform SMBus Process Call operation, which means Write 2 bytes following by Read 2 bytes.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
send_word – Word (16-bit) to be sent to the peripheral device.
recv_word – Word (16-bit) received from the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_pcall() is not implemented by the driver.
-
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.
This routine provides a generic interface to perform SMBus Block Write operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
count – Size of the data block buffer. Maximum 32 bytes.
buf – Data block buffer to be sent to the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_block_write() is not implemented by the driver.
-
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.
This routine provides a generic interface to perform SMBus Block Read operation.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
count – Size of the data peripheral sent. Maximum 32 bytes.
buf – Data block buffer received from the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_block_read() is not implemented by the driver.
-
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.
This routine provides a generic interface to perform SMBus Block Process Call operation. This operation is basically Block Write followed by Block Read.
- Parameters:
dev – Pointer to the device structure for the SMBus driver instance.
addr – Address of the SMBus peripheral device.
cmd – Command byte which is sent to peripheral device first.
snd_count – Size of the data block buffer to send.
snd_buf – Data block buffer send to the peripheral device.
rcv_count – Size of the data peripheral sent.
rcv_buf – Data block buffer received from the peripheral device.
- Return values:
0 – If successful.
-EIO – General input / output error.
-ENOSYS – If function smbus_block_pcall() is not implemented by the driver.
-
struct smbus_callback
- #include <smbus.h>
SMBus callback structure.
Used to register a callback in the driver instance callback list. As many callbacks as needed can be added as long as each of them is a unique pointer of struct smbus_callback.
Note: Such struct should not be allocated on stack.
Public Members
-
sys_snode_t node
This should be used in driver for a callback list management.
-
smbus_callback_handler_t handler
Actual callback function being called when relevant.
-
uint8_t addr
Peripheral device address.
-
sys_snode_t node
-
struct smbus_dt_spec
- #include <smbus.h>
Complete SMBus DT information.