1 /*
2  * Copyright (c) 2018 Diego Sueiro, <diego.sueiro@gmail.com>
3  * Copyright 2022 NXP
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT fsl_imx21_i2c
9 
10 #include <errno.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <soc.h>
13 #include <i2c_imx.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/drivers/pinctrl.h>
16 
17 #include <zephyr/logging/log.h>
18 #include <zephyr/irq.h>
19 LOG_MODULE_REGISTER(i2c_imx);
20 
21 #include "i2c-priv.h"
22 
23 #define DEV_BASE(dev) \
24 	((I2C_Type *)((const struct i2c_imx_config * const)(dev)->config)->base)
25 
26 struct i2c_imx_config {
27 	I2C_Type *base;
28 	void (*irq_config_func)(const struct device *dev);
29 	uint32_t bitrate;
30 	const struct pinctrl_dev_config *pincfg;
31 };
32 
33 struct i2c_master_transfer {
34 	const uint8_t     *txBuff;
35 	volatile uint8_t  *rxBuff;
36 	volatile uint32_t	cmdSize;
37 	volatile uint32_t	txSize;
38 	volatile uint32_t	rxSize;
39 	volatile bool	isBusy;
40 	volatile uint32_t	currentDir;
41 	volatile uint32_t	currentMode;
42 	volatile bool	ack;
43 };
44 
45 struct i2c_imx_data {
46 	struct i2c_master_transfer transfer;
47 	struct k_sem device_sync_sem;
48 };
49 
i2c_imx_write(const struct device * dev,uint8_t * txBuffer,uint32_t txSize)50 static bool i2c_imx_write(const struct device *dev, uint8_t *txBuffer,
51 			  uint32_t txSize)
52 {
53 	I2C_Type *base = DEV_BASE(dev);
54 	struct i2c_imx_data *data = dev->data;
55 	struct i2c_master_transfer *transfer = &data->transfer;
56 
57 	transfer->isBusy = true;
58 
59 	/* Clear I2C interrupt flag to avoid spurious interrupt */
60 	I2C_ClearStatusFlag(base, i2cStatusInterrupt);
61 
62 	/* Set I2C work under Tx mode */
63 	I2C_SetDirMode(base, i2cDirectionTransmit);
64 	transfer->currentDir = i2cDirectionTransmit;
65 
66 	transfer->txBuff = txBuffer;
67 	transfer->txSize = txSize;
68 
69 	I2C_WriteByte(base, *transfer->txBuff);
70 	transfer->txBuff++;
71 	transfer->txSize--;
72 
73 	/* Enable I2C interrupt, subsequent data transfer will be handled
74 	 * in ISR.
75 	 */
76 	I2C_SetIntCmd(base, true);
77 
78 	/* Wait for the transfer to complete */
79 	k_sem_take(&data->device_sync_sem, K_FOREVER);
80 
81 	return transfer->ack;
82 }
83 
i2c_imx_read(const struct device * dev,uint8_t * rxBuffer,uint32_t rxSize)84 static void i2c_imx_read(const struct device *dev, uint8_t *rxBuffer,
85 			 uint32_t rxSize)
86 {
87 	I2C_Type *base = DEV_BASE(dev);
88 	struct i2c_imx_data *data = dev->data;
89 	struct i2c_master_transfer *transfer = &data->transfer;
90 
91 	transfer->isBusy = true;
92 
93 	/* Clear I2C interrupt flag to avoid spurious interrupt */
94 	I2C_ClearStatusFlag(base, i2cStatusInterrupt);
95 
96 	/* Change to receive state. */
97 	I2C_SetDirMode(base, i2cDirectionReceive);
98 	transfer->currentDir = i2cDirectionReceive;
99 
100 	transfer->rxBuff = rxBuffer;
101 	transfer->rxSize = rxSize;
102 
103 	if (transfer->rxSize == 1U) {
104 		/* Send Nack */
105 		I2C_SetAckBit(base, false);
106 	} else {
107 		/* Send Ack */
108 		I2C_SetAckBit(base, true);
109 	}
110 
111 	/* dummy read to clock in 1st byte */
112 	I2C_ReadByte(base);
113 
114 	/* Enable I2C interrupt, subsequent data transfer will be handled
115 	 * in ISR.
116 	 */
117 	I2C_SetIntCmd(base, true);
118 
119 	/* Wait for the transfer to complete */
120 	k_sem_take(&data->device_sync_sem, K_FOREVER);
121 
122 }
123 
i2c_imx_configure(const struct device * dev,uint32_t dev_config_raw)124 static int i2c_imx_configure(const struct device *dev,
125 			     uint32_t dev_config_raw)
126 {
127 	I2C_Type *base = DEV_BASE(dev);
128 	struct i2c_imx_data *data = dev->data;
129 	struct i2c_master_transfer *transfer = &data->transfer;
130 	uint32_t baudrate;
131 
132 	if (!(I2C_MODE_CONTROLLER & dev_config_raw)) {
133 		return -EINVAL;
134 	}
135 
136 	if (I2C_ADDR_10_BITS & dev_config_raw) {
137 		return -EINVAL;
138 	}
139 
140 	/* Initialize I2C state structure content. */
141 	transfer->txBuff = 0;
142 	transfer->rxBuff = 0;
143 	transfer->cmdSize = 0U;
144 	transfer->txSize = 0U;
145 	transfer->rxSize = 0U;
146 	transfer->isBusy = false;
147 	transfer->currentDir = i2cDirectionReceive;
148 	transfer->currentMode = i2cModeSlave;
149 
150 	switch (I2C_SPEED_GET(dev_config_raw)) {
151 	case I2C_SPEED_STANDARD:
152 		baudrate = KHZ(100);
153 		break;
154 	case I2C_SPEED_FAST:
155 		baudrate = KHZ(400);
156 		break;
157 	case I2C_SPEED_FAST_PLUS:
158 		baudrate = MHZ(1);
159 		break;
160 	default:
161 		return -EINVAL;
162 	}
163 
164 	/* Setup I2C init structure. */
165 	i2c_init_config_t i2cInitConfig = {
166 		.baudRate	  = baudrate,
167 		.slaveAddress = 0x00
168 	};
169 
170 	i2cInitConfig.clockRate = get_i2c_clock_freq(base);
171 
172 	I2C_Init(base, &i2cInitConfig);
173 
174 	I2C_Enable(base);
175 
176 	return 0;
177 }
178 
i2c_imx_send_addr(const struct device * dev,uint16_t addr,uint8_t flags)179 static int i2c_imx_send_addr(const struct device *dev, uint16_t addr,
180 			     uint8_t flags)
181 {
182 	uint8_t byte0 = addr << 1;
183 
184 	byte0 |= (flags & I2C_MSG_RW_MASK) == I2C_MSG_READ;
185 	return i2c_imx_write(dev, &byte0, 1);
186 }
187 
i2c_imx_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)188 static int i2c_imx_transfer(const struct device *dev, struct i2c_msg *msgs,
189 			    uint8_t num_msgs, uint16_t addr)
190 {
191 	I2C_Type *base = DEV_BASE(dev);
192 	struct i2c_imx_data *data = dev->data;
193 	struct i2c_master_transfer *transfer = &data->transfer;
194 	uint16_t timeout = UINT16_MAX;
195 	int result = -EIO;
196 
197 	if (!num_msgs) {
198 		return 0;
199 	}
200 
201 	/* Wait until bus not busy */
202 	while ((I2C_I2SR_REG(base) & i2cStatusBusBusy) && (--timeout)) {
203 	}
204 
205 	if (timeout == 0U) {
206 		return result;
207 	}
208 
209 	/* Make sure we're in a good state so slave recognises the Start */
210 	I2C_SetWorkMode(base, i2cModeSlave);
211 	transfer->currentMode = i2cModeSlave;
212 	/* Switch back to Rx direction. */
213 	I2C_SetDirMode(base, i2cDirectionReceive);
214 	transfer->currentDir = i2cDirectionReceive;
215 	/* Start condition */
216 	I2C_SetDirMode(base, i2cDirectionTransmit);
217 	transfer->currentDir = i2cDirectionTransmit;
218 	I2C_SetWorkMode(base, i2cModeMaster);
219 	transfer->currentMode = i2cModeMaster;
220 
221 	/* Send address after any Start condition */
222 	if (!i2c_imx_send_addr(dev, addr, msgs->flags)) {
223 		goto finish; /* No ACK received */
224 	}
225 
226 	do {
227 		if (msgs->flags & I2C_MSG_RESTART) {
228 			I2C_SendRepeatStart(base);
229 			if (!i2c_imx_send_addr(dev, addr, msgs->flags)) {
230 				goto finish; /* No ACK received */
231 			}
232 		}
233 
234 		/* Transfer data */
235 		if (msgs->len) {
236 			if ((msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
237 				i2c_imx_read(dev, msgs->buf, msgs->len);
238 			} else {
239 				if (!i2c_imx_write(dev, msgs->buf, msgs->len)) {
240 					goto finish; /* No ACK received */
241 				}
242 			}
243 		}
244 
245 		if (msgs->flags & I2C_MSG_STOP) {
246 			I2C_SetWorkMode(base, i2cModeSlave);
247 			transfer->currentMode = i2cModeSlave;
248 			I2C_SetDirMode(base, i2cDirectionReceive);
249 			transfer->currentDir = i2cDirectionReceive;
250 		}
251 
252 		/* Next message */
253 		msgs++;
254 		num_msgs--;
255 	} while (num_msgs);
256 
257 	/* Complete without error */
258 	result = 0;
259 	return result;
260 
261 finish:
262 	I2C_SetWorkMode(base, i2cModeSlave);
263 	transfer->currentMode = i2cModeSlave;
264 	I2C_SetDirMode(base, i2cDirectionReceive);
265 	transfer->currentDir = i2cDirectionReceive;
266 
267 	return result;
268 }
269 
270 
i2c_imx_isr(const struct device * dev)271 static void i2c_imx_isr(const struct device *dev)
272 {
273 	I2C_Type *base = DEV_BASE(dev);
274 	struct i2c_imx_data *data = dev->data;
275 	struct i2c_master_transfer *transfer = &data->transfer;
276 
277 	/* Clear interrupt flag. */
278 	I2C_ClearStatusFlag(base, i2cStatusInterrupt);
279 
280 
281 	/* Exit the ISR if no transfer is happening for this instance. */
282 	if (!transfer->isBusy) {
283 		return;
284 	}
285 
286 	if (i2cModeMaster == transfer->currentMode) {
287 		if (i2cDirectionTransmit == transfer->currentDir) {
288 			/* Normal write operation. */
289 			transfer->ack =
290 			!(I2C_GetStatusFlag(base, i2cStatusReceivedAck));
291 
292 			if (transfer->txSize == 0U) {
293 				/* Close I2C interrupt. */
294 				I2C_SetIntCmd(base, false);
295 				/* Release I2C Bus. */
296 				transfer->isBusy = false;
297 				k_sem_give(&data->device_sync_sem);
298 			} else {
299 				I2C_WriteByte(base, *transfer->txBuff);
300 				transfer->txBuff++;
301 				transfer->txSize--;
302 			}
303 		} else {
304 			/* Normal read operation. */
305 			if (transfer->rxSize == 2U) {
306 				/* Send Nack */
307 				I2C_SetAckBit(base, false);
308 			} else {
309 				/* Send Ack */
310 				I2C_SetAckBit(base, true);
311 			}
312 
313 			if (transfer->rxSize == 1U) {
314 				/* Switch back to Tx direction to avoid
315 				 * additional I2C bus read.
316 				 */
317 				I2C_SetDirMode(base, i2cDirectionTransmit);
318 				transfer->currentDir = i2cDirectionTransmit;
319 			}
320 
321 			*transfer->rxBuff = I2C_ReadByte(base);
322 			transfer->rxBuff++;
323 			transfer->rxSize--;
324 
325 			/* receive finished. */
326 			if (transfer->rxSize == 0U) {
327 				/* Close I2C interrupt. */
328 				I2C_SetIntCmd(base, false);
329 				/* Release I2C Bus. */
330 				transfer->isBusy = false;
331 				k_sem_give(&data->device_sync_sem);
332 			}
333 		}
334 	}
335 }
336 
i2c_imx_init(const struct device * dev)337 static int i2c_imx_init(const struct device *dev)
338 {
339 	const struct i2c_imx_config *config = dev->config;
340 	struct i2c_imx_data *data = dev->data;
341 	uint32_t bitrate_cfg;
342 	int error;
343 
344 	k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT);
345 
346 	error = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
347 	if (error) {
348 		return error;
349 	}
350 
351 	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
352 
353 	error = i2c_imx_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
354 	if (error) {
355 		return error;
356 	}
357 
358 	config->irq_config_func(dev);
359 
360 	return 0;
361 }
362 
363 static const struct i2c_driver_api i2c_imx_driver_api = {
364 	.configure = i2c_imx_configure,
365 	.transfer = i2c_imx_transfer,
366 };
367 
368 #define I2C_IMX_INIT(n)							\
369 	PINCTRL_DT_INST_DEFINE(n);					\
370 	static void i2c_imx_config_func_##n(const struct device *dev);	\
371 									\
372 	static const struct i2c_imx_config i2c_imx_config_##n = {	\
373 		.base = (I2C_Type *)DT_INST_REG_ADDR(n),		\
374 		.irq_config_func = i2c_imx_config_func_##n,		\
375 		.bitrate = DT_INST_PROP(n, clock_frequency),		\
376 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),		\
377 	};								\
378 									\
379 	static struct i2c_imx_data i2c_imx_data_##n;			\
380 									\
381 	I2C_DEVICE_DT_INST_DEFINE(n,					\
382 				i2c_imx_init,				\
383 				NULL,					\
384 				&i2c_imx_data_##n, &i2c_imx_config_##n,	\
385 				POST_KERNEL,				\
386 				CONFIG_I2C_INIT_PRIORITY,		\
387 				&i2c_imx_driver_api);			\
388 									\
389 	static void i2c_imx_config_func_##n(const struct device *dev)	\
390 	{								\
391 		ARG_UNUSED(dev);					\
392 									\
393 		IRQ_CONNECT(DT_INST_IRQN(n),				\
394 			    DT_INST_IRQ(n, priority),			\
395 			    i2c_imx_isr, DEVICE_DT_INST_GET(n), 0);	\
396 									\
397 		irq_enable(DT_INST_IRQN(n));				\
398 	}
399 
400 DT_INST_FOREACH_STATUS_OKAY(I2C_IMX_INIT)
401