1 /*
2  * Copyright (c) 2017 Piotr Mienkowski
3  * Copyright (c) 2023 Gerson Fernando Budke
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT atmel_sam_i2c_twi
9 
10 /** @file
11  * @brief I2C bus (TWI) driver for Atmel SAM MCU family.
12  *
13  * Limitations:
14  * - Only I2C Master Mode with 7 bit addressing is currently supported.
15  * - No reentrancy support.
16  */
17 
18 #include <errno.h>
19 #include <zephyr/sys/__assert.h>
20 #include <stdbool.h>
21 #include <zephyr/kernel.h>
22 #include <zephyr/device.h>
23 #include <zephyr/init.h>
24 #include <soc.h>
25 #include <zephyr/drivers/i2c.h>
26 #include <zephyr/drivers/pinctrl.h>
27 #include <zephyr/drivers/clock_control/atmel_sam_pmc.h>
28 
29 #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
30 #include <zephyr/logging/log.h>
31 #include <zephyr/irq.h>
32 LOG_MODULE_REGISTER(i2c_sam_twi);
33 
34 #include "i2c-priv.h"
35 
36 /** I2C bus speed [Hz] in Standard Mode */
37 #define BUS_SPEED_STANDARD_HZ         100000U
38 /** I2C bus speed [Hz] in Fast Mode */
39 #define BUS_SPEED_FAST_HZ             400000U
40 /* Maximum value of Clock Divider (CKDIV) */
41 #define CKDIV_MAX                          7
42 
43 /* Device constant configuration parameters */
44 struct i2c_sam_twi_dev_cfg {
45 	Twi *regs;
46 	void (*irq_config)(void);
47 	uint32_t bitrate;
48 	const struct atmel_sam_pmc_config clock_cfg;
49 	const struct pinctrl_dev_config *pcfg;
50 	uint8_t irq_id;
51 };
52 
53 struct twi_msg {
54 	/* Buffer containing data to read or write */
55 	uint8_t *buf;
56 	/* Length of the buffer */
57 	uint32_t len;
58 	/* Index of the next byte to be read/written from/to the buffer */
59 	uint32_t idx;
60 	/* Value of TWI_SR at the end of the message */
61 	uint32_t twi_sr;
62 	/* Transfer flags as defined in the i2c.h file */
63 	uint8_t flags;
64 };
65 
66 /* Device run time data */
67 struct i2c_sam_twi_dev_data {
68 	struct k_sem lock;
69 	struct k_sem sem;
70 	struct twi_msg msg;
71 };
72 
i2c_clk_set(Twi * const twi,uint32_t speed)73 static int i2c_clk_set(Twi *const twi, uint32_t speed)
74 {
75 	uint32_t ck_div = 0U;
76 	uint32_t cl_div;
77 	bool div_completed = false;
78 
79 	/*  From the datasheet "TWI Clock Waveform Generator Register"
80 	 *  T_low = ( ( CLDIV × 2^CKDIV ) + 4 ) × T_MCK
81 	 */
82 	while (!div_completed) {
83 		cl_div =   ((SOC_ATMEL_SAM_MCK_FREQ_HZ / (speed * 2U)) - 4)
84 			 / (1 << ck_div);
85 
86 		if (cl_div <= 255U) {
87 			div_completed = true;
88 		} else {
89 			ck_div++;
90 		}
91 	}
92 
93 	if (ck_div > CKDIV_MAX) {
94 		LOG_ERR("Failed to configure I2C clock");
95 		return -EIO;
96 	}
97 
98 	/* Set TWI clock duty cycle to 50% */
99 	twi->TWI_CWGR = TWI_CWGR_CLDIV(cl_div) | TWI_CWGR_CHDIV(cl_div)
100 			| TWI_CWGR_CKDIV(ck_div);
101 
102 	return 0;
103 }
104 
i2c_sam_twi_configure(const struct device * dev,uint32_t config)105 static int i2c_sam_twi_configure(const struct device *dev, uint32_t config)
106 {
107 	const struct i2c_sam_twi_dev_cfg *const dev_cfg = dev->config;
108 	struct i2c_sam_twi_dev_data *const dev_data = dev->data;
109 	Twi *const twi = dev_cfg->regs;
110 	uint32_t bitrate;
111 	int ret;
112 
113 	if (!(config & I2C_MODE_CONTROLLER)) {
114 		LOG_ERR("Master Mode is not enabled");
115 		return -EIO;
116 	}
117 
118 	if (config & I2C_ADDR_10_BITS) {
119 		LOG_ERR("I2C 10-bit addressing is currently not supported");
120 		LOG_ERR("Please submit a patch");
121 		return -EIO;
122 	}
123 
124 	/* Configure clock */
125 	switch (I2C_SPEED_GET(config)) {
126 	case I2C_SPEED_STANDARD:
127 		bitrate = BUS_SPEED_STANDARD_HZ;
128 		break;
129 	case I2C_SPEED_FAST:
130 		bitrate = BUS_SPEED_FAST_HZ;
131 		break;
132 	default:
133 		LOG_ERR("Unsupported I2C speed value");
134 		return -EIO;
135 	}
136 
137 	k_sem_take(&dev_data->lock, K_FOREVER);
138 
139 	/* Setup clock waveform */
140 	ret = i2c_clk_set(twi, bitrate);
141 	if (ret < 0) {
142 		goto unlock;
143 	}
144 
145 	/* Disable Slave Mode */
146 	twi->TWI_CR = TWI_CR_SVDIS;
147 
148 	/* Enable Master Mode */
149 	twi->TWI_CR = TWI_CR_MSEN;
150 
151 	ret = 0;
152 unlock:
153 	k_sem_give(&dev_data->lock);
154 
155 	return ret;
156 }
157 
write_msg_start(Twi * const twi,struct twi_msg * msg,uint8_t daddr)158 static void write_msg_start(Twi *const twi, struct twi_msg *msg, uint8_t daddr)
159 {
160 	/* Set slave address and number of internal address bytes. */
161 	twi->TWI_MMR = TWI_MMR_DADR(daddr);
162 
163 	/* Write first data byte on I2C bus */
164 	twi->TWI_THR = msg->buf[msg->idx++];
165 
166 	/* Enable Transmit Ready and Transmission Completed interrupts */
167 	twi->TWI_IER = TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_NACK;
168 }
169 
read_msg_start(Twi * const twi,struct twi_msg * msg,uint8_t daddr)170 static void read_msg_start(Twi *const twi, struct twi_msg *msg, uint8_t daddr)
171 {
172 	uint32_t twi_cr_stop;
173 
174 	/* Set slave address and number of internal address bytes */
175 	twi->TWI_MMR = TWI_MMR_MREAD | TWI_MMR_DADR(daddr);
176 
177 	/* In single data byte read the START and STOP must both be set */
178 	twi_cr_stop = (msg->len == 1U) ? TWI_CR_STOP : 0;
179 	/* Start the transfer by sending START condition */
180 	twi->TWI_CR = TWI_CR_START | twi_cr_stop;
181 
182 	/* Enable Receive Ready and Transmission Completed interrupts */
183 	twi->TWI_IER = TWI_IER_RXRDY | TWI_IER_TXCOMP | TWI_IER_NACK;
184 }
185 
i2c_sam_twi_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)186 static int i2c_sam_twi_transfer(const struct device *dev,
187 				struct i2c_msg *msgs,
188 				uint8_t num_msgs, uint16_t addr)
189 {
190 	const struct i2c_sam_twi_dev_cfg *const dev_cfg = dev->config;
191 	struct i2c_sam_twi_dev_data *const dev_data = dev->data;
192 	Twi *const twi = dev_cfg->regs;
193 	int ret;
194 
195 	__ASSERT_NO_MSG(msgs);
196 	if (!num_msgs) {
197 		return 0;
198 	}
199 	k_sem_take(&dev_data->lock, K_FOREVER);
200 
201 	/* Clear pending interrupts, such as NACK. */
202 	(void)twi->TWI_SR;
203 
204 	/* Set number of internal address bytes to 0, not used. */
205 	twi->TWI_IADR = 0;
206 
207 	for (; num_msgs > 0; num_msgs--, msgs++) {
208 		dev_data->msg.buf = msgs->buf;
209 		dev_data->msg.len = msgs->len;
210 		dev_data->msg.idx = 0U;
211 		dev_data->msg.twi_sr = 0U;
212 		dev_data->msg.flags = msgs->flags;
213 
214 		/*
215 		 * REMARK: Dirty workaround:
216 		 *
217 		 * The controller does not have a documented, generic way to
218 		 * issue RESTART when changing transfer direction as master.
219 		 * Send a stop condition in such a case.
220 		 */
221 		if (num_msgs > 1) {
222 			if ((msgs[0].flags & I2C_MSG_RW_MASK) !=
223 			    (msgs[1].flags & I2C_MSG_RW_MASK)) {
224 				dev_data->msg.flags |= I2C_MSG_STOP;
225 			}
226 		}
227 
228 		if ((msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
229 			read_msg_start(twi, &dev_data->msg, addr);
230 		} else {
231 			write_msg_start(twi, &dev_data->msg, addr);
232 		}
233 		/* Wait for the transfer to complete */
234 		k_sem_take(&dev_data->sem, K_FOREVER);
235 
236 		if (dev_data->msg.twi_sr > 0) {
237 			/* Something went wrong */
238 			ret = -EIO;
239 			goto unlock;
240 		}
241 	}
242 
243 	ret = 0;
244 unlock:
245 	k_sem_give(&dev_data->lock);
246 
247 	return ret;
248 }
249 
i2c_sam_twi_isr(const struct device * dev)250 static void i2c_sam_twi_isr(const struct device *dev)
251 {
252 	const struct i2c_sam_twi_dev_cfg *const dev_cfg = dev->config;
253 	struct i2c_sam_twi_dev_data *const dev_data = dev->data;
254 	Twi *const twi = dev_cfg->regs;
255 	struct twi_msg *msg = &dev_data->msg;
256 	uint32_t isr_status;
257 
258 	/* Retrieve interrupt status */
259 	isr_status = twi->TWI_SR & twi->TWI_IMR;
260 
261 	/* Not Acknowledged */
262 	if (isr_status & TWI_SR_NACK) {
263 		msg->twi_sr = isr_status;
264 		goto tx_comp;
265 	}
266 
267 	/* Byte received */
268 	if (isr_status & TWI_SR_RXRDY) {
269 
270 		msg->buf[msg->idx++] = twi->TWI_RHR;
271 
272 		if (msg->idx == msg->len - 1U) {
273 			/* Send a STOP condition on the TWI */
274 			twi->TWI_CR = TWI_CR_STOP;
275 		}
276 	}
277 
278 	/* Byte sent */
279 	if (isr_status & TWI_SR_TXRDY) {
280 		if (msg->idx == msg->len) {
281 			if (msg->flags & I2C_MSG_STOP) {
282 				/* Send a STOP condition on the TWI */
283 				twi->TWI_CR = TWI_CR_STOP;
284 				/* Disable Transmit Ready interrupt */
285 				twi->TWI_IDR = TWI_IDR_TXRDY;
286 			} else {
287 				/* Transmission completed */
288 				goto tx_comp;
289 			}
290 		} else {
291 			twi->TWI_THR = msg->buf[msg->idx++];
292 		}
293 	}
294 
295 	/* Transmission completed */
296 	if (isr_status & TWI_SR_TXCOMP) {
297 		goto tx_comp;
298 	}
299 
300 	return;
301 
302 tx_comp:
303 	/* Disable all enabled interrupts */
304 	twi->TWI_IDR = twi->TWI_IMR;
305 	/* We are done */
306 	k_sem_give(&dev_data->sem);
307 }
308 
i2c_sam_twi_initialize(const struct device * dev)309 static int i2c_sam_twi_initialize(const struct device *dev)
310 {
311 	const struct i2c_sam_twi_dev_cfg *const dev_cfg = dev->config;
312 	struct i2c_sam_twi_dev_data *const dev_data = dev->data;
313 	Twi *const twi = dev_cfg->regs;
314 	uint32_t bitrate_cfg;
315 	int ret;
316 
317 	/* Configure interrupts */
318 	dev_cfg->irq_config();
319 
320 	/* Initialize semaphores */
321 	k_sem_init(&dev_data->lock, 1, 1);
322 	k_sem_init(&dev_data->sem, 0, 1);
323 
324 	/* Connect pins to the peripheral */
325 	ret = pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT);
326 	if (ret < 0) {
327 		return ret;
328 	}
329 
330 	/* Enable TWI clock in PMC */
331 	(void)clock_control_on(SAM_DT_PMC_CONTROLLER,
332 			       (clock_control_subsys_t)&dev_cfg->clock_cfg);
333 
334 	/* Reset TWI module */
335 	twi->TWI_CR = TWI_CR_SWRST;
336 
337 	bitrate_cfg = i2c_map_dt_bitrate(dev_cfg->bitrate);
338 
339 	ret = i2c_sam_twi_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
340 	if (ret < 0) {
341 		LOG_ERR("Failed to initialize %s device", dev->name);
342 		return ret;
343 	}
344 
345 	/* Enable module's IRQ */
346 	irq_enable(dev_cfg->irq_id);
347 
348 	LOG_INF("Device %s initialized", dev->name);
349 
350 	return 0;
351 }
352 
353 static const struct i2c_driver_api i2c_sam_twi_driver_api = {
354 	.configure = i2c_sam_twi_configure,
355 	.transfer = i2c_sam_twi_transfer,
356 };
357 
358 #define I2C_TWI_SAM_INIT(n)						\
359 	PINCTRL_DT_INST_DEFINE(n);					\
360 	static void i2c##n##_sam_irq_config(void)			\
361 	{								\
362 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority),	\
363 			    i2c_sam_twi_isr,				\
364 			    DEVICE_DT_INST_GET(n), 0);			\
365 	}								\
366 									\
367 	static const struct i2c_sam_twi_dev_cfg i2c##n##_sam_config = {	\
368 		.regs = (Twi *)DT_INST_REG_ADDR(n),			\
369 		.irq_config = i2c##n##_sam_irq_config,			\
370 		.clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n),		\
371 		.irq_id = DT_INST_IRQN(n),				\
372 		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),		\
373 		.bitrate = DT_INST_PROP(n, clock_frequency),		\
374 	};								\
375 									\
376 	static struct i2c_sam_twi_dev_data i2c##n##_sam_data;		\
377 									\
378 	I2C_DEVICE_DT_INST_DEFINE(n, i2c_sam_twi_initialize,		\
379 			    NULL,					\
380 			    &i2c##n##_sam_data, &i2c##n##_sam_config,	\
381 			    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,	\
382 			    &i2c_sam_twi_driver_api);
383 
384 DT_INST_FOREACH_STATUS_OKAY(I2C_TWI_SAM_INIT)
385