1 /*
2 * Copyright (c) 2019, Henrik Brix Andersen <henrik@brixandersen.dk>
3 *
4 * Based on the i2c_mcux_lpi2c.c driver, which is:
5 * Copyright (c) 2016 Freescale Semiconductor, Inc.
6 * Copyright (c) 2019, NXP
7 *
8 * SPDX-License-Identifier: Apache-2.0
9 */
10
11 #define DT_DRV_COMPAT openisa_rv32m1_lpi2c
12
13 #include <zephyr/drivers/i2c.h>
14 #include <zephyr/drivers/clock_control.h>
15 #include <zephyr/irq.h>
16 #include <fsl_lpi2c.h>
17 #include <zephyr/logging/log.h>
18 #include <zephyr/drivers/pinctrl.h>
19
20 LOG_MODULE_REGISTER(rv32m1_lpi2c);
21
22 #include "i2c-priv.h"
23
24 struct rv32m1_lpi2c_config {
25 LPI2C_Type *base;
26 const struct device *clock_dev;
27 clock_control_subsys_t clock_subsys;
28 clock_ip_name_t clock_ip_name;
29 uint32_t clock_ip_src;
30 uint32_t bitrate;
31 void (*irq_config_func)(const struct device *dev);
32 const struct pinctrl_dev_config *pincfg;
33 };
34
35 struct rv32m1_lpi2c_data {
36 lpi2c_master_handle_t handle;
37 struct k_sem transfer_sync;
38 struct k_sem completion_sync;
39 status_t completion_status;
40 };
41
rv32m1_lpi2c_configure(const struct device * dev,uint32_t dev_config)42 static int rv32m1_lpi2c_configure(const struct device *dev,
43 uint32_t dev_config)
44 {
45 const struct rv32m1_lpi2c_config *config = dev->config;
46 uint32_t baudrate;
47 uint32_t clk_freq;
48 int err;
49
50 if (!(I2C_MODE_CONTROLLER & dev_config)) {
51 /* Slave mode not supported - yet */
52 LOG_ERR("Slave mode not supported");
53 return -ENOTSUP;
54 }
55
56 if (I2C_ADDR_10_BITS & dev_config) {
57 /* FSL LPI2C driver only supports 7-bit addressing */
58 LOG_ERR("10 bit addressing not supported");
59 return -ENOTSUP;
60 }
61
62 switch (I2C_SPEED_GET(dev_config)) {
63 case I2C_SPEED_STANDARD:
64 baudrate = KHZ(100);
65 break;
66 case I2C_SPEED_FAST:
67 baudrate = KHZ(400);
68 break;
69 case I2C_SPEED_FAST_PLUS:
70 baudrate = MHZ(1);
71 break;
72 /* TODO: only if SCL pin implements current source pull-up */
73 /* case I2C_SPEED_HIGH: */
74 /* baudrate = KHZ(3400); */
75 /* break; */
76 /* TODO: ultra-fast requires pin_config setting */
77 /* case I2C_SPEED_ULTRA: */
78 /* baudrate = MHZ(5); */
79 /* break; */
80 default:
81 LOG_ERR("Unsupported speed");
82 return -ENOTSUP;
83 }
84
85 err = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clk_freq);
86 if (err) {
87 LOG_ERR("Could not get clock frequency (err %d)", err);
88 return -EINVAL;
89 }
90
91 LPI2C_MasterSetBaudRate(config->base, clk_freq, baudrate);
92
93 return 0;
94 }
95
rv32m1_lpi2c_master_transfer_callback(LPI2C_Type * base,lpi2c_master_handle_t * handle,status_t completionStatus,void * userData)96 static void rv32m1_lpi2c_master_transfer_callback(LPI2C_Type *base,
97 lpi2c_master_handle_t *handle,
98 status_t completionStatus,
99 void *userData)
100 {
101 struct rv32m1_lpi2c_data *data = userData;
102
103 ARG_UNUSED(base);
104 ARG_UNUSED(handle);
105
106 data->completion_status = completionStatus;
107 k_sem_give(&data->completion_sync);
108 }
109
rv32m1_lpi2c_convert_flags(int msg_flags)110 static uint32_t rv32m1_lpi2c_convert_flags(int msg_flags)
111 {
112 uint32_t flags = 0U;
113
114 if (!(msg_flags & I2C_MSG_STOP)) {
115 flags |= kLPI2C_TransferNoStopFlag;
116 }
117
118 if (msg_flags & I2C_MSG_RESTART) {
119 flags |= kLPI2C_TransferRepeatedStartFlag;
120 }
121
122 return flags;
123 }
124
rv32m1_lpi2c_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)125 static int rv32m1_lpi2c_transfer(const struct device *dev,
126 struct i2c_msg *msgs,
127 uint8_t num_msgs, uint16_t addr)
128 {
129 const struct rv32m1_lpi2c_config *config = dev->config;
130 struct rv32m1_lpi2c_data *data = dev->data;
131 lpi2c_master_transfer_t transfer;
132 status_t status;
133 int ret = 0;
134
135 k_sem_take(&data->transfer_sync, K_FOREVER);
136
137 /* Iterate over all the messages */
138 for (int i = 0; i < num_msgs; i++) {
139 if (I2C_MSG_ADDR_10_BITS & msgs->flags) {
140 ret = -ENOTSUP;
141 goto out;
142 }
143
144 /* Initialize the transfer descriptor */
145 transfer.flags = rv32m1_lpi2c_convert_flags(msgs->flags);
146
147 /* Prevent the controller to send a start condition between
148 * messages, except if explicitly requested.
149 */
150 if (i != 0 && !(msgs->flags & I2C_MSG_RESTART)) {
151 transfer.flags |= kLPI2C_TransferNoStartFlag;
152 }
153
154 transfer.slaveAddress = addr;
155 transfer.direction = (msgs->flags & I2C_MSG_READ)
156 ? kLPI2C_Read : kLPI2C_Write;
157 transfer.subaddress = 0;
158 transfer.subaddressSize = 0;
159 transfer.data = msgs->buf;
160 transfer.dataSize = msgs->len;
161
162 /* Start the transfer */
163 status = LPI2C_MasterTransferNonBlocking(config->base,
164 &data->handle,
165 &transfer);
166
167 /* Return an error if the transfer didn't start successfully
168 * e.g., if the bus was busy
169 */
170 if (status != kStatus_Success) {
171 LOG_DBG("Could not start transfer (status %d)", status);
172 ret = -EIO;
173 goto out;
174 }
175
176 /* Wait for the transfer to complete */
177 k_sem_take(&data->completion_sync, K_FOREVER);
178
179 /* Return an error if the transfer didn't complete
180 * successfully. e.g., nak, timeout, lost arbitration
181 */
182 if (data->completion_status != kStatus_Success) {
183 LOG_DBG("Transfer failed (status %d)",
184 data->completion_status);
185 LPI2C_MasterTransferAbort(config->base, &data->handle);
186 ret = -EIO;
187 goto out;
188 }
189
190 /* Move to the next message */
191 msgs++;
192 }
193
194 out:
195 k_sem_give(&data->transfer_sync);
196 return ret;
197 }
198
rv32m1_lpi2c_isr(const struct device * dev)199 static void rv32m1_lpi2c_isr(const struct device *dev)
200 {
201 const struct rv32m1_lpi2c_config *config = dev->config;
202 struct rv32m1_lpi2c_data *data = dev->data;
203
204 LPI2C_MasterTransferHandleIRQ(config->base, &data->handle);
205 }
206
rv32m1_lpi2c_init(const struct device * dev)207 static int rv32m1_lpi2c_init(const struct device *dev)
208 {
209 const struct rv32m1_lpi2c_config *config = dev->config;
210 struct rv32m1_lpi2c_data *data = dev->data;
211 lpi2c_master_config_t master_config;
212 uint32_t clk_freq, dev_cfg;
213 int err;
214
215 CLOCK_SetIpSrc(config->clock_ip_name, config->clock_ip_src);
216
217 if (!device_is_ready(config->clock_dev)) {
218 LOG_ERR("clock control device not ready");
219 return -ENODEV;
220 }
221
222 err = clock_control_on(config->clock_dev, config->clock_subsys);
223 if (err) {
224 LOG_ERR("Could not turn on clock (err %d)", err);
225 return -EINVAL;
226 }
227
228 err = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clk_freq);
229 if (err) {
230 LOG_ERR("Could not get clock frequency (err %d)", err);
231 return -EINVAL;
232 }
233
234 LPI2C_MasterGetDefaultConfig(&master_config);
235 LPI2C_MasterInit(config->base, &master_config, clk_freq);
236 LPI2C_MasterTransferCreateHandle(config->base, &data->handle,
237 rv32m1_lpi2c_master_transfer_callback,
238 data);
239
240 dev_cfg = i2c_map_dt_bitrate(config->bitrate);
241 err = rv32m1_lpi2c_configure(dev, dev_cfg | I2C_MODE_CONTROLLER);
242 if (err) {
243 LOG_ERR("Could not configure controller (err %d)", err);
244 return err;
245 }
246
247 err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
248 if (err != 0) {
249 return err;
250 }
251
252 config->irq_config_func(dev);
253
254 return 0;
255 }
256
257 static const struct i2c_driver_api rv32m1_lpi2c_driver_api = {
258 .configure = rv32m1_lpi2c_configure,
259 .transfer = rv32m1_lpi2c_transfer,
260 };
261
262 #define RV32M1_LPI2C_DEVICE(id) \
263 PINCTRL_DT_INST_DEFINE(id); \
264 static void rv32m1_lpi2c_irq_config_func_##id(const struct device *dev); \
265 static const struct rv32m1_lpi2c_config rv32m1_lpi2c_##id##_config = { \
266 .base = \
267 (LPI2C_Type *)DT_INST_REG_ADDR(id), \
268 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \
269 .clock_subsys = \
270 (clock_control_subsys_t) DT_INST_CLOCKS_CELL(id, name),\
271 .clock_ip_name = INST_DT_CLOCK_IP_NAME(id), \
272 .clock_ip_src = kCLOCK_IpSrcFircAsync, \
273 .bitrate = DT_INST_PROP(id, clock_frequency), \
274 .irq_config_func = rv32m1_lpi2c_irq_config_func_##id, \
275 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \
276 }; \
277 static struct rv32m1_lpi2c_data rv32m1_lpi2c_##id##_data = { \
278 .transfer_sync = Z_SEM_INITIALIZER( \
279 rv32m1_lpi2c_##id##_data.transfer_sync, 1, 1), \
280 .completion_sync = Z_SEM_INITIALIZER( \
281 rv32m1_lpi2c_##id##_data.completion_sync, 0, 1), \
282 }; \
283 I2C_DEVICE_DT_INST_DEFINE(id, \
284 rv32m1_lpi2c_init, \
285 NULL, \
286 &rv32m1_lpi2c_##id##_data, \
287 &rv32m1_lpi2c_##id##_config, \
288 POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
289 &rv32m1_lpi2c_driver_api); \
290 static void rv32m1_lpi2c_irq_config_func_##id(const struct device *dev) \
291 { \
292 IRQ_CONNECT(DT_INST_IRQN(id), \
293 0, \
294 rv32m1_lpi2c_isr, DEVICE_DT_INST_GET(id), \
295 0); \
296 irq_enable(DT_INST_IRQN(id)); \
297 } \
298
299 DT_INST_FOREACH_STATUS_OKAY(RV32M1_LPI2C_DEVICE)
300