1 /*
2  * Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
3  * Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT atmel_sam0_i2c
9 
10 #include <errno.h>
11 #include <zephyr/device.h>
12 #include <zephyr/init.h>
13 #include <soc.h>
14 #include <zephyr/drivers/i2c.h>
15 #include <zephyr/drivers/dma.h>
16 #include <zephyr/drivers/pinctrl.h>
17 
18 #include <zephyr/logging/log.h>
19 #include <zephyr/irq.h>
20 LOG_MODULE_REGISTER(i2c_sam0, CONFIG_I2C_LOG_LEVEL);
21 
22 /* clang-format off */
23 
24 #include "i2c-priv.h"
25 
26 #ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER
27 #define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER SERCOM_I2CM_CTRLA_MODE(5)
28 #endif
29 
30 #if CONFIG_I2C_SAM0_TRANSFER_TIMEOUT
31 #define I2C_TRANSFER_TIMEOUT_MSEC K_MSEC(CONFIG_I2C_SAM0_TRANSFER_TIMEOUT)
32 #else
33 #define I2C_TRANSFER_TIMEOUT_MSEC K_FOREVER
34 #endif
35 
36 struct i2c_sam0_dev_config {
37 	SercomI2cm *regs;
38 	const struct pinctrl_dev_config *pcfg;
39 	uint32_t bitrate;
40 	volatile uint32_t *mclk;
41 	uint32_t mclk_mask;
42 	uint32_t gclk_gen;
43 	uint16_t gclk_id;
44 	void (*irq_config_func)(const struct device *dev);
45 
46 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
47 	const struct device *dma_dev;
48 	uint8_t write_dma_request;
49 	uint8_t read_dma_request;
50 	uint8_t dma_channel;
51 #endif
52 };
53 
54 struct i2c_sam0_msg {
55 	uint8_t *buffer;
56 	uint32_t size;
57 	uint32_t status;
58 };
59 
60 struct i2c_sam0_dev_data {
61 	struct k_sem lock;
62 	struct k_sem sem;
63 	struct i2c_sam0_msg msg;
64 	struct i2c_msg *msgs;
65 	uint8_t num_msgs;
66 };
67 
wait_synchronization(SercomI2cm * regs)68 static void wait_synchronization(SercomI2cm *regs)
69 {
70 #if defined(SERCOM_I2CM_SYNCBUSY_MASK)
71 	/* SYNCBUSY is a register */
72 	while ((regs->SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK) != 0) {
73 	}
74 #elif defined(SERCOM_I2CM_STATUS_SYNCBUSY)
75 	/* SYNCBUSY is a bit */
76 	while ((regs->STATUS.reg & SERCOM_I2CM_STATUS_SYNCBUSY) != 0) {
77 	}
78 #else
79 #error Unsupported device
80 #endif
81 }
82 
i2c_sam0_terminate_on_error(const struct device * dev)83 static bool i2c_sam0_terminate_on_error(const struct device *dev)
84 {
85 	struct i2c_sam0_dev_data *data = dev->data;
86 	const struct i2c_sam0_dev_config *const cfg = dev->config;
87 	SercomI2cm *i2c = cfg->regs;
88 
89 	if (!(i2c->STATUS.reg & (SERCOM_I2CM_STATUS_ARBLOST |
90 				 SERCOM_I2CM_STATUS_RXNACK |
91 #ifdef SERCOM_I2CM_STATUS_LENERR
92 				 SERCOM_I2CM_STATUS_LENERR |
93 #endif
94 #ifdef SERCOM_I2CM_STATUS_SEXTTOUT
95 				 SERCOM_I2CM_STATUS_SEXTTOUT |
96 #endif
97 #ifdef SERCOM_I2CM_STATUS_MEXTTOUT
98 				 SERCOM_I2CM_STATUS_MEXTTOUT |
99 #endif
100 				 SERCOM_I2CM_STATUS_LOWTOUT |
101 				 SERCOM_I2CM_STATUS_BUSERR))) {
102 		return false;
103 	}
104 
105 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
106 	if (cfg->dma_channel != 0xFF) {
107 		dma_stop(cfg->dma_dev, cfg->dma_channel);
108 	}
109 #endif
110 
111 	data->msg.status = i2c->STATUS.reg;
112 
113 	/*
114 	 * Clear all the flags that require an explicit clear
115 	 * (as opposed to being cleared by ADDR writes, etc)
116 	 */
117 	i2c->STATUS.reg = SERCOM_I2CM_STATUS_ARBLOST |
118 #ifdef SERCOM_I2CM_STATUS_LENERR
119 			  SERCOM_I2CM_STATUS_LENERR |
120 #endif
121 			  SERCOM_I2CM_STATUS_LOWTOUT |
122 			  SERCOM_I2CM_STATUS_BUSERR;
123 	wait_synchronization(i2c);
124 
125 	i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
126 	if (i2c->INTFLAG.reg & (SERCOM_I2CM_INTFLAG_MB | SERCOM_I2CM_INTFLAG_SB)) {
127 		i2c->CTRLB.bit.CMD = 3;
128 	}
129 	k_sem_give(&data->sem);
130 	return true;
131 }
132 
i2c_sam0_isr(const struct device * dev)133 static void i2c_sam0_isr(const struct device *dev)
134 {
135 	struct i2c_sam0_dev_data *data = dev->data;
136 	const struct i2c_sam0_dev_config *const cfg = dev->config;
137 	SercomI2cm *i2c = cfg->regs;
138 
139 	/* Get present interrupts and clear them */
140 	uint32_t status = i2c->INTFLAG.reg;
141 
142 	i2c->INTFLAG.reg = status;
143 
144 	if (i2c_sam0_terminate_on_error(dev)) {
145 		return;
146 	}
147 
148 	/*
149 	 * Directly send/receive next message if it is in the same direction and
150 	 * the current message has no stop flag and the next message has no
151 	 * restart flag.
152 	 */
153 	const bool continue_next = (data->msg.size == 1) && (data->num_msgs > 1) &&
154 				   ((data->msgs[0].flags & I2C_MSG_RW_MASK) ==
155 				    (data->msgs[1].flags & I2C_MSG_RW_MASK)) &&
156 				   !(data->msgs[0].flags & I2C_MSG_STOP) &&
157 				   !(data->msgs[1].flags & I2C_MSG_RESTART) &&
158 				   ((status & (SERCOM_I2CM_INTFLAG_MB | SERCOM_I2CM_INTFLAG_SB)));
159 
160 	if (status & SERCOM_I2CM_INTFLAG_MB) {
161 		if (!data->msg.size) {
162 			i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
163 
164 			/*
165 			 * Decide whether to issue a repeated start, or a stop condition...
166 			 *   - A repeated start can either be accomplished by writing a 0x1
167 			 *     to the CMD field, or by writing to ADDR - which is what this
168 			 *     driver does in i2c_sam0_transfer().
169 			 *   - A stop is accomplished by writing a 0x3 to CMD (below).
170 			 *
171 			 * This decision is not the same as continue_next, as the value of
172 			 * data->msg.size is already zero (not one), and i2c_sam0_transfer()
173 			 * is responsible for advancing to the next message, not the ISR.
174 			 */
175 			if ((data->num_msgs <= 1)
176 			    || (data->msgs[0].flags & I2C_MSG_STOP)
177 			    || !(data->msgs[1].flags & I2C_MSG_RESTART)) {
178 				i2c->CTRLB.bit.CMD = 3;
179 			}
180 
181 			k_sem_give(&data->sem);
182 			return;
183 		}
184 
185 		i2c->DATA.reg = *data->msg.buffer;
186 		data->msg.buffer++;
187 		data->msg.size--;
188 	} else if (status & SERCOM_I2CM_INTFLAG_SB) {
189 		if (!continue_next && (data->msg.size == 1)) {
190 			/*
191 			 * If this is the last byte, then prepare for an auto
192 			 * NACK before doing the actual read.  This does not
193 			 * require write synchronization.
194 			 */
195 			i2c->CTRLB.bit.ACKACT = 1;
196 			i2c->CTRLB.bit.CMD = 3;
197 		}
198 
199 		*data->msg.buffer = i2c->DATA.reg;
200 		data->msg.buffer++;
201 		data->msg.size--;
202 
203 		if (!continue_next && !data->msg.size) {
204 			i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
205 			k_sem_give(&data->sem);
206 			return;
207 		}
208 	}
209 
210 	if (continue_next) {
211 		data->msgs++;
212 		data->num_msgs--;
213 
214 		data->msg.buffer = data->msgs->buf;
215 		data->msg.size = data->msgs->len;
216 		data->msg.status = 0;
217 	}
218 }
219 
220 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
221 
i2c_sam0_dma_write_done(const struct device * dma_dev,void * arg,uint32_t id,int error_code)222 static void i2c_sam0_dma_write_done(const struct device *dma_dev, void *arg,
223 				    uint32_t id, int error_code)
224 {
225 	const struct device *dev = arg;
226 	struct i2c_sam0_dev_data *data = dev->data;
227 	const struct i2c_sam0_dev_config *const cfg = dev->config;
228 	SercomI2cm *i2c = cfg->regs;
229 
230 	ARG_UNUSED(dma_dev);
231 	ARG_UNUSED(id);
232 
233 	unsigned int key = irq_lock();
234 
235 	if (i2c_sam0_terminate_on_error(dev)) {
236 		irq_unlock(key);
237 		return;
238 	}
239 
240 	if (error_code < 0) {
241 		LOG_ERR("DMA write error on %s: %d", dev->name, error_code);
242 		i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
243 		irq_unlock(key);
244 
245 		data->msg.status = error_code;
246 
247 		k_sem_give(&data->sem);
248 		return;
249 	}
250 
251 	irq_unlock(key);
252 
253 	/*
254 	 * DMA has written the whole message now, so just wait for the
255 	 * final I2C IRQ to indicate that it's finished transmitting.
256 	 */
257 	data->msg.size = 0;
258 	i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_MB;
259 }
260 
i2c_sam0_dma_write_start(const struct device * dev)261 static bool i2c_sam0_dma_write_start(const struct device *dev)
262 {
263 	struct i2c_sam0_dev_data *data = dev->data;
264 	const struct i2c_sam0_dev_config *const cfg = dev->config;
265 	SercomI2cm *i2c = cfg->regs;
266 	int retval;
267 
268 	if (cfg->dma_channel == 0xFF) {
269 		return false;
270 	}
271 
272 	if (data->msg.size <= 1) {
273 		/*
274 		 * Catch empty writes and skip DMA on single byte transfers.
275 		 */
276 		return false;
277 	}
278 
279 	struct dma_config dma_cfg = { 0 };
280 	struct dma_block_config dma_blk = { 0 };
281 
282 	dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL;
283 	dma_cfg.source_data_size = 1;
284 	dma_cfg.dest_data_size = 1;
285 	dma_cfg.user_data = (void *)dev;
286 	dma_cfg.dma_callback = i2c_sam0_dma_write_done;
287 	dma_cfg.block_count = 1;
288 	dma_cfg.head_block = &dma_blk;
289 	dma_cfg.dma_slot = cfg->write_dma_request;
290 
291 	dma_blk.block_size = data->msg.size;
292 	dma_blk.source_address = (uint32_t)data->msg.buffer;
293 	dma_blk.dest_address = (uint32_t)(&(i2c->DATA.reg));
294 	dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;
295 
296 	retval = dma_config(cfg->dma_dev, cfg->dma_channel, &dma_cfg);
297 	if (retval != 0) {
298 		LOG_ERR("Write DMA configure on %s failed: %d",
299 			dev->name, retval);
300 		return false;
301 	}
302 
303 	retval = dma_start(cfg->dma_dev, cfg->dma_channel);
304 	if (retval != 0) {
305 		LOG_ERR("Write DMA start on %s failed: %d",
306 			dev->name, retval);
307 		return false;
308 	}
309 
310 	return true;
311 }
312 
i2c_sam0_dma_read_done(const struct device * dma_dev,void * arg,uint32_t id,int error_code)313 static void i2c_sam0_dma_read_done(const struct device *dma_dev, void *arg,
314 				   uint32_t id, int error_code)
315 {
316 	const struct device *dev = arg;
317 	struct i2c_sam0_dev_data *data = dev->data;
318 	const struct i2c_sam0_dev_config *const cfg = dev->config;
319 	SercomI2cm *i2c = cfg->regs;
320 
321 	ARG_UNUSED(dma_dev);
322 	ARG_UNUSED(id);
323 
324 	unsigned int key = irq_lock();
325 
326 	if (i2c_sam0_terminate_on_error(dev)) {
327 		irq_unlock(key);
328 		return;
329 	}
330 
331 	if (error_code < 0) {
332 		LOG_ERR("DMA read error on %s: %d", dev->name, error_code);
333 		i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
334 		irq_unlock(key);
335 
336 		data->msg.status = error_code;
337 
338 		k_sem_give(&data->sem);
339 		return;
340 	}
341 
342 	irq_unlock(key);
343 
344 	/*
345 	 * DMA has read all but the last byte now, so let the ISR handle
346 	 * that and the terminating NACK.
347 	 */
348 	data->msg.buffer += data->msg.size - 1;
349 	data->msg.size = 1;
350 	i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_SB;
351 }
352 
i2c_sam0_dma_read_start(const struct device * dev)353 static bool i2c_sam0_dma_read_start(const struct device *dev)
354 {
355 	struct i2c_sam0_dev_data *data = dev->data;
356 	const struct i2c_sam0_dev_config *const cfg = dev->config;
357 	SercomI2cm *i2c = cfg->regs;
358 	int retval;
359 
360 	if (cfg->dma_channel == 0xFF) {
361 		return false;
362 	}
363 
364 	if (data->msg.size <= 2) {
365 		/*
366 		 * The last byte is always handled by the I2C ISR so
367 		 * just skip a two length read as well.
368 		 */
369 		return false;
370 	}
371 
372 	struct dma_config dma_cfg = { 0 };
373 	struct dma_block_config dma_blk = { 0 };
374 
375 	dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY;
376 	dma_cfg.source_data_size = 1;
377 	dma_cfg.dest_data_size = 1;
378 	dma_cfg.user_data = (void *)dev;
379 	dma_cfg.dma_callback = i2c_sam0_dma_read_done;
380 	dma_cfg.block_count = 1;
381 	dma_cfg.head_block = &dma_blk;
382 	dma_cfg.dma_slot = cfg->read_dma_request;
383 
384 	dma_blk.block_size = data->msg.size - 1;
385 	dma_blk.dest_address = (uint32_t)data->msg.buffer;
386 	dma_blk.source_address = (uint32_t)(&(i2c->DATA.reg));
387 	dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;
388 
389 	retval = dma_config(cfg->dma_dev, cfg->dma_channel, &dma_cfg);
390 	if (retval != 0) {
391 		LOG_ERR("Read DMA configure on %s failed: %d",
392 			dev->name, retval);
393 		return false;
394 	}
395 
396 	retval = dma_start(cfg->dma_dev, cfg->dma_channel);
397 	if (retval != 0) {
398 		LOG_ERR("Read DMA start on %s failed: %d",
399 			dev->name, retval);
400 		return false;
401 	}
402 
403 	return true;
404 }
405 
406 #endif
407 
i2c_sam0_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)408 static int i2c_sam0_transfer(const struct device *dev, struct i2c_msg *msgs,
409 			     uint8_t num_msgs, uint16_t addr)
410 {
411 	struct i2c_sam0_dev_data *data = dev->data;
412 	const struct i2c_sam0_dev_config *const cfg = dev->config;
413 	SercomI2cm *i2c = cfg->regs;
414 	uint32_t addr_reg;
415 	int ret;
416 
417 	if (!num_msgs) {
418 		return 0;
419 	}
420 
421 	k_sem_take(&data->lock, K_FOREVER);
422 
423 	data->num_msgs = num_msgs;
424 	data->msgs = msgs;
425 
426 	for (; data->num_msgs > 0;) {
427 		if (!data->msgs->len) {
428 			if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
429 				ret = -EINVAL;
430 				goto unlock;
431 			}
432 		}
433 
434 		i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
435 		i2c->INTFLAG.reg = SERCOM_I2CM_INTFLAG_MASK;
436 
437 		i2c->STATUS.reg = SERCOM_I2CM_STATUS_ARBLOST |
438 #ifdef SERCOM_I2CM_STATUS_LENERR
439 				  SERCOM_I2CM_STATUS_LENERR |
440 #endif
441 				  SERCOM_I2CM_STATUS_LOWTOUT |
442 				  SERCOM_I2CM_STATUS_BUSERR;
443 		wait_synchronization(i2c);
444 
445 		data->msg.buffer = data->msgs->buf;
446 		data->msg.size = data->msgs->len;
447 		data->msg.status = 0;
448 
449 		addr_reg = addr << 1U;
450 		if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
451 			addr_reg |= 1U;
452 
453 			/* Set to auto ACK */
454 			i2c->CTRLB.bit.ACKACT = 0;
455 			wait_synchronization(i2c);
456 		}
457 
458 		if (data->msgs->flags & I2C_MSG_ADDR_10_BITS) {
459 #ifdef SERCOM_I2CM_ADDR_TENBITEN
460 			addr_reg |= SERCOM_I2CM_ADDR_TENBITEN;
461 #else
462 			ret = -ENOTSUP;
463 			goto unlock;
464 #endif
465 		}
466 
467 		unsigned int key = irq_lock();
468 
469 		/*
470 		 * Writing the address starts the transaction, issuing
471 		 * a start/repeated start as required.
472 		 */
473 		i2c->ADDR.reg = addr_reg;
474 
475 		/*
476 		 * Have to wait here to make sure the address write
477 		 * clears any pending requests or errors before DMA or
478 		 * ISR tries to handle it.
479 		 */
480 		wait_synchronization(i2c);
481 
482 #ifdef SERCOM_I2CM_INTENSET_ERROR
483 		i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_ERROR;
484 #endif
485 
486 		if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
487 			/*
488 			 * Always set MB even when reading, since that's how
489 			 * some errors are indicated.
490 			 */
491 			i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_MB;
492 
493 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
494 			if (!i2c_sam0_dma_read_start(dev))
495 #endif
496 			{
497 				i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_SB;
498 			}
499 
500 		} else {
501 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
502 			if (!i2c_sam0_dma_write_start(dev))
503 #endif
504 			{
505 				i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_MB;
506 			}
507 		}
508 
509 		irq_unlock(key);
510 
511 		/* Now wait for the ISR to handle everything */
512 		ret = k_sem_take(&data->sem, I2C_TRANSFER_TIMEOUT_MSEC);
513 
514 		if (ret != 0) {
515 			ret = -EIO;
516 			goto unlock;
517 		}
518 
519 		if (data->msg.status) {
520 			if (data->msg.status & SERCOM_I2CM_STATUS_ARBLOST) {
521 				LOG_DBG("Arbitration lost on %s",
522 					dev->name);
523 				ret = -EAGAIN;
524 				goto unlock;
525 			}
526 
527 			LOG_ERR("Transaction error on %s: %08X",
528 				dev->name, data->msg.status);
529 			ret = -EIO;
530 			goto unlock;
531 		}
532 
533 		data->num_msgs--;
534 		data->msgs++;
535 	}
536 
537 	ret = 0;
538 unlock:
539 	k_sem_give(&data->lock);
540 
541 	return ret;
542 }
543 
i2c_sam0_set_apply_bitrate(const struct device * dev,uint32_t config)544 static int i2c_sam0_set_apply_bitrate(const struct device *dev,
545 				      uint32_t config)
546 {
547 	const struct i2c_sam0_dev_config *const cfg = dev->config;
548 	SercomI2cm *i2c = cfg->regs;
549 	uint32_t baud;
550 	uint32_t baud_low;
551 	uint32_t baud_high;
552 
553 	uint32_t CTRLA = i2c->CTRLA.reg;
554 
555 #ifdef SERCOM_I2CM_CTRLA_SPEED_Msk
556 	CTRLA &= ~SERCOM_I2CM_CTRLA_SPEED_Msk;
557 #endif
558 	CTRLA &= ~SERCOM_I2CM_CTRLA_SDAHOLD_Msk;
559 
560 	switch (I2C_SPEED_GET(config)) {
561 	case I2C_SPEED_STANDARD:
562 #ifdef SERCOM_I2CM_CTRLA_SPEED
563 		CTRLA |= SERCOM_I2CM_CTRLA_SPEED(0);
564 #endif
565 		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x0);
566 		i2c->CTRLA.reg = CTRLA;
567 		wait_synchronization(i2c);
568 
569 		/* 5 is the nominal 100ns rise time from the app notes */
570 		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 100000U - 5U - 10U) / 2U;
571 		if (baud > 255U || baud < 1U) {
572 			return -ERANGE;
573 		}
574 
575 		LOG_DBG("Setting %s to standard mode with divisor %u",
576 			dev->name, baud);
577 
578 		i2c->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(baud);
579 		break;
580 
581 	case I2C_SPEED_FAST:
582 		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x0);
583 		i2c->CTRLA.reg = CTRLA;
584 		wait_synchronization(i2c);
585 
586 		/* 5 is the nominal 100ns rise time from the app notes */
587 		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 400000U - 5U - 10U) / 2U;
588 		if (baud > 255U || baud < 1U) {
589 			return -ERANGE;
590 		}
591 
592 		LOG_DBG("Setting %s to fast mode with divisor %u",
593 			dev->name, baud);
594 
595 		i2c->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(baud);
596 		break;
597 
598 	case I2C_SPEED_FAST_PLUS:
599 #ifdef SERCOM_I2CM_CTRLA_SPEED
600 		CTRLA |= SERCOM_I2CM_CTRLA_SPEED(1);
601 #endif
602 		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x2);
603 		i2c->CTRLA.reg = CTRLA;
604 		wait_synchronization(i2c);
605 
606 		/* 5 is the nominal 100ns rise time from the app notes */
607 		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 1000000U - 5U - 10U);
608 
609 		/* 2:1 low:high ratio */
610 		baud_high = baud;
611 		baud_high /= 3U;
612 		baud_high = CLAMP(baud_high, 1U, 255U);
613 		baud_low = baud - baud_high;
614 		if (baud_low < 1U && baud_high > 1U) {
615 			--baud_high;
616 			++baud_low;
617 		}
618 
619 		if (baud_low < 1U || baud_low > 255U) {
620 			return -ERANGE;
621 		}
622 
623 		LOG_DBG("Setting %s to fast mode plus with divisors %u/%u",
624 			dev->name, baud_high, baud_low);
625 
626 		i2c->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(baud_high) |
627 				SERCOM_I2CM_BAUD_BAUDLOW(baud_low);
628 		break;
629 
630 	case I2C_SPEED_HIGH:
631 #ifdef SERCOM_I2CM_CTRLA_SPEED
632 		CTRLA |= SERCOM_I2CM_CTRLA_SPEED(2);
633 #endif
634 		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x2);
635 		i2c->CTRLA.reg = CTRLA;
636 		wait_synchronization(i2c);
637 
638 		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 3400000U) - 2U;
639 
640 		/* 2:1 low:high ratio */
641 		baud_high = baud;
642 		baud_high /= 3U;
643 		baud_high = CLAMP(baud_high, 1U, 255U);
644 		baud_low = baud - baud_high;
645 		if (baud_low < 1U && baud_high > 1U) {
646 			--baud_high;
647 			++baud_low;
648 		}
649 
650 		if (baud_low < 1U || baud_low > 255U) {
651 			return -ERANGE;
652 		}
653 
654 #ifdef SERCOM_I2CM_BAUD_HSBAUD
655 		LOG_DBG("Setting %s to high speed with divisors %u/%u",
656 			dev->name, baud_high, baud_low);
657 
658 		/*
659 		 * 48 is just from the app notes, but the datasheet says
660 		 * it's ignored
661 		 */
662 		i2c->BAUD.reg = SERCOM_I2CM_BAUD_HSBAUD(baud_high) |
663 				SERCOM_I2CM_BAUD_HSBAUDLOW(baud_low) |
664 				SERCOM_I2CM_BAUD_BAUD(48) |
665 				SERCOM_I2CM_BAUD_BAUDLOW(48);
666 #else
667 		return -ENOTSUP;
668 #endif
669 		break;
670 
671 	default:
672 		return -ENOTSUP;
673 	}
674 
675 	wait_synchronization(i2c);
676 	return 0;
677 }
678 
i2c_sam0_configure(const struct device * dev,uint32_t config)679 static int i2c_sam0_configure(const struct device *dev, uint32_t config)
680 {
681 	const struct i2c_sam0_dev_config *const cfg = dev->config;
682 	SercomI2cm *i2c = cfg->regs;
683 	int retval;
684 
685 	if (!(config & I2C_MODE_CONTROLLER)) {
686 		return -EINVAL;
687 	}
688 
689 	if (config & I2C_SPEED_MASK) {
690 		i2c->CTRLA.bit.ENABLE = 0;
691 		wait_synchronization(i2c);
692 
693 		retval = i2c_sam0_set_apply_bitrate(dev, config);
694 
695 		i2c->CTRLA.bit.ENABLE = 1;
696 		wait_synchronization(i2c);
697 
698 		if (retval != 0) {
699 			return retval;
700 		}
701 	}
702 
703 	return 0;
704 }
705 
i2c_sam0_initialize(const struct device * dev)706 static int i2c_sam0_initialize(const struct device *dev)
707 {
708 	struct i2c_sam0_dev_data *data = dev->data;
709 	const struct i2c_sam0_dev_config *const cfg = dev->config;
710 	SercomI2cm *i2c = cfg->regs;
711 	int retval;
712 
713 	*cfg->mclk |= cfg->mclk_mask;
714 
715 #ifdef MCLK
716 	GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
717 					| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
718 #else
719 	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
720 			  | GCLK_CLKCTRL_GEN(cfg->gclk_gen)
721 			  | GCLK_CLKCTRL_ID(cfg->gclk_id);
722 #endif
723 
724 	/* Disable all I2C interrupts */
725 	i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
726 
727 	retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
728 	if (retval < 0) {
729 		return retval;
730 	}
731 
732 	/* I2C mode, enable timeouts */
733 	i2c->CTRLA.reg = SERCOM_I2CM_CTRLA_MODE_I2C_MASTER |
734 #ifdef SERCOM_I2CM_CTRLA_LOWTOUTEN
735 			 SERCOM_I2CM_CTRLA_LOWTOUTEN |
736 #endif
737 			 SERCOM_I2CM_CTRLA_INACTOUT(0x3);
738 	wait_synchronization(i2c);
739 
740 	/* Enable smart mode (auto ACK) */
741 	i2c->CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN;
742 	wait_synchronization(i2c);
743 
744 	retval = i2c_sam0_set_apply_bitrate(dev,
745 					    i2c_map_dt_bitrate(cfg->bitrate));
746 	if (retval != 0) {
747 		return retval;
748 	}
749 
750 	k_sem_init(&data->lock, 1, 1);
751 	k_sem_init(&data->sem, 0, 1);
752 
753 	cfg->irq_config_func(dev);
754 
755 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
756 	if (!device_is_ready(cfg->dma_dev)) {
757 		return -ENODEV;
758 	}
759 #endif
760 
761 	i2c->CTRLA.bit.ENABLE = 1;
762 	wait_synchronization(i2c);
763 
764 	/* Force bus idle */
765 	i2c->STATUS.bit.BUSSTATE = 1;
766 	wait_synchronization(i2c);
767 
768 	return 0;
769 }
770 
771 static DEVICE_API(i2c, i2c_sam0_driver_api) = {
772 	.configure = i2c_sam0_configure,
773 	.transfer = i2c_sam0_transfer,
774 #ifdef CONFIG_I2C_RTIO
775 	.iodev_submit = i2c_iodev_submit_fallback,
776 #endif
777 };
778 
779 #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
780 #define I2C_SAM0_DMA_CHANNELS(n)					\
781 	.dma_dev = DEVICE_DT_GET(ATMEL_SAM0_DT_INST_DMA_CTLR(n, tx)),	\
782 	.write_dma_request = ATMEL_SAM0_DT_INST_DMA_TRIGSRC(n, tx),	\
783 	.read_dma_request = ATMEL_SAM0_DT_INST_DMA_TRIGSRC(n, rx),	\
784 	.dma_channel = ATMEL_SAM0_DT_INST_DMA_CHANNEL(n, rx),
785 #else
786 #define I2C_SAM0_DMA_CHANNELS(n)
787 #endif
788 
789 #define SAM0_I2C_IRQ_CONNECT(n, m)					\
790 	do {								\
791 		IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq),		\
792 			    DT_INST_IRQ_BY_IDX(n, m, priority),		\
793 			    i2c_sam0_isr,				\
794 			    DEVICE_DT_INST_GET(n), 0);			\
795 		irq_enable(DT_INST_IRQ_BY_IDX(n, m, irq));		\
796 	} while (false)
797 
798 #if DT_INST_IRQ_HAS_IDX(0, 3)
799 #define I2C_SAM0_IRQ_HANDLER(n)						\
800 static void i2c_sam0_irq_config_##n(const struct device *dev)		\
801 {									\
802 	SAM0_I2C_IRQ_CONNECT(n, 0);					\
803 	SAM0_I2C_IRQ_CONNECT(n, 1);					\
804 	SAM0_I2C_IRQ_CONNECT(n, 2);					\
805 	SAM0_I2C_IRQ_CONNECT(n, 3);					\
806 }
807 #else
808 #define I2C_SAM0_IRQ_HANDLER(n)						\
809 static void i2c_sam0_irq_config_##n(const struct device *dev)		\
810 {									\
811 	SAM0_I2C_IRQ_CONNECT(n, 0);					\
812 }
813 #endif
814 
815 #define ASSIGNED_CLOCKS_CELL_BY_NAME					\
816 	ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
817 
818 #ifdef MCLK
819 #define I2C_SAM0_CONFIG(n)						\
820 static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = {	\
821 	.regs = (SercomI2cm *)DT_INST_REG_ADDR(n),			\
822 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),			\
823 	.bitrate = DT_INST_PROP(n, clock_frequency),			\
824 	.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen),		\
825 	.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id),		\
826 	.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n),		\
827 	.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit),	\
828 	.irq_config_func = &i2c_sam0_irq_config_##n,			\
829 	I2C_SAM0_DMA_CHANNELS(n)					\
830 }
831 #else /* !MCLK */
832 #define I2C_SAM0_CONFIG(n)						\
833 static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = {	\
834 	.regs = (SercomI2cm *)DT_INST_REG_ADDR(n),			\
835 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),			\
836 	.bitrate = DT_INST_PROP(n, clock_frequency),			\
837 	.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen),		\
838 	.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id),		\
839 	.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n),		\
840 	.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit),	\
841 	.irq_config_func = &i2c_sam0_irq_config_##n,			\
842 	I2C_SAM0_DMA_CHANNELS(n)					\
843 }
844 #endif
845 
846 #define I2C_SAM0_DEVICE(n)						\
847 	PINCTRL_DT_INST_DEFINE(n);					\
848 	static void i2c_sam0_irq_config_##n(const struct device *dev);	\
849 	I2C_SAM0_CONFIG(n);						\
850 	static struct i2c_sam0_dev_data i2c_sam0_dev_data_##n;		\
851 	I2C_DEVICE_DT_INST_DEFINE(n,					\
852 			    i2c_sam0_initialize,			\
853 			    NULL,					\
854 			    &i2c_sam0_dev_data_##n,			\
855 			    &i2c_sam0_dev_config_##n, POST_KERNEL,	\
856 			    CONFIG_I2C_INIT_PRIORITY,			\
857 			    &i2c_sam0_driver_api);			\
858 	I2C_SAM0_IRQ_HANDLER(n)
859 
860 DT_INST_FOREACH_STATUS_OKAY(I2C_SAM0_DEVICE)
861 
862 /* clang-format on */
863