smbus: Introduce SMBus subsystem driver API
Introduces SMBus driver API for SMBus controllers. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
0633b8c75c
commit
adff73d618
6 changed files with 1105 additions and 0 deletions
|
@ -35,6 +35,7 @@ add_subdirectory_ifdef(CONFIG_FUEL_GAUGE fuel_gauge)
|
||||||
add_subdirectory_ifdef(CONFIG_GPIO gpio)
|
add_subdirectory_ifdef(CONFIG_GPIO gpio)
|
||||||
add_subdirectory_ifdef(CONFIG_HWINFO hwinfo)
|
add_subdirectory_ifdef(CONFIG_HWINFO hwinfo)
|
||||||
add_subdirectory_ifdef(CONFIG_I2C i2c)
|
add_subdirectory_ifdef(CONFIG_I2C i2c)
|
||||||
|
add_subdirectory_ifdef(CONFIG_SMBUS smbus)
|
||||||
add_subdirectory_ifdef(CONFIG_I2S i2s)
|
add_subdirectory_ifdef(CONFIG_I2S i2s)
|
||||||
add_subdirectory_ifdef(CONFIG_I3C i3c)
|
add_subdirectory_ifdef(CONFIG_I3C i3c)
|
||||||
add_subdirectory_ifdef(CONFIG_IEEE802154 ieee802154)
|
add_subdirectory_ifdef(CONFIG_IEEE802154 ieee802154)
|
||||||
|
|
|
@ -35,6 +35,7 @@ source "drivers/hwinfo/Kconfig"
|
||||||
source "drivers/i2c/Kconfig"
|
source "drivers/i2c/Kconfig"
|
||||||
source "drivers/i2s/Kconfig"
|
source "drivers/i2s/Kconfig"
|
||||||
source "drivers/i3c/Kconfig"
|
source "drivers/i3c/Kconfig"
|
||||||
|
source "drivers/smbus/Kconfig"
|
||||||
source "drivers/ieee802154/Kconfig"
|
source "drivers/ieee802154/Kconfig"
|
||||||
source "drivers/input/Kconfig"
|
source "drivers/input/Kconfig"
|
||||||
source "drivers/interrupt_controller/Kconfig"
|
source "drivers/interrupt_controller/Kconfig"
|
||||||
|
|
6
drivers/smbus/CMakeLists.txt
Normal file
6
drivers/smbus/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
zephyr_library()
|
||||||
|
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_USERSPACE smbus_handlers.c)
|
30
drivers/smbus/Kconfig
Normal file
30
drivers/smbus/Kconfig
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# SMBus configuration options
|
||||||
|
|
||||||
|
# Copyright (c) 2022 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
menuconfig SMBUS
|
||||||
|
bool "SMBus Drivers"
|
||||||
|
help
|
||||||
|
Enable SMBus Driver Configuration
|
||||||
|
|
||||||
|
if SMBUS
|
||||||
|
|
||||||
|
config SMBUS_STATS
|
||||||
|
bool "SMBus device Stats"
|
||||||
|
depends on STATS
|
||||||
|
help
|
||||||
|
Enable SMBus Stats.
|
||||||
|
|
||||||
|
config SMBUS_INIT_PRIORITY
|
||||||
|
int "Init priority"
|
||||||
|
default KERNEL_INIT_PRIORITY_DEVICE
|
||||||
|
help
|
||||||
|
SMBus device driver initialization priority.
|
||||||
|
|
||||||
|
|
||||||
|
module = SMBUS
|
||||||
|
module-str = smbus
|
||||||
|
source "subsys/logging/Kconfig.template.log_config"
|
||||||
|
|
||||||
|
endif # SMBUS
|
130
drivers/smbus/smbus_handlers.c
Normal file
130
drivers/smbus/smbus_handlers.c
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/smbus.h>
|
||||||
|
#include <zephyr/syscall_handler.h>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_configure(const struct device *dev,
|
||||||
|
uint32_t dev_config)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_DRIVER_SMBUS(dev, configure));
|
||||||
|
|
||||||
|
return z_impl_smbus_configure(dev, dev_config);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_configure_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_get_config(const struct device *dev,
|
||||||
|
uint32_t *dev_config)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_DRIVER_SMBUS(dev, get_config));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t)));
|
||||||
|
|
||||||
|
return z_impl_smbus_get_config(dev, dev_config);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_get_config_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_quick(const struct device *dev, uint16_t addr,
|
||||||
|
enum smbus_direction rw)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
|
||||||
|
return z_impl_smbus_quick(dev, addr, rw);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_quick_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_byte_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
|
||||||
|
return z_impl_smbus_byte_write(dev, addr, byte);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_byte_write_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_byte_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t *byte)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t)));
|
||||||
|
|
||||||
|
return z_impl_smbus_byte_read(dev, addr, byte);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_byte_read_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_byte_data_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t byte)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
|
||||||
|
return z_impl_smbus_byte_data_write(dev, addr, cmd, byte);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_byte_data_write_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_byte_data_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t *byte)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t)));
|
||||||
|
|
||||||
|
return z_impl_smbus_byte_data_read(dev, addr, cmd, byte);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_byte_data_read_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_word_data_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t word)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
|
||||||
|
return z_impl_smbus_word_data_write(dev, addr, cmd, word);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_word_data_write_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_word_data_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t *word)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(word, sizeof(uint16_t)));
|
||||||
|
|
||||||
|
return z_impl_smbus_word_data_read(dev, addr, cmd, word);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_word_data_read_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_pcall(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t send_word, uint16_t *recv_word)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(recv_word, sizeof(uint16_t)));
|
||||||
|
|
||||||
|
return z_impl_smbus_pcall(dev, addr, cmd, send_word, recv_word);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_pcall_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_block_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t count, uint8_t *buf)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, count));
|
||||||
|
|
||||||
|
return z_impl_smbus_block_write(dev, addr, cmd, count, buf);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_block_write_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_smbus_block_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t *count, uint8_t *buf)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(count, sizeof(uint8_t)));
|
||||||
|
|
||||||
|
return z_impl_smbus_block_read(dev, addr, cmd, count, buf);
|
||||||
|
}
|
||||||
|
#include <syscalls/smbus_block_read_mrsh.c>
|
937
include/zephyr/drivers/smbus.h
Normal file
937
include/zephyr/drivers/smbus.h
Normal file
|
@ -0,0 +1,937 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
|
||||||
|
#define ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SMBus Interface
|
||||||
|
* @defgroup smbus_interface SMBus Interface
|
||||||
|
* @ingroup io_interfaces
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SMBus Protocol commands
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* SMBus Specification defines following SMBus protocols operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Quick protocol is 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.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* 0 1
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* |S| Periph Addr |D|A|P|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_QUICK 0b000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Byte protocol can send or receive one byte of data.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* 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|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_BYTE 0b001
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Byte Data protocol send first byte (command) followed
|
||||||
|
* by read or write one byte.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* 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|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_BYTE_DATA 0b010
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Word Data protocol send first byte (command) followed
|
||||||
|
* by read or write two bytes.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* 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|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_WORD_DATA 0b011
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Process Call protocol is basically Write Word followed by
|
||||||
|
* Wead Word. It is named so because command sends data and waits
|
||||||
|
* for the perihperal to return reply.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* 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|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_PROC_CALL 0b100
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Block protocol reads or writes block of data up to 32 bytes.
|
||||||
|
* Count byte specifies the amount of data.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
*
|
||||||
|
* 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|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_BLOCK 0b101
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMBus Block Write - Block Read Process Call protocol is basically
|
||||||
|
* Block Write followed by Block Read
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* 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|
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SMBUS_CMD_BLOCK_PROC 0b111
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** Maximum number of bytes in SMBus Block protocol */
|
||||||
|
#define SMBUS_BLOCK_BYTES_MAX 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SMBus device functionality
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* Following parameters describes functionality of SMBus device
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Peripheral to act as Controller. */
|
||||||
|
#define SMBUS_MODE_CONTROLLER BIT(0)
|
||||||
|
|
||||||
|
/** Support Packet Error Code (PEC) checking */
|
||||||
|
#define SMBUS_MODE_PEC BIT(1)
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SMBus special reserved addresses
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* Following addresses are reserved by SMBus specification
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alert Response Address (ARA)
|
||||||
|
*
|
||||||
|
* A broadcast address used by the system host as part of the
|
||||||
|
* Alert Response Protocol.
|
||||||
|
*/
|
||||||
|
#define SMBUS_ADDRESS_ARA 0x0c
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SMBus read / write direction
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @brief SMBus read / write direction */
|
||||||
|
enum smbus_direction {
|
||||||
|
/** Write message to SMBus */
|
||||||
|
SMBUS_MSG_WRITE = 0,
|
||||||
|
/** Read message from SMBus */
|
||||||
|
SMBUS_MSG_READ = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @cond INTERNAL_HIDDEN */
|
||||||
|
#define SMBUS_MSG_RW_MASK BIT(0)
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Complete SMBus DT information
|
||||||
|
*
|
||||||
|
* @param bus SMBus bus
|
||||||
|
* @param addr peripheral address
|
||||||
|
*/
|
||||||
|
struct smbus_dt_spec {
|
||||||
|
const struct device *bus;
|
||||||
|
uint16_t addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure initializer for smbus_dt_spec from devicetree
|
||||||
|
*
|
||||||
|
* This helper macro expands to a static initializer for a <tt>struct
|
||||||
|
* smbus_dt_spec</tt> by reading the relevant bus and address data from
|
||||||
|
* the devicetree.
|
||||||
|
*
|
||||||
|
* @param node_id Devicetree node identifier for the SMBus device whose
|
||||||
|
* struct smbus_dt_spec to create an initializer for
|
||||||
|
*/
|
||||||
|
#define SMBUS_DT_SPEC_GET(node_id) \
|
||||||
|
{ \
|
||||||
|
.bus = DEVICE_DT_GET(DT_BUS(node_id)), \
|
||||||
|
.addr = DT_REG_ADDR(node_id) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure initializer for smbus_dt_spec from devicetree instance
|
||||||
|
*
|
||||||
|
* This is equivalent to
|
||||||
|
* <tt>SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))</tt>.
|
||||||
|
*
|
||||||
|
* @param inst Devicetree instance number
|
||||||
|
*/
|
||||||
|
#define SMBUS_DT_SPEC_INST_GET(inst) SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @cond INTERNAL_HIDDEN
|
||||||
|
*
|
||||||
|
* These are for internal use only, so skip these in
|
||||||
|
* public documentation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (*smbus_api_configure_t)(const struct device *dev,
|
||||||
|
uint32_t dev_config);
|
||||||
|
typedef int (*smbus_api_get_config_t)(const struct device *dev,
|
||||||
|
uint32_t *dev_config);
|
||||||
|
typedef int (*smbus_api_quick_t)(const struct device *dev,
|
||||||
|
uint16_t addr, enum smbus_direction);
|
||||||
|
typedef int (*smbus_api_byte_write_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t byte);
|
||||||
|
typedef int (*smbus_api_byte_read_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t *byte);
|
||||||
|
typedef int (*smbus_api_byte_data_write_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t byte);
|
||||||
|
typedef int (*smbus_api_byte_data_read_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t *byte);
|
||||||
|
typedef int (*smbus_api_word_data_write_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t word);
|
||||||
|
typedef int (*smbus_api_word_data_read_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t *word);
|
||||||
|
typedef int (*smbus_api_pcall_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t send_word, uint16_t *recv_word);
|
||||||
|
typedef int (*smbus_api_block_write_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t count, uint8_t *buf);
|
||||||
|
typedef int (*smbus_api_block_read_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t *count, uint8_t *buf);
|
||||||
|
typedef int (*smbus_api_block_pcall_t)(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t send_count, uint8_t *send_buf,
|
||||||
|
uint8_t *recv_count, uint8_t *recv_buf);
|
||||||
|
|
||||||
|
__subsystem struct smbus_driver_api {
|
||||||
|
smbus_api_configure_t configure;
|
||||||
|
smbus_api_get_config_t get_config;
|
||||||
|
smbus_api_quick_t smbus_quick;
|
||||||
|
smbus_api_byte_write_t smbus_byte_write;
|
||||||
|
smbus_api_byte_read_t smbus_byte_read;
|
||||||
|
smbus_api_byte_data_write_t smbus_byte_data_write;
|
||||||
|
smbus_api_byte_data_read_t smbus_byte_data_read;
|
||||||
|
smbus_api_word_data_write_t smbus_word_data_write;
|
||||||
|
smbus_api_word_data_read_t smbus_word_data_read;
|
||||||
|
smbus_api_pcall_t smbus_pcall;
|
||||||
|
smbus_api_block_write_t smbus_block_write;
|
||||||
|
smbus_api_block_read_t smbus_block_read;
|
||||||
|
smbus_api_block_pcall_t smbus_block_pcall;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @endcond
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_SMBUS_STATS) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
#include <zephyr/stats/stats.h>
|
||||||
|
|
||||||
|
/** @cond INTERNAL_HIDDEN */
|
||||||
|
|
||||||
|
STATS_SECT_START(smbus)
|
||||||
|
STATS_SECT_ENTRY32(bytes_read)
|
||||||
|
STATS_SECT_ENTRY32(bytes_written)
|
||||||
|
STATS_SECT_ENTRY32(command_count)
|
||||||
|
STATS_SECT_END;
|
||||||
|
|
||||||
|
STATS_NAME_START(smbus)
|
||||||
|
STATS_NAME(smbus, bytes_read)
|
||||||
|
STATS_NAME(smbus, bytes_written)
|
||||||
|
STATS_NAME(smbus, command_count)
|
||||||
|
STATS_NAME_END(smbus);
|
||||||
|
|
||||||
|
struct smbus_device_state {
|
||||||
|
struct device_state devstate;
|
||||||
|
struct stats_smbus stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define a statically allocated and section assigned smbus device state
|
||||||
|
*/
|
||||||
|
#define Z_SMBUS_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||||
|
static struct smbus_device_state Z_DEVICE_STATE_NAME(dev_name) \
|
||||||
|
__attribute__((__section__(".z_devstate")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define an smbus device init wrapper function
|
||||||
|
*
|
||||||
|
* This does device instance specific initialization of common data
|
||||||
|
* (such as stats) and calls the given init_fn
|
||||||
|
*/
|
||||||
|
#define Z_SMBUS_INIT_FN(dev_name, init_fn) \
|
||||||
|
static inline int \
|
||||||
|
UTIL_CAT(dev_name, _init)(const struct device *dev) \
|
||||||
|
{ \
|
||||||
|
struct smbus_device_state *state = \
|
||||||
|
CONTAINER_OF(dev->state, \
|
||||||
|
struct smbus_device_state, \
|
||||||
|
devstate); \
|
||||||
|
stats_init(&state->stats.s_hdr, STATS_SIZE_32, 4, \
|
||||||
|
STATS_NAME_INIT_PARMS(smbus)); \
|
||||||
|
stats_register(dev->name, &(state->stats.s_hdr)); \
|
||||||
|
return init_fn(dev); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates the SMBus stats
|
||||||
|
*
|
||||||
|
* @param dev SMBus device to update stats for
|
||||||
|
* @param sent Number of bytes sent
|
||||||
|
* @param recv Number of bytes received
|
||||||
|
*/
|
||||||
|
static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
|
||||||
|
uint8_t recv)
|
||||||
|
{
|
||||||
|
struct smbus_device_state *state =
|
||||||
|
CONTAINER_OF(dev->state, struct smbus_device_state, devstate);
|
||||||
|
|
||||||
|
STATS_INC(state->stats, command_count);
|
||||||
|
STATS_INCN(state->stats, bytes_read, recv);
|
||||||
|
STATS_INCN(state->stats, bytes_written, sent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Like DEVICE_DT_DEFINE() with SMBus specifics.
|
||||||
|
*
|
||||||
|
* @details 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 @kconfig{CONFIG_SMBUS_STATS}.
|
||||||
|
*
|
||||||
|
* @param node_id The devicetree node identifier.
|
||||||
|
*
|
||||||
|
* @param init_fn Name of the init function of the driver.
|
||||||
|
*
|
||||||
|
* @param pm_device PM device resources reference
|
||||||
|
* (NULL if device does not use PM).
|
||||||
|
*
|
||||||
|
* @param data_ptr Pointer to the device's private data.
|
||||||
|
*
|
||||||
|
* @param cfg_ptr The address to the structure containing the
|
||||||
|
* configuration information for this instance of the driver.
|
||||||
|
*
|
||||||
|
* @param level The initialization level. See SYS_INIT() for
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* @param prio Priority within the selected initialization level. See
|
||||||
|
* SYS_INIT() for details.
|
||||||
|
*
|
||||||
|
* @param api_ptr Provides an initial pointer to the API function struct
|
||||||
|
* used by the driver. Can be NULL.
|
||||||
|
*/
|
||||||
|
#define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
|
||||||
|
data_ptr, cfg_ptr, level, prio, \
|
||||||
|
api_ptr, ...) \
|
||||||
|
Z_SMBUS_DEVICE_STATE_DEFINE(node_id, \
|
||||||
|
Z_DEVICE_DT_DEV_NAME(node_id)); \
|
||||||
|
Z_SMBUS_INIT_FN(Z_DEVICE_DT_DEV_NAME(node_id), init_fn) \
|
||||||
|
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
|
||||||
|
DEVICE_DT_NAME(node_id), \
|
||||||
|
&UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init),\
|
||||||
|
pm_device, \
|
||||||
|
data_ptr, cfg_ptr, level, prio, \
|
||||||
|
api_ptr, \
|
||||||
|
&(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME \
|
||||||
|
(node_id)).devstate), \
|
||||||
|
__VA_ARGS__)
|
||||||
|
|
||||||
|
#else /* CONFIG_SMBUS_STATS */
|
||||||
|
|
||||||
|
static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
|
||||||
|
uint8_t recv)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(dev);
|
||||||
|
ARG_UNUSED(sent);
|
||||||
|
ARG_UNUSED(recv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
|
||||||
|
data_ptr, cfg_ptr, level, prio, \
|
||||||
|
api_ptr, ...) \
|
||||||
|
DEVICE_DT_DEFINE(node_id, &init_fn, pm_device, \
|
||||||
|
data_ptr, cfg_ptr, level, prio, \
|
||||||
|
api_ptr, __VA_ARGS__)
|
||||||
|
|
||||||
|
#endif /* CONFIG_SMBUS_STATS */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Like SMBUS_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT
|
||||||
|
* compatible
|
||||||
|
*
|
||||||
|
* @param inst instance number. This is replaced by
|
||||||
|
* <tt>DT_DRV_COMPAT(inst)</tt> in the call to SMBUS_DEVICE_DT_DEFINE().
|
||||||
|
*
|
||||||
|
* @param ... other parameters as expected by SMBUS_DEVICE_DT_DEFINE().
|
||||||
|
*/
|
||||||
|
#define SMBUS_DEVICE_DT_INST_DEFINE(inst, ...) \
|
||||||
|
SMBUS_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure operation of a SMBus host controller.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
* @param dev_config Bit-packed 32-bit value to the device runtime configuration
|
||||||
|
* for the SMBus controller.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -EIO General input / output error, failed to configure device.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_configure(const struct device *dev, uint32_t dev_config);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_configure(const struct device *dev,
|
||||||
|
uint32_t dev_config)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
return api->configure(dev, dev_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
* @param dev_config Pointer to return bit-packed 32-bit value of
|
||||||
|
* the SMBus controller configuration.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
* @retval -ENOSYS If get config is not implemented
|
||||||
|
*/
|
||||||
|
__syscall int smbus_get_config(const struct device *dev, uint32_t *dev_config);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_get_config(const struct device *dev,
|
||||||
|
uint32_t *dev_config)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->get_config == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->get_config(dev, dev_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Quick operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus Quick
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param direction Direction Read or Write.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_quick(const struct device *dev, uint16_t addr,
|
||||||
|
enum smbus_direction direction);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_quick(const struct device *dev, uint16_t addr,
|
||||||
|
enum smbus_direction direction)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_quick == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction != SMBUS_MSG_READ && direction != SMBUS_MSG_WRITE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_quick(dev, addr, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Byte Write operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Byte Write operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param byte Byte to be sent to the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_byte_write(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t byte);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_byte_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_byte_write == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_byte_write(dev, addr, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Byte Read operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Byte Read operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param byte Byte received from the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_byte_read(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t *byte);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_byte_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t *byte)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_byte_read == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_byte_read(dev, addr, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Byte Data Write operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Byte Data Write operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param byte Byte to be sent to the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_byte_data_write(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint8_t byte);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_byte_data_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t byte)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_byte_data_write == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_byte_data_write(dev, addr, cmd, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
__syscall int smbus_byte_data_read(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint8_t *byte);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Byte Data Read operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Byte Data Read operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param byte Byte received from the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
static inline int z_impl_smbus_byte_data_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t *byte)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_byte_data_read == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_byte_data_read(dev, addr, cmd, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Word Data Write operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Word Data Write operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param word Word (16-bit) to be sent to the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_word_data_write(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint16_t word);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_word_data_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t word)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_word_data_write == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_word_data_write(dev, addr, cmd, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Word Data Read operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Word Data Read operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param word Word (16-bit) received from the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_word_data_read(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint16_t *word);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_word_data_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t *word)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_word_data_read == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_word_data_read(dev, addr, cmd, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param send_word Word (16-bit) to be sent to the peripheral device.
|
||||||
|
* @param recv_word Word (16-bit) received from the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_pcall(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint16_t send_word, uint16_t *recv_word);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_pcall(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint16_t send_word, uint16_t *recv_word)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_pcall == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_pcall(dev, addr, cmd, send_word, recv_word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Block Write operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Block Write operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param count Size of the data block buffer. Maximum 32 bytes.
|
||||||
|
* @param buf Data block buffer to be sent to the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_block_write(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint8_t count, uint8_t *buf);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_block_write(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t count, uint8_t *buf)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_block_write == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 1 || count > SMBUS_BLOCK_BYTES_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_block_write(dev, addr, cmd, count, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform SMBus Block Read operation
|
||||||
|
*
|
||||||
|
* This routine provides a generic interface to perform SMBus
|
||||||
|
* Block Read operation.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param count Size of the data peripheral sent. Maximum 32 bytes.
|
||||||
|
* @param buf Data block buffer received from the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall int smbus_block_read(const struct device *dev, uint16_t addr,
|
||||||
|
uint8_t cmd, uint8_t *count, uint8_t *buf);
|
||||||
|
|
||||||
|
static inline int z_impl_smbus_block_read(const struct device *dev,
|
||||||
|
uint16_t addr, uint8_t cmd,
|
||||||
|
uint8_t *count, uint8_t *buf)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_block_read == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_block_read(dev, addr, cmd, count, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for an SMBus
|
||||||
|
* driver configured in controller mode.
|
||||||
|
* @param addr Address of the SMBus peripheral device.
|
||||||
|
* @param cmd Command byte which is sent to peripheral device first.
|
||||||
|
* @param snd_count Size of the data block buffer to send.
|
||||||
|
* @param snd_buf Data block buffer send to the peripheral device.
|
||||||
|
* @param rcv_count Size of the data peripheral sent.
|
||||||
|
* @param rcv_buf Data block buffer received from the peripheral device.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval -ENOSYS If not implemented by the driver.
|
||||||
|
* @retval -EIO General input / output error.
|
||||||
|
*/
|
||||||
|
__syscall 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);
|
||||||
|
|
||||||
|
static inline int z_impl_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)
|
||||||
|
{
|
||||||
|
const struct smbus_driver_api *api =
|
||||||
|
(const struct smbus_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->smbus_block_pcall == NULL) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf,
|
||||||
|
rcv_count, rcv_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <syscalls/smbus.h>
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue