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