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.

SMBus read / write direction

enum smbus_direction

SMBus read / write direction.

Values:

enumerator SMBUS_MSG_WRITE = 0

Write a message to SMBus peripheral.

enumerator SMBUS_MSG_READ = 1

Read a message from SMBus peripheral.

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:

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.

struct smbus_dt_spec
#include <smbus.h>

Complete SMBus DT information.

Public Members

const struct device *bus

SMBus bus.

uint16_t addr

Address of the SMBus peripheral device.