summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorIwona Winiarska <iwona.winiarska@intel.com>2022-02-20 01:40:02 +0300
committerIwona Winiarska <iwona.winiarska@intel.com>2022-04-12 14:07:34 +0300
commitbcc82f5f230e4ad36c928f0d2caf93eeb58aa64c (patch)
treefbef76dcdaa17032110b0405fd1c20ab10956b1c /include
parent5da20cec3542029f8bee7ea3855bab90bb96a242 (diff)
downloadlinux-bcc82f5f230e4ad36c928f0d2caf93eeb58aa64c.tar.xz
i3c: Add I3C target support
Extend the existing core implementation with I3C target support. Add missing I3C target driver API. Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/i3c/device.h9
-rw-r--r--include/linux/i3c/master.h23
-rw-r--r--include/linux/i3c/target.h23
3 files changed, 55 insertions, 0 deletions
diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h
index c31624535fbf..e632941575bd 100644
--- a/include/linux/i3c/device.h
+++ b/include/linux/i3c/device.h
@@ -179,6 +179,7 @@ struct i3c_driver {
int (*probe)(struct i3c_device *dev);
void (*remove)(struct i3c_device *dev);
const struct i3c_device_id *id_table;
+ bool target;
};
static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv)
@@ -294,6 +295,8 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev,
struct i3c_priv_xfer *xfers,
int nxfers);
+int i3c_device_generate_ibi(struct i3c_device *dev, const u8 *data, int len);
+
void i3c_device_get_info(struct i3c_device *dev, struct i3c_device_info *info);
struct i3c_ibi_payload {
@@ -335,4 +338,10 @@ int i3c_device_disable_ibi(struct i3c_device *dev);
int i3c_device_getstatus_ccc(struct i3c_device *dev, struct i3c_device_info *info);
+struct i3c_target_read_setup {
+ void (*handler)(struct i3c_device *dev, const u8 *data, size_t len);
+};
+
+int i3c_target_read_register(struct i3c_device *dev, const struct i3c_target_read_setup *setup);
+
#endif /* I3C_DEV_H */
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index 11cdcc062b3e..5d35a6d1c992 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -22,6 +22,7 @@
#define I3C_BROADCAST_ADDR 0x7e
#define I3C_MAX_ADDR GENMASK(6, 0)
+struct i3c_target_ops;
struct i3c_master_controller;
struct i3c_bus;
struct i2c_device;
@@ -185,10 +186,20 @@ struct i3c_dev_boardinfo {
};
/**
+ * struct i3c_target_info - target information attached to a specific device
+ * @read handler: handler specified at i3c_target_read_register() call time.
+ */
+
+struct i3c_target_info {
+ void (*read_handler)(struct i3c_device *dev, const u8 *data, size_t len);
+};
+
+/**
* struct i3c_dev_desc - I3C device descriptor
* @common: common part of the I3C device descriptor
* @info: I3C device information. Will be automatically filled when you create
* your device with i3c_master_add_i3c_dev_locked()
+ * @target_info: I3C target information.
* @ibi_lock: lock used to protect the &struct_i3c_device->ibi
* @ibi: IBI info attached to a device. Should be NULL until
* i3c_device_request_ibi() is called
@@ -207,6 +218,7 @@ struct i3c_dev_boardinfo {
struct i3c_dev_desc {
struct i3c_i2c_dev_desc common;
struct i3c_device_info info;
+ struct i3c_target_info target_info;
struct mutex ibi_lock;
struct i3c_device_ibi_info *ibi;
struct i3c_device *dev;
@@ -463,6 +475,8 @@ struct i3c_master_controller_ops {
* registered to the I2C subsystem to be as transparent as possible to
* existing I2C drivers
* @ops: master operations. See &struct i3c_master_controller_ops
+ * @target_ops: target operations. See &struct i3c_target_ops
+ * @target: true if the underlying I3C device acts as a target on I3C bus
* @secondary: true if the master is a secondary master
* @init_done: true when the bus initialization is done
* @boardinfo.i3c: list of I3C boardinfo objects
@@ -485,6 +499,8 @@ struct i3c_master_controller {
struct i3c_dev_desc *this;
struct i2c_adapter i2c;
const struct i3c_master_controller_ops *ops;
+ const struct i3c_target_ops *target_ops;
+ unsigned int target : 1;
unsigned int secondary : 1;
unsigned int init_done : 1;
unsigned int jdec_spd : 1;
@@ -545,6 +561,13 @@ int i3c_master_register(struct i3c_master_controller *master,
bool secondary);
int i3c_master_unregister(struct i3c_master_controller *master);
+int i3c_register(struct i3c_master_controller *master,
+ struct device *parent,
+ const struct i3c_master_controller_ops *master_ops,
+ const struct i3c_target_ops *target_ops,
+ bool secondary);
+int i3c_unregister(struct i3c_master_controller *master);
+
/**
* i3c_dev_get_master_data() - get master private data attached to an I3C
* device descriptor
diff --git a/include/linux/i3c/target.h b/include/linux/i3c/target.h
new file mode 100644
index 000000000000..9e71124b5325
--- /dev/null
+++ b/include/linux/i3c/target.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2022, Intel Corporation */
+
+#ifndef I3C_TARGET_H
+#define I3C_TARGET_H
+
+#include <linux/device.h>
+#include <linux/i3c/device.h>
+
+struct i3c_master_controller;
+
+struct i3c_target_ops {
+ int (*bus_init)(struct i3c_master_controller *master);
+ void (*bus_cleanup)(struct i3c_master_controller *master);
+ int (*priv_xfers)(struct i3c_dev_desc *dev, struct i3c_priv_xfer *xfers, int nxfers);
+ int (*generate_ibi)(struct i3c_dev_desc *dev, const u8 *data, int len);
+};
+
+int i3c_target_register(struct i3c_master_controller *master, struct device *parent,
+ const struct i3c_target_ops *ops);
+int i3c_target_unregister(struct i3c_master_controller *master);
+
+#endif