1 /*
2  * Copyright (c) 2021 Argentum Systems Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _ATMEL_SAM_ADC_FIXUP_H_
8 #define _ATMEL_SAM_ADC_FIXUP_H_
9 
10 #if defined(ADC_SYNCBUSY_MASK)
11 #define ADC_SYNC(adc) ((adc)->SYNCBUSY.reg)
12 #define ADC_SYNC_MASK (ADC_SYNCBUSY_MASK)
13 #elif defined(ADC_STATUS_SYNCBUSY)
14 #define ADC_SYNC(adc) ((adc)->STATUS.reg)
15 #define ADC_SYNC_MASK (ADC_STATUS_SYNCBUSY)
16 #else
17 #error ADC not supported...
18 #endif
19 
20 #if defined(ADC_INPUTCTRL_DIFFMODE)
21 #define ADC_DIFF(adc) (inputctrl)
22 #define ADC_DIFF_MASK (ADC_INPUTCTRL_DIFFMODE)
23 #elif defined(ADC_CTRLB_DIFFMODE)
24 #define ADC_DIFF(adc) ((adc)->CTRLB.reg)
25 #define ADC_DIFF_MASK (ADC_CTRLB_DIFFMODE)
26 #elif defined(ADC_CTRLC_DIFFMODE)
27 #define ADC_DIFF(adc) ((adc)->CTRLC.reg)
28 #define ADC_DIFF_MASK (ADC_CTRLC_DIFFMODE)
29 #else
30 #error ADC not supported...
31 #endif
32 
33 #if defined(ADC_CTRLB_RESSEL)
34 #define ADC_RESSEL(adc)  ((adc)->CTRLB.bit.RESSEL)
35 #define ADC_RESSEL_8BIT  ADC_CTRLB_RESSEL_8BIT_Val
36 #define ADC_RESSEL_10BIT ADC_CTRLB_RESSEL_10BIT_Val
37 #define ADC_RESSEL_12BIT ADC_CTRLB_RESSEL_12BIT_Val
38 #define ADC_RESSEL_16BIT ADC_CTRLB_RESSEL_16BIT_Val
39 #elif defined(ADC_CTRLC_RESSEL)
40 #define ADC_RESSEL(adc)  ((adc)->CTRLC.bit.RESSEL)
41 #define ADC_RESSEL_8BIT  ADC_CTRLC_RESSEL_8BIT_Val
42 #define ADC_RESSEL_10BIT ADC_CTRLC_RESSEL_10BIT_Val
43 #define ADC_RESSEL_12BIT ADC_CTRLC_RESSEL_12BIT_Val
44 #define ADC_RESSEL_16BIT ADC_CTRLC_RESSEL_16BIT_Val
45 #else
46 #error ADC not supported...
47 #endif
48 
49 #if defined(ADC_CTRLA_PRESCALER)
50 #define ADC_PRESCALER(adc) ((adc)->CTRLA.bit.PRESCALER)
51 #define ADC_CTRLx_PRESCALER_DIV ADC_CTRLA_PRESCALER_DIV
52 #elif defined(ADC_CTRLB_PRESCALER)
53 #define ADC_PRESCALER(adc) ((adc)->CTRLB.bit.PRESCALER)
54 #define ADC_CTRLx_PRESCALER_DIV ADC_CTRLB_PRESCALER_DIV
55 #else
56 #error ADC not supported...
57 #endif
58 
59 #if defined(SYSCTRL_VREF_TSEN)
60 #define ADC_TSEN (SYSCTRL->VREF.bit.TSEN)
61 #elif defined(SUPC_VREF_TSEN)
62 #define ADC_TSEN (SUPC->VREF.bit.TSEN)
63 #else
64 #error ADC not supported...
65 #endif
66 
67 #if defined(SYSCTRL_VREF_BGOUTEN)
68 #define ADC_BGEN (SYSCTRL->VREF.bit.BGOUTEN)
69 #elif defined(SUPC_VREF_VREFOE)
70 #define ADC_BGEN (SUPC->VREF.bit.VREFOE)
71 #else
72 #error ADC not supported...
73 #endif
74 
75 #if defined(MCLK)
76 /* a trailing underscore and/or lumpy concatenation is used to prevent expansion */
77 #define ADC_SAM0_CALIB(prefix, val) \
78 	UTIL_CAT(ADC_CALIB_, val)( \
79 		(((*(uint32_t *)UTIL_CAT(UTIL_CAT(UTIL_CAT(prefix, FUSES_), val), _ADDR)) \
80 		>> UTIL_CAT(UTIL_CAT(UTIL_CAT(prefix, FUSES_), val), _Pos)) \
81 		& UTIL_CAT(UTIL_CAT(UTIL_CAT(prefix, FUSES_), val), _Msk)) \
82 	)
83 
84 #if ADC_INST_NUM == 1
85 #  define ADC_FUSES_PREFIX(n) ADC_
86 #else
87 #  define ADC_FUSES_PREFIX(n) UTIL_CAT(AD, UTIL_CAT(C, UTIL_CAT(n, _)))
88 #endif
89 
90 #if defined(ADC_FUSES_BIASCOMP) || defined(ADC0_FUSES_BIASCOMP)
91 #  define ADC_SAM0_BIASCOMP(n) ADC_SAM0_CALIB(ADC_FUSES_PREFIX(n), BIASCOMP)
92 #else
93 #  define ADC_SAM0_BIASCOMP(n) 0
94 #endif
95 
96 #if defined(ADC_FUSES_BIASR2R) || defined(ADC0_FUSES_BIASR2R)
97 #  define ADC_SAM0_BIASR2R(n) ADC_SAM0_CALIB(ADC_FUSES_PREFIX(n), BIASR2R)
98 #else
99 #  define ADC_SAM0_BIASR2R(n) 0
100 #endif
101 
102 #if defined(ADC_FUSES_BIASREFBUF) || defined(ADC0_FUSES_BIASREFBUF)
103 #  define ADC_SAM0_BIASREFBUF(n) ADC_SAM0_CALIB(ADC_FUSES_PREFIX(n), BIASREFBUF)
104 #else
105 #  define ADC_SAM0_BIASREFBUF(n) 0
106 #endif
107 
108 /*
109  * The following MCLK clock configuration fix-up symbols map to the applicable
110  * APB-specific symbols, in order to accommodate different SoC series with the
111  * ADC core connected to different APBs.
112  */
113 #if defined(MCLK_APBDMASK_ADC) || defined(MCLK_APBDMASK_ADC0)
114 #  define MCLK_ADC (MCLK->APBDMASK.reg)
115 #elif defined(MCLK_APBCMASK_ADC0)
116 #  define MCLK_ADC (MCLK->APBCMASK.reg)
117 #else
118 #  error ADC not supported...
119 #endif
120 #endif /* MCLK */
121 
122 /*
123  * All SAM0 define the internal voltage reference as 1.0V by default.
124  */
125 #ifndef ADC_REFCTRL_REFSEL_INTERNAL
126 #  ifdef ADC_REFCTRL_REFSEL_INTREF
127 #    define ADC_REFCTRL_REFSEL_INTERNAL ADC_REFCTRL_REFSEL_INTREF
128 #  else
129 #    define ADC_REFCTRL_REFSEL_INTERNAL ADC_REFCTRL_REFSEL_INT1V
130 #  endif
131 #endif
132 
133 /*
134  * Some SAM0 devices can use VDDANA as a direct reference. For the devices
135  * that not offer this option, the internal 1.0V reference will be used.
136  */
137 #ifndef ADC_REFCTRL_REFSEL_VDD_1
138 #  if defined(ADC0_BANDGAP)
139 #    define ADC_REFCTRL_REFSEL_VDD_1 ADC_REFCTRL_REFSEL_INTVCC1
140 #  elif defined(ADC_REFCTRL_REFSEL_INTVCC2)
141 #    define ADC_REFCTRL_REFSEL_VDD_1 ADC_REFCTRL_REFSEL_INTVCC2
142 #  endif
143 #endif
144 
145 /*
146  * SAMD/E5x define ADC[0-1]_BANDGAP symbol. Only those devices use INTVCC0 to
147  * implement VDDANA / 2.
148  */
149 #ifndef ADC_REFCTRL_REFSEL_VDD_1_2
150 #  ifdef ADC0_BANDGAP
151 #    define ADC_REFCTRL_REFSEL_VDD_1_2 ADC_REFCTRL_REFSEL_INTVCC0
152 #  else
153 #    define ADC_REFCTRL_REFSEL_VDD_1_2 ADC_REFCTRL_REFSEL_INTVCC1
154 #  endif
155 #endif
156 
157 #endif /* _ATMEL_SAM0_ADC_FIXUP_H_ */
158