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