@@ -17,12 +17,21 @@ LOG_MODULE_REGISTER(i2c_sam0, CONFIG_I2C_LOG_LEVEL);
1717
1818#include "i2c-priv.h"
1919
20+ #ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER
21+ #define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER SERCOM_I2CM_CTRLA_MODE(5)
22+ #endif
23+
2024struct i2c_sam0_dev_config {
2125 SercomI2cm * regs ;
2226 u32_t bitrate ;
27+ #ifdef MCLK
28+ volatile uint32_t * mclk ;
29+ u32_t mclk_mask ;
30+ u16_t gclk_core_id ;
31+ #else
2332 u32_t pm_apbcmask ;
2433 u16_t gclk_clkctrl_id ;
25-
34+ #endif
2635 void (* irq_config_func )(struct device * dev );
2736
2837#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
@@ -660,13 +669,20 @@ static int i2c_sam0_initialize(struct device *dev)
660669 SercomI2cm * i2c = cfg -> regs ;
661670 int retval ;
662671
672+ #ifdef MCLK
673+ /* Enable the GCLK */
674+ GCLK -> PCHCTRL [cfg -> gclk_core_id ].reg = GCLK_PCHCTRL_GEN_GCLK0 |
675+ GCLK_PCHCTRL_CHEN ;
676+ /* Enable SERCOM clock in MCLK */
677+ * cfg -> mclk |= cfg -> mclk_mask ;
678+ #else
663679 /* Enable the GCLK */
664680 GCLK -> CLKCTRL .reg = cfg -> gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
665681 GCLK_CLKCTRL_CLKEN ;
666682
667683 /* Enable SERCOM clock in PM */
668684 PM -> APBCMASK .reg |= cfg -> pm_apbcmask ;
669-
685+ #endif
670686 /* Disable all I2C interrupts */
671687 i2c -> INTENCLR .reg = SERCOM_I2CM_INTENCLR_MASK ;
672688
@@ -748,30 +764,67 @@ static const struct i2c_driver_api i2c_sam0_driver_api = {
748764#define I2C_SAM0_DMA_CHANNELS (n )
749765#endif
750766
751- #define I2C_SAM0_DEVICE (n ) \
752- static void i2c_sam_irq_config_##n(struct device *dev); \
767+ #define DT_ATMEL_SAM0_I2C_SERCOM_IRQ (n , m ) DT_ATMEL_SAM0_I2C_SERCOM_ ## n ## _IRQ_ ## m
768+ #define DT_ATMEL_SAM0_I2C_SERCOM_IRQ_PRIORITY (n , m ) DT_ATMEL_SAM0_I2C_SERCOM_ ## n ## _IRQ_ ## m ## _PRIORITY
769+
770+ #define SAM0_I2C_IRQ_CONNECT (n , m ) \
771+ do { \
772+ IRQ_CONNECT(DT_ATMEL_SAM0_I2C_SERCOM_IRQ(n, m), \
773+ DT_ATMEL_SAM0_I2C_SERCOM_IRQ_PRIORITY(n, m), \
774+ i2c_sam0_isr, DEVICE_GET(i2c_sam0_##n), 0); \
775+ irq_enable(DT_ATMEL_SAM0_I2C_SERCOM_IRQ(n, m)); \
776+ } while (0)
777+
778+ #ifdef DT_ATMEL_SAM0_I2C_0_IRQ_3
779+ #define I2C_SAM0_IRQ_HANDLER (n ) \
780+ static void i2c_sam0_irq_config_##n(struct device *dev) \
781+ { \
782+ SAM0_I2C_IRQ_CONNECT(n, 0); \
783+ SAM0_I2C_IRQ_CONNECT(n, 1); \
784+ SAM0_I2C_IRQ_CONNECT(n, 2); \
785+ SAM0_I2C_IRQ_CONNECT(n, 3); \
786+ }
787+ #else
788+ #define I2C_SAM0_IRQ_HANDLER (n ) \
789+ static void i2c_sam0_irq_config_##n(struct device *dev) \
790+ { \
791+ SAM0_I2C_IRQ_CONNECT(n, 0); \
792+ }
793+ #endif
794+
795+ #ifdef MCLK
796+ #define I2C_SAM0_CONFIG (n ) \
797+ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \
798+ .regs = (SercomI2cm *)DT_ATMEL_SAM0_I2C_SERCOM_##n##_BASE_ADDRESS, \
799+ .bitrate = DT_ATMEL_SAM0_I2C_SERCOM_##n##_CLOCK_FREQUENCY, \
800+ .mclk = MCLK_SERCOM##n, \
801+ .mclk_mask = MCLK_SERCOM##n##_MASK, \
802+ .gclk_core_id = SERCOM##n##_GCLK_ID_CORE, \
803+ .irq_config_func = &i2c_sam0_irq_config_##n \
804+ I2C_SAM0_DMA_CHANNELS(n) \
805+ }
806+ #else /* !MCLK */
807+ #define I2C_SAM0_CONFIG (n ) \
753808 static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \
754809 .regs = (SercomI2cm *)DT_ATMEL_SAM0_I2C_SERCOM_##n##_BASE_ADDRESS, \
755810 .bitrate = DT_ATMEL_SAM0_I2C_SERCOM_##n##_CLOCK_FREQUENCY, \
756811 .pm_apbcmask = PM_APBCMASK_SERCOM##n, \
757812 .gclk_clkctrl_id = GCLK_CLKCTRL_ID_SERCOM##n##_CORE, \
758- .irq_config_func = &i2c_sam_irq_config_ ##n, \
813+ .irq_config_func = &i2c_sam0_irq_config_ ##n, \
759814 I2C_SAM0_DMA_CHANNELS(n) \
760- }; \
815+ }
816+ #endif
817+
818+ #define I2C_SAM0_DEVICE (n ) \
819+ static void i2c_sam0_irq_config_##n(struct device *dev); \
820+ I2C_SAM0_CONFIG(n); \
761821 static struct i2c_sam0_dev_data i2c_sam0_dev_data_##n; \
762822 DEVICE_AND_API_INIT(i2c_sam0_##n, \
763823 DT_ATMEL_SAM0_I2C_SERCOM_##n##_LABEL, \
764824 &i2c_sam0_initialize, &i2c_sam0_dev_data_##n, \
765825 &i2c_sam0_dev_config_##n, POST_KERNEL, \
766826 CONFIG_I2C_INIT_PRIORITY, &i2c_sam0_driver_api);\
767- static void i2c_sam_irq_config_##n(struct device *dev) \
768- { \
769- IRQ_CONNECT(DT_ATMEL_SAM0_I2C_SERCOM_##n##_IRQ_0, \
770- DT_ATMEL_SAM0_I2C_SERCOM_##n##_IRQ_0_PRIORITY, \
771- i2c_sam0_isr, DEVICE_GET(i2c_sam0_##n), \
772- 0); \
773- irq_enable(DT_ATMEL_SAM0_I2C_SERCOM_##n##_IRQ_0); \
774- }
827+ I2C_SAM0_IRQ_HANDLER(n)
775828
776829#if DT_ATMEL_SAM0_I2C_SERCOM_0_BASE_ADDRESS
777830I2C_SAM0_DEVICE (0 );
0 commit comments