drivers: smbus: pch: Add Block Process Call operation

Add SMBus Block Process Call implementation for Intel PCH SMBus
driver.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
Andrei Emeltchenko 2022-09-29 16:40:31 +03:00 committed by Anas Nashif
commit 2de1936acc
2 changed files with 65 additions and 0 deletions

View file

@ -716,6 +716,56 @@ unlock:
return ret;
}
/* Implementation of SMBus Block Process Call */
static int pch_smbus_block_pcall(const struct device *dev,
uint16_t periph_addr, uint8_t command,
uint8_t send_count, uint8_t *send_buf,
uint8_t *recv_count, uint8_t *recv_buf)
{
struct pch_data *data = dev->data;
int ret;
LOG_DBG("dev %p addr 0x%02x command 0x%02x",
dev, periph_addr, command);
k_mutex_lock(&data->mutex, K_FOREVER);
ret = pch_smbus_block_start(dev, periph_addr, SMBUS_MSG_WRITE, command,
send_count, send_buf, SMBUS_CMD_BLOCK_PROC);
if (ret < 0) {
goto unlock;
}
/* Wait for completion from ISR */
ret = k_sem_take(&data->completion_sync, K_MSEC(30));
if (ret != 0) {
LOG_ERR("SMBus Block Process Call timed out");
ret = -ETIMEDOUT;
goto unlock;
}
ret = pch_check_status(dev);
if (ret < 0) {
goto unlock;
}
*recv_count = pch_reg_read(dev, PCH_SMBUS_HD0);
if (*recv_count == 0 ||
*recv_count + send_count > SMBUS_BLOCK_BYTES_MAX) {
ret = -ENODATA;
goto unlock;
}
for (int i = 0; i < *recv_count; i++) {
recv_buf[i] = pch_reg_read(dev, PCH_SMBUS_HBD);
}
unlock:
k_mutex_unlock(&data->mutex);
return ret;
}
static const struct smbus_driver_api funcs = {
.configure = pch_configure,
.get_config = pch_get_config,
@ -729,6 +779,7 @@ static const struct smbus_driver_api funcs = {
.smbus_pcall = pch_smbus_pcall,
.smbus_block_write = pch_smbus_block_write,
.smbus_block_read = pch_smbus_block_read,
.smbus_block_pcall = pch_smbus_block_pcall,
};
static void smbus_isr(const struct device *dev)

View file

@ -128,3 +128,17 @@ static inline int z_vrfy_smbus_block_read(const struct device *dev,
return z_impl_smbus_block_read(dev, addr, cmd, count, buf);
}
#include <syscalls/smbus_block_read_mrsh.c>
static inline int z_vrfy_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)
{
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS));
Z_OOPS(Z_SYSCALL_MEMORY_READ(snd_buf, snd_count));
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(rcv_count, sizeof(uint8_t)));
return z_impl_smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf,
rcv_count, rcv_buf);
}
#include <syscalls/smbus_block_pcall_mrsh.c>