From 4987202965423fafd5c704d4e68a51a4167a4414 Mon Sep 17 00:00:00 2001 From: Oleksandr Shulzhenko Date: Thu, 30 Sep 2021 16:28:26 +0200 Subject: [PATCH] Add sample i3c slave driver The aim of the driver is to debug various i3c solutions implemented for DesignWare master I3C driver. The driver is bound to the I3C device that corresponds to I3C slave emulated by Prodigy with manufacturer ID 0xAC and part ID 0x55AA. It is enough to fill the I3C_DEVICE macro with the corresponding data to adjust the driver with another I3C slave device Signed-off-by: Oleksandr Shulzhenko --- drivers/i3c/Kconfig | 2 + drivers/i3c/Makefile | 1 + drivers/i3c/sample/Kconfig | 7 +++ drivers/i3c/sample/Makefile | 2 + drivers/i3c/sample/dw-i3c-sample.c | 75 ++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 drivers/i3c/sample/Kconfig create mode 100644 drivers/i3c/sample/Makefile create mode 100644 drivers/i3c/sample/dw-i3c-sample.c diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index 01642768ab5f..202b0d091631 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -36,4 +36,6 @@ config I3CDEV and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. source "drivers/i3c/master/Kconfig" + +source "drivers/i3c/sample/Kconfig" endif # I3C diff --git a/drivers/i3c/Makefile b/drivers/i3c/Makefile index 606d422841b2..8048a9a793c6 100644 --- a/drivers/i3c/Makefile +++ b/drivers/i3c/Makefile @@ -3,3 +3,4 @@ i3c-y := device.o master.o obj-$(CONFIG_I3C) += i3c.o obj-$(CONFIG_I3CDEV) += i3cdev.o obj-$(CONFIG_I3C) += master/ +obj-$(CONFIG_I3C) += sample/ diff --git a/drivers/i3c/sample/Kconfig b/drivers/i3c/sample/Kconfig new file mode 100644 index 000000000000..6376c9891795 --- /dev/null +++ b/drivers/i3c/sample/Kconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +config DW_I3C_SAMPLE + tristate "Synopsys DesignWare I3C sample driver" + depends on I3C +help + Say yes here to enable the driver for DesignWare + I3C Sample driver. diff --git a/drivers/i3c/sample/Makefile b/drivers/i3c/sample/Makefile new file mode 100644 index 000000000000..c73bb34fce0e --- /dev/null +++ b/drivers/i3c/sample/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_DW_I3C_SAMPLE) += dw-i3c-sample.o \ No newline at end of file diff --git a/drivers/i3c/sample/dw-i3c-sample.c b/drivers/i3c/sample/dw-i3c-sample.c new file mode 100644 index 000000000000..1993b9fdb32b --- /dev/null +++ b/drivers/i3c/sample/dw-i3c-sample.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2021 Intel Corporation.*/ + +#include +#include + +#define IBI_QUEUE_STATUS_IBI_ID(x) (((x) & GENMASK(15, 8)) >> 8) +#define IBI_QUEUE_IBI_ADDR(x) (IBI_QUEUE_STATUS_IBI_ID(x) >> 1) +#define IBI_QUEUE_STATUS_DATA_LEN(x) ((x) & GENMASK(7, 0)) + +static void ibi_handler(struct i3c_device *dev, + const struct i3c_ibi_payload *payload) +{ + unsigned int i = 0; + u32 ibi_status; + u8 addr; + const u8 *buf; + + dev_info(i3cdev_to_dev(dev), "%s:%d\n", __func__, __LINE__); + if (payload) { + ibi_status = *((u32 *)payload->data); + addr = IBI_QUEUE_IBI_ADDR(ibi_status); + dev_info(i3cdev_to_dev(dev), "%s, dynamic address = 0x%02x\n", + __func__, addr); + /* We need to read only IBI Paylod data - so shift for IBI_QUEUE_STATUS + * length which is 32 bits + */ + buf = payload->data + sizeof(u32); + for (i = 0; i < IBI_QUEUE_STATUS_DATA_LEN(ibi_status); i++) + dev_info(i3cdev_to_dev(dev), "%s payload[%d] = 0x%02x\n", + __func__, i, *(buf + sizeof(u8) * i)); + } +} + +static int dw_i3c_sample_probe(struct i3c_device *i3cdev) +{ + int ret; + struct i3c_ibi_setup ibireq = { + .handler = ibi_handler, + .max_payload_len = 2, + .num_slots = 10, + }; + + ret = i3c_device_request_ibi(i3cdev, &ibireq); + if (ret) + return ret; + ret = i3c_device_enable_ibi(i3cdev); + if (ret) + i3c_device_free_ibi(i3cdev); + + return ret; +} + +static void dw_i3c_sample_remove(struct i3c_device *i3cdev) +{ + i3c_device_disable_ibi(i3cdev); + i3c_device_free_ibi(i3cdev); +} + +static const struct i3c_device_id dw_i3c_sample_ids[] = { + I3C_DEVICE(0x2AC /*manufid*/, 0x55AA /*partid*/, NULL /*driver-data*/), + { /* sentinel */ }, +}; + +static struct i3c_driver dw_i3c_sample = { + .driver.name = "dw-i3c-sample", + .id_table = dw_i3c_sample_ids, + .probe = dw_i3c_sample_probe, + .remove = dw_i3c_sample_remove, +}; + +module_i3c_driver(dw_i3c_sample); +MODULE_AUTHOR("Oleksandr Shulzhenko "); +MODULE_DESCRIPTION("DesignWare I3C sample driver"); +MODULE_LICENSE("GPL"); -- 2.25.1