1 /*
2  * Copyright (c) 2016 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT nxp_kinetis_i2c
8 
9 #include <errno.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/kernel.h>
12 #include <soc.h>
13 #include <fsl_i2c.h>
14 #include <fsl_clock.h>
15 #include <zephyr/sys/util.h>
16 
17 #include <zephyr/drivers/pinctrl.h>
18 
19 #include <zephyr/logging/log.h>
20 #include <zephyr/irq.h>
21 LOG_MODULE_REGISTER(i2c_mcux);
22 
23 #include "i2c-priv.h"
24 
25 #define DEV_BASE(dev) \
26 	((I2C_Type *)((const struct i2c_mcux_config * const)(dev)->config)->base)
27 
28 struct i2c_mcux_config {
29 	I2C_Type *base;
30 	clock_name_t clock_source;
31 	void (*irq_config_func)(const struct device *dev);
32 	uint32_t bitrate;
33 	const struct pinctrl_dev_config *pincfg;
34 };
35 
36 struct i2c_mcux_data {
37 	i2c_master_handle_t handle;
38 	struct k_sem lock;
39 	struct k_sem device_sync_sem;
40 	status_t callback_status;
41 #ifdef CONFIG_I2C_CALLBACK
42 	uint16_t addr;
43 	uint32_t msg;
44 	struct i2c_msg *msgs;
45 	uint32_t num_msgs;
46 	i2c_callback_t cb;
47 	void *userdata;
48 #endif /* CONFIG_I2C_CALLBACK */
49 };
50 
i2c_mcux_configure(const struct device * dev,uint32_t dev_config_raw)51 static int i2c_mcux_configure(const struct device *dev,
52 			      uint32_t dev_config_raw)
53 {
54 	I2C_Type *base = DEV_BASE(dev);
55 	struct i2c_mcux_data *data = dev->data;
56 	const struct i2c_mcux_config *config = dev->config;
57 	uint32_t clock_freq;
58 	uint32_t baudrate;
59 
60 	if (!(I2C_MODE_CONTROLLER & dev_config_raw)) {
61 		return -EINVAL;
62 	}
63 
64 	if (I2C_ADDR_10_BITS & dev_config_raw) {
65 		return -EINVAL;
66 	}
67 
68 	switch (I2C_SPEED_GET(dev_config_raw)) {
69 	case I2C_SPEED_STANDARD:
70 		baudrate = KHZ(100);
71 		break;
72 	case I2C_SPEED_FAST:
73 		baudrate = KHZ(400);
74 		break;
75 	case I2C_SPEED_FAST_PLUS:
76 		baudrate = MHZ(1);
77 		break;
78 	default:
79 		return -EINVAL;
80 	}
81 
82 	clock_freq = CLOCK_GetFreq(config->clock_source);
83 	k_sem_take(&data->lock, K_FOREVER);
84 	I2C_MasterSetBaudRate(base, baudrate, clock_freq);
85 	k_sem_give(&data->lock);
86 
87 	return 0;
88 }
89 
90 #ifdef CONFIG_I2C_CALLBACK
91 
92 static void i2c_mcux_async_done(const struct device *dev, struct i2c_mcux_data *data, int result);
93 static void i2c_mcux_async_iter(const struct device *dev);
94 
95 #endif
96 
i2c_mcux_master_transfer_callback(I2C_Type * base,i2c_master_handle_t * handle,status_t status,void * userdata)97 static void i2c_mcux_master_transfer_callback(I2C_Type *base,
98 					      i2c_master_handle_t *handle,
99 					      status_t status, void *userdata)
100 {
101 
102 	ARG_UNUSED(handle);
103 	ARG_UNUSED(base);
104 
105 	struct device *dev = userdata;
106 	struct i2c_mcux_data *data = dev->data;
107 
108 	#ifdef CONFIG_I2C_CALLBACK
109 	if (data->cb != NULL) {
110 		/* Async transfer */
111 		if (status != kStatus_Success) {
112 			I2C_MasterTransferAbort(base, &data->handle);
113 			i2c_mcux_async_done(dev, data, -EIO);
114 		} else if (data->msg == data->num_msgs - 1) {
115 			i2c_mcux_async_done(dev, data, 0);
116 		} else {
117 			data->msg++;
118 			i2c_mcux_async_iter(dev);
119 		}
120 		return;
121 	}
122 	#endif /* CONFIG_I2C_CALLBACK */
123 
124 	data->callback_status = status;
125 
126 	k_sem_give(&data->device_sync_sem);
127 }
128 
i2c_mcux_convert_flags(int msg_flags)129 static uint32_t i2c_mcux_convert_flags(int msg_flags)
130 {
131 	uint32_t flags = 0U;
132 
133 	if (!(msg_flags & I2C_MSG_STOP)) {
134 		flags |= kI2C_TransferNoStopFlag;
135 	}
136 
137 	if (msg_flags & I2C_MSG_RESTART) {
138 		flags |= kI2C_TransferRepeatedStartFlag;
139 	}
140 
141 	return flags;
142 }
143 
i2c_mcux_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)144 static int i2c_mcux_transfer(const struct device *dev, struct i2c_msg *msgs,
145 			     uint8_t num_msgs, uint16_t addr)
146 {
147 	I2C_Type *base = DEV_BASE(dev);
148 	struct i2c_mcux_data *data = dev->data;
149 	i2c_master_transfer_t transfer;
150 	status_t status;
151 	int ret = 0;
152 
153 	k_sem_take(&data->lock, K_FOREVER);
154 
155 	/* Iterate over all the messages */
156 	for (int i = 0; i < num_msgs; i++) {
157 		if (I2C_MSG_ADDR_10_BITS & msgs->flags) {
158 			ret = -ENOTSUP;
159 			break;
160 		}
161 
162 		/* Initialize the transfer descriptor */
163 		transfer.flags = i2c_mcux_convert_flags(msgs->flags);
164 		transfer.slaveAddress = addr;
165 		transfer.direction = (msgs->flags & I2C_MSG_READ)
166 			? kI2C_Read : kI2C_Write;
167 		transfer.subaddress = 0;
168 		transfer.subaddressSize = 0;
169 		transfer.data = msgs->buf;
170 		transfer.dataSize = msgs->len;
171 
172 		/* Prevent the controller to send a start condition between
173 		 * messages, except if explicitly requested.
174 		 */
175 		if (i != 0 && !(msgs->flags & I2C_MSG_RESTART)) {
176 			transfer.flags |= kI2C_TransferNoStartFlag;
177 		}
178 
179 		/* Start the transfer */
180 		status = I2C_MasterTransferNonBlocking(base,
181 				&data->handle, &transfer);
182 
183 		/* Return an error if the transfer didn't start successfully
184 		 * e.g., if the bus was busy
185 		 */
186 		if (status != kStatus_Success) {
187 			I2C_MasterTransferAbort(base, &data->handle);
188 			ret = -EIO;
189 			break;
190 		}
191 
192 		/* Wait for the transfer to complete */
193 		k_sem_take(&data->device_sync_sem, K_FOREVER);
194 
195 		/* Return an error if the transfer didn't complete
196 		 * successfully. e.g., nak, timeout, lost arbitration
197 		 */
198 		if (data->callback_status != kStatus_Success) {
199 			I2C_MasterTransferAbort(base, &data->handle);
200 			ret = -EIO;
201 			break;
202 		}
203 
204 		/* Move to the next message */
205 		msgs++;
206 	}
207 
208 	k_sem_give(&data->lock);
209 
210 	return ret;
211 }
212 
213 #ifdef CONFIG_I2C_CALLBACK
214 
i2c_mcux_async_done(const struct device * dev,struct i2c_mcux_data * data,int result)215 static void i2c_mcux_async_done(const struct device *dev, struct i2c_mcux_data *data, int result)
216 {
217 
218 	i2c_callback_t cb = data->cb;
219 	void *userdata = data->userdata;
220 
221 	data->msg = 0;
222 	data->msgs = NULL;
223 	data->num_msgs = 0;
224 	data->cb = NULL;
225 	data->userdata = NULL;
226 	data->addr = 0;
227 
228 	k_sem_give(&data->lock);
229 
230 	/* Callback may wish to start another transfer */
231 	cb(dev, result, userdata);
232 }
233 
234 /* Start a transfer asynchronously */
i2c_mcux_async_iter(const struct device * dev)235 static void i2c_mcux_async_iter(const struct device *dev)
236 {
237 	I2C_Type *base = DEV_BASE(dev);
238 	struct i2c_mcux_data *data = dev->data;
239 	i2c_master_transfer_t transfer;
240 	status_t status;
241 	struct i2c_msg *msg = &data->msgs[data->msg];
242 
243 	if (I2C_MSG_ADDR_10_BITS & msg->flags) {
244 		i2c_mcux_async_done(dev, data, -ENOTSUP);
245 		return;
246 	}
247 
248 	/* Initialize the transfer descriptor */
249 	transfer.flags = i2c_mcux_convert_flags(msg->flags);
250 	transfer.slaveAddress = data->addr;
251 	transfer.direction = (msg->flags & I2C_MSG_READ) ? kI2C_Read : kI2C_Write;
252 	transfer.subaddress = 0;
253 	transfer.subaddressSize = 0;
254 	transfer.data = msg->buf;
255 	transfer.dataSize = msg->len;
256 
257 	/* Prevent the controller to send a start condition between
258 	 * messages, except if explicitly requested.
259 	 */
260 	if (data->msg != 0 && !(msg->flags & I2C_MSG_RESTART)) {
261 		transfer.flags |= kI2C_TransferNoStartFlag;
262 	}
263 
264 	/* Start the transfer */
265 	status = I2C_MasterTransferNonBlocking(base, &data->handle, &transfer);
266 
267 	/* Return an error if the transfer didn't start successfully
268 	 * e.g., if the bus was busy
269 	 */
270 	if (status != kStatus_Success) {
271 		I2C_MasterTransferAbort(base, &data->handle);
272 		i2c_mcux_async_done(dev, data, -EIO);
273 	}
274 }
275 
i2c_mcux_transfer_cb(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr,i2c_callback_t cb,void * userdata)276 static int i2c_mcux_transfer_cb(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs,
277 				   uint16_t addr, i2c_callback_t cb, void *userdata)
278 {
279 	struct i2c_mcux_data *data = dev->data;
280 
281 	int res = k_sem_take(&data->lock, K_NO_WAIT);
282 
283 	if (res != 0) {
284 		return -EWOULDBLOCK;
285 	}
286 
287 	data->msg = 0;
288 	data->msgs = msgs;
289 	data->num_msgs = num_msgs;
290 	data->addr = addr;
291 	data->cb = cb;
292 	data->userdata = userdata;
293 	data->addr = addr;
294 
295 	i2c_mcux_async_iter(dev);
296 
297 	return 0;
298 }
299 
300 #endif /* CONFIG_I2C_CALLBACK */
301 
i2c_mcux_isr(const struct device * dev)302 static void i2c_mcux_isr(const struct device *dev)
303 {
304 	I2C_Type *base = DEV_BASE(dev);
305 	struct i2c_mcux_data *data = dev->data;
306 
307 	I2C_MasterTransferHandleIRQ(base, &data->handle);
308 }
309 
i2c_mcux_init(const struct device * dev)310 static int i2c_mcux_init(const struct device *dev)
311 {
312 	I2C_Type *base = DEV_BASE(dev);
313 	const struct i2c_mcux_config *config = dev->config;
314 	struct i2c_mcux_data *data = dev->data;
315 	uint32_t clock_freq, bitrate_cfg;
316 	i2c_master_config_t master_config;
317 	int error;
318 
319 	k_sem_init(&data->lock, 1, 1);
320 	k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT);
321 
322 	clock_freq = CLOCK_GetFreq(config->clock_source);
323 	I2C_MasterGetDefaultConfig(&master_config);
324 	I2C_MasterInit(base, &master_config, clock_freq);
325 	I2C_MasterTransferCreateHandle(base, &data->handle,
326 				       i2c_mcux_master_transfer_callback, (void *)dev);
327 
328 	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
329 
330 	error = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
331 	if (error) {
332 		return error;
333 	}
334 
335 	error = i2c_mcux_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
336 	if (error) {
337 		return error;
338 	}
339 
340 	config->irq_config_func(dev);
341 
342 	return 0;
343 }
344 
345 static DEVICE_API(i2c, i2c_mcux_driver_api) = {
346 	.configure = i2c_mcux_configure,
347 	.transfer = i2c_mcux_transfer,
348 #ifdef CONFIG_I2C_CALLBACK
349 	.transfer_cb = i2c_mcux_transfer_cb,
350 #endif
351 #ifdef CONFIG_I2C_RTIO
352 	.iodev_submit = i2c_iodev_submit_fallback,
353 #endif
354 };
355 
356 #define I2C_DEVICE_INIT_MCUX(n)			\
357 	PINCTRL_DT_INST_DEFINE(n);					\
358 									\
359 	static void i2c_mcux_config_func_ ## n(const struct device *dev); \
360 									\
361 	static const struct i2c_mcux_config i2c_mcux_config_ ## n = {	\
362 		.base = (I2C_Type *)DT_INST_REG_ADDR(n),\
363 		.clock_source = I2C ## n ## _CLK_SRC,			\
364 		.irq_config_func = i2c_mcux_config_func_ ## n,		\
365 		.bitrate = DT_INST_PROP(n, clock_frequency),		\
366 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),		\
367 	};								\
368 									\
369 	static struct i2c_mcux_data i2c_mcux_data_ ## n;		\
370 									\
371 	I2C_DEVICE_DT_INST_DEFINE(n,					\
372 			i2c_mcux_init, NULL,				\
373 			&i2c_mcux_data_ ## n,				\
374 			&i2c_mcux_config_ ## n, POST_KERNEL,		\
375 			CONFIG_I2C_INIT_PRIORITY,			\
376 			&i2c_mcux_driver_api);				\
377 									\
378 	static void i2c_mcux_config_func_ ## n(const struct device *dev) \
379 	{								\
380 		IRQ_CONNECT(DT_INST_IRQN(n),				\
381 			DT_INST_IRQ(n, priority),			\
382 			i2c_mcux_isr,					\
383 			DEVICE_DT_INST_GET(n), 0);			\
384 									\
385 		irq_enable(DT_INST_IRQN(n));				\
386 	}
387 
388 DT_INST_FOREACH_STATUS_OKAY(I2C_DEVICE_INIT_MCUX)
389