summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed/0005-Add-sample-i3c-slave-driver.patch
blob: 8f548c2e508c6fd3819d074eb4cc05f069c7f5b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
From 4987202965423fafd5c704d4e68a51a4167a4414 Mon Sep 17 00:00:00 2001
From: Oleksandr Shulzhenko <oleksandr.shulzhenko.viktorovych@intel.com>
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 <oleksandr.shulzhenko.viktorovych@intel.com>
---
 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 <linux/i3c/device.h>
+#include <linux/module.h>
+
+#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 <oleksandr.shulzhenko.viktorovych@intel.com>");
+MODULE_DESCRIPTION("DesignWare I3C sample driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1