1 /*
2 * Copyright (c) 2024 Texas Instruments Incorporated
3 * Andrew Davis <afd@ti.com>
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT zephyr_mbox_ipm
9
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/ipm.h>
13 #include <zephyr/drivers/mbox.h>
14
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(ipm_mbox, CONFIG_IPM_LOG_LEVEL);
17
18 struct ipm_mbox_data {
19 ipm_callback_t callback;
20 void *user_data;
21 };
22
23 struct ipm_mbox_config {
24 struct mbox_dt_spec mbox_tx;
25 struct mbox_dt_spec mbox_rx;
26 };
27
ipm_mbox_callback(const struct device * mboxdev,mbox_channel_id_t channel_id,void * user_data,struct mbox_msg * data)28 static void ipm_mbox_callback(const struct device *mboxdev, mbox_channel_id_t channel_id,
29 void *user_data, struct mbox_msg *data)
30 {
31 const struct device *ipmdev = user_data;
32 struct ipm_mbox_data *ipm_mbox_data = ipmdev->data;
33
34 ipm_mbox_data->callback(ipmdev, ipm_mbox_data->user_data, channel_id, (void *)data->data);
35 }
36
ipm_mbox_send(const struct device * ipmdev,int wait,uint32_t id,const void * data,int size)37 static int ipm_mbox_send(const struct device *ipmdev, int wait, uint32_t id,
38 const void *data, int size)
39 {
40 const struct ipm_mbox_config *config = ipmdev->config;
41
42 struct mbox_msg message = {
43 .data = data,
44 .size = size,
45 };
46
47 return mbox_send_dt(&config->mbox_tx, &message);
48 }
49
ipm_mbox_register_callback(const struct device * ipmdev,ipm_callback_t cb,void * user_data)50 static void ipm_mbox_register_callback(const struct device *ipmdev,
51 ipm_callback_t cb,
52 void *user_data)
53 {
54 struct ipm_mbox_data *data = ipmdev->data;
55
56 data->callback = cb;
57 data->user_data = user_data;
58 }
59
ipm_mbox_get_max_data_size(const struct device * ipmdev)60 static int ipm_mbox_get_max_data_size(const struct device *ipmdev)
61 {
62 const struct ipm_mbox_config *config = ipmdev->config;
63
64 return mbox_mtu_get_dt(&config->mbox_tx);
65 }
66
ipm_mbox_get_max_id(const struct device * ipmdev)67 static uint32_t ipm_mbox_get_max_id(const struct device *ipmdev)
68 {
69 const struct ipm_mbox_config *config = ipmdev->config;
70
71 return mbox_max_channels_get_dt(&config->mbox_tx);
72 }
73
ipm_mbox_set_enable(const struct device * ipmdev,int enable)74 static int ipm_mbox_set_enable(const struct device *ipmdev, int enable)
75 {
76 const struct ipm_mbox_config *config = ipmdev->config;
77
78 mbox_set_enabled_dt(&config->mbox_rx, enable);
79
80 return 0;
81 }
82
ipm_mbox_init(const struct device * ipmdev)83 static int ipm_mbox_init(const struct device *ipmdev)
84 {
85 const struct ipm_mbox_config *config = ipmdev->config;
86
87 mbox_register_callback_dt(&config->mbox_rx, ipm_mbox_callback, (void *)ipmdev);
88
89 return 0;
90 }
91
92 static DEVICE_API(ipm, ipm_mbox_funcs) = {
93 .send = ipm_mbox_send,
94 .register_callback = ipm_mbox_register_callback,
95 .max_data_size_get = ipm_mbox_get_max_data_size,
96 .max_id_val_get = ipm_mbox_get_max_id,
97 .set_enabled = ipm_mbox_set_enable,
98 };
99
100 #define IPM_MBOX_DEV_DEFINE(n) \
101 static struct ipm_mbox_data ipm_mbox_data_##n; \
102 static const struct ipm_mbox_config ipm_mbox_config_##n = { \
103 .mbox_tx = MBOX_DT_SPEC_INST_GET(n, tx), \
104 .mbox_rx = MBOX_DT_SPEC_INST_GET(n, rx), \
105 }; \
106 DEVICE_DT_INST_DEFINE(n, \
107 &ipm_mbox_init, \
108 NULL, \
109 &ipm_mbox_data_##n, \
110 &ipm_mbox_config_##n, \
111 POST_KERNEL, \
112 CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
113 &ipm_mbox_funcs);
114
115 DT_INST_FOREACH_STATUS_OKAY(IPM_MBOX_DEV_DEFINE)
116