Commit | Line | Data |
---|---|---|
3adbf342 MB |
1 | /* |
2 | * Amlogic Meson Successive Approximation Register (SAR) A/D Converter | |
3 | * | |
4 | * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * You should have received a copy of the GNU General Public License | |
11 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12 | */ | |
13 | ||
14 | #include <linux/bitfield.h> | |
15 | #include <linux/clk.h> | |
16 | #include <linux/clk-provider.h> | |
17 | #include <linux/delay.h> | |
18 | #include <linux/io.h> | |
19 | #include <linux/iio/iio.h> | |
20 | #include <linux/module.h> | |
3af10913 | 21 | #include <linux/interrupt.h> |
3adbf342 | 22 | #include <linux/of.h> |
3af10913 | 23 | #include <linux/of_irq.h> |
3adbf342 MB |
24 | #include <linux/of_device.h> |
25 | #include <linux/platform_device.h> | |
26 | #include <linux/regmap.h> | |
27 | #include <linux/regulator/consumer.h> | |
28 | ||
29 | #define MESON_SAR_ADC_REG0 0x00 | |
30 | #define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31) | |
31 | #define MESON_SAR_ADC_REG0_BUSY_MASK GENMASK(30, 28) | |
32 | #define MESON_SAR_ADC_REG0_DELTA_BUSY BIT(30) | |
33 | #define MESON_SAR_ADC_REG0_AVG_BUSY BIT(29) | |
34 | #define MESON_SAR_ADC_REG0_SAMPLE_BUSY BIT(28) | |
35 | #define MESON_SAR_ADC_REG0_FIFO_FULL BIT(27) | |
36 | #define MESON_SAR_ADC_REG0_FIFO_EMPTY BIT(26) | |
37 | #define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK GENMASK(25, 21) | |
38 | #define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK GENMASK(20, 19) | |
39 | #define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK GENMASK(18, 16) | |
40 | #define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL BIT(15) | |
41 | #define MESON_SAR_ADC_REG0_SAMPLING_STOP BIT(14) | |
42 | #define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK GENMASK(13, 12) | |
43 | #define MESON_SAR_ADC_REG0_DETECT_IRQ_POL BIT(10) | |
44 | #define MESON_SAR_ADC_REG0_DETECT_IRQ_EN BIT(9) | |
45 | #define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK GENMASK(8, 4) | |
46 | #define MESON_SAR_ADC_REG0_FIFO_IRQ_EN BIT(3) | |
47 | #define MESON_SAR_ADC_REG0_SAMPLING_START BIT(2) | |
48 | #define MESON_SAR_ADC_REG0_CONTINUOUS_EN BIT(1) | |
49 | #define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE BIT(0) | |
50 | ||
51 | #define MESON_SAR_ADC_CHAN_LIST 0x04 | |
52 | #define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK GENMASK(26, 24) | |
53 | #define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan) \ | |
54 | (GENMASK(2, 0) << ((_chan) * 3)) | |
55 | ||
56 | #define MESON_SAR_ADC_AVG_CNTL 0x08 | |
57 | #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan) \ | |
58 | (16 + ((_chan) * 2)) | |
59 | #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan) \ | |
60 | (GENMASK(17, 16) << ((_chan) * 2)) | |
61 | #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \ | |
62 | (0 + ((_chan) * 2)) | |
63 | #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan) \ | |
64 | (GENMASK(1, 0) << ((_chan) * 2)) | |
65 | ||
66 | #define MESON_SAR_ADC_REG3 0x0c | |
67 | #define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY BIT(31) | |
68 | #define MESON_SAR_ADC_REG3_CLK_EN BIT(30) | |
69 | #define MESON_SAR_ADC_REG3_BL30_INITIALIZED BIT(28) | |
70 | #define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN BIT(27) | |
71 | #define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE BIT(26) | |
72 | #define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK GENMASK(25, 23) | |
73 | #define MESON_SAR_ADC_REG3_DETECT_EN BIT(22) | |
74 | #define MESON_SAR_ADC_REG3_ADC_EN BIT(21) | |
75 | #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18) | |
76 | #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16) | |
77 | #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10 | |
78 | #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5 | |
79 | #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8) | |
80 | #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0) | |
81 | ||
82 | #define MESON_SAR_ADC_DELAY 0x10 | |
83 | #define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK GENMASK(25, 24) | |
84 | #define MESON_SAR_ADC_DELAY_BL30_BUSY BIT(15) | |
85 | #define MESON_SAR_ADC_DELAY_KERNEL_BUSY BIT(14) | |
86 | #define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK GENMASK(23, 16) | |
87 | #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK GENMASK(9, 8) | |
88 | #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK GENMASK(7, 0) | |
89 | ||
90 | #define MESON_SAR_ADC_LAST_RD 0x14 | |
91 | #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK GENMASK(23, 16) | |
92 | #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK GENMASK(9, 0) | |
93 | ||
94 | #define MESON_SAR_ADC_FIFO_RD 0x18 | |
95 | #define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK GENMASK(14, 12) | |
96 | #define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0) | |
97 | ||
98 | #define MESON_SAR_ADC_AUX_SW 0x1c | |
ab569a4c MB |
99 | #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(_chan) \ |
100 | (8 + (((_chan) - 2) * 3)) | |
3adbf342 MB |
101 | #define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6) |
102 | #define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5) | |
103 | #define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4) | |
104 | #define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW BIT(3) | |
105 | #define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW BIT(2) | |
106 | #define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW BIT(1) | |
107 | #define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW BIT(0) | |
108 | ||
109 | #define MESON_SAR_ADC_CHAN_10_SW 0x20 | |
110 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK GENMASK(25, 23) | |
111 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX BIT(22) | |
112 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX BIT(21) | |
113 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL BIT(20) | |
114 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW BIT(19) | |
115 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW BIT(18) | |
116 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW BIT(17) | |
117 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW BIT(16) | |
118 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK GENMASK(9, 7) | |
119 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX BIT(6) | |
120 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX BIT(5) | |
121 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL BIT(4) | |
122 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW BIT(3) | |
123 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW BIT(2) | |
124 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW BIT(1) | |
125 | #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW BIT(0) | |
126 | ||
127 | #define MESON_SAR_ADC_DETECT_IDLE_SW 0x24 | |
128 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN BIT(26) | |
129 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK GENMASK(25, 23) | |
130 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX BIT(22) | |
131 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX BIT(21) | |
132 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL BIT(20) | |
133 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19) | |
134 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18) | |
135 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17) | |
136 | #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16) | |
137 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK GENMASK(9, 7) | |
138 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX BIT(6) | |
139 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX BIT(5) | |
140 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL BIT(4) | |
141 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW BIT(3) | |
142 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW BIT(2) | |
143 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW BIT(1) | |
144 | #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW BIT(0) | |
145 | ||
146 | #define MESON_SAR_ADC_DELTA_10 0x28 | |
147 | #define MESON_SAR_ADC_DELTA_10_TEMP_SEL BIT(27) | |
148 | #define MESON_SAR_ADC_DELTA_10_TS_REVE1 BIT(26) | |
149 | #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK GENMASK(25, 16) | |
150 | #define MESON_SAR_ADC_DELTA_10_TS_REVE0 BIT(15) | |
151 | #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT 11 | |
152 | #define MESON_SAR_ADC_DELTA_10_TS_C_MASK GENMASK(14, 11) | |
153 | #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN BIT(10) | |
154 | #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK GENMASK(9, 0) | |
155 | ||
156 | /* | |
157 | * NOTE: registers from here are undocumented (the vendor Linux kernel driver | |
158 | * and u-boot source served as reference). These only seem to be relevant on | |
159 | * GXBB and newer. | |
160 | */ | |
161 | #define MESON_SAR_ADC_REG11 0x2c | |
162 | #define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13) | |
163 | ||
164 | #define MESON_SAR_ADC_REG13 0x34 | |
165 | #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK GENMASK(13, 8) | |
166 | ||
167 | #define MESON_SAR_ADC_MAX_FIFO_SIZE 32 | |
3af10913 | 168 | #define MESON_SAR_ADC_TIMEOUT 100 /* ms */ |
48ba7c3c HK |
169 | /* for use with IIO_VAL_INT_PLUS_MICRO */ |
170 | #define MILLION 1000000 | |
3adbf342 MB |
171 | |
172 | #define MESON_SAR_ADC_CHAN(_chan) { \ | |
173 | .type = IIO_VOLTAGE, \ | |
174 | .indexed = 1, \ | |
175 | .channel = _chan, \ | |
176 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | |
177 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), \ | |
48ba7c3c HK |
178 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ |
179 | BIT(IIO_CHAN_INFO_CALIBBIAS) | \ | |
180 | BIT(IIO_CHAN_INFO_CALIBSCALE), \ | |
3adbf342 MB |
181 | .datasheet_name = "SAR_ADC_CH"#_chan, \ |
182 | } | |
183 | ||
184 | /* | |
185 | * TODO: the hardware supports IIO_TEMP for channel 6 as well which is | |
186 | * currently not supported by this driver. | |
187 | */ | |
188 | static const struct iio_chan_spec meson_sar_adc_iio_channels[] = { | |
189 | MESON_SAR_ADC_CHAN(0), | |
190 | MESON_SAR_ADC_CHAN(1), | |
191 | MESON_SAR_ADC_CHAN(2), | |
192 | MESON_SAR_ADC_CHAN(3), | |
193 | MESON_SAR_ADC_CHAN(4), | |
194 | MESON_SAR_ADC_CHAN(5), | |
195 | MESON_SAR_ADC_CHAN(6), | |
196 | MESON_SAR_ADC_CHAN(7), | |
197 | IIO_CHAN_SOFT_TIMESTAMP(8), | |
198 | }; | |
199 | ||
200 | enum meson_sar_adc_avg_mode { | |
201 | NO_AVERAGING = 0x0, | |
202 | MEAN_AVERAGING = 0x1, | |
203 | MEDIAN_AVERAGING = 0x2, | |
204 | }; | |
205 | ||
206 | enum meson_sar_adc_num_samples { | |
207 | ONE_SAMPLE = 0x0, | |
208 | TWO_SAMPLES = 0x1, | |
209 | FOUR_SAMPLES = 0x2, | |
210 | EIGHT_SAMPLES = 0x3, | |
211 | }; | |
212 | ||
213 | enum meson_sar_adc_chan7_mux_sel { | |
214 | CHAN7_MUX_VSS = 0x0, | |
215 | CHAN7_MUX_VDD_DIV4 = 0x1, | |
216 | CHAN7_MUX_VDD_DIV2 = 0x2, | |
217 | CHAN7_MUX_VDD_MUL3_DIV4 = 0x3, | |
218 | CHAN7_MUX_VDD = 0x4, | |
219 | CHAN7_MUX_CH7_INPUT = 0x7, | |
220 | }; | |
221 | ||
222 | struct meson_sar_adc_data { | |
6c76ed31 | 223 | bool has_bl30_integration; |
fda29dba | 224 | unsigned long clock_rate; |
d85eed9f | 225 | u32 bandgap_reg; |
3adbf342 MB |
226 | unsigned int resolution; |
227 | const char *name; | |
96748823 | 228 | const struct regmap_config *regmap_config; |
3adbf342 MB |
229 | }; |
230 | ||
231 | struct meson_sar_adc_priv { | |
232 | struct regmap *regmap; | |
233 | struct regulator *vref; | |
234 | const struct meson_sar_adc_data *data; | |
235 | struct clk *clkin; | |
236 | struct clk *core_clk; | |
3adbf342 MB |
237 | struct clk *adc_sel_clk; |
238 | struct clk *adc_clk; | |
239 | struct clk_gate clk_gate; | |
240 | struct clk *adc_div_clk; | |
241 | struct clk_divider clk_div; | |
3af10913 | 242 | struct completion done; |
48ba7c3c HK |
243 | int calibbias; |
244 | int calibscale; | |
3adbf342 MB |
245 | }; |
246 | ||
96748823 | 247 | static const struct regmap_config meson_sar_adc_regmap_config_gxbb = { |
3adbf342 MB |
248 | .reg_bits = 8, |
249 | .val_bits = 32, | |
250 | .reg_stride = 4, | |
251 | .max_register = MESON_SAR_ADC_REG13, | |
252 | }; | |
253 | ||
96748823 MB |
254 | static const struct regmap_config meson_sar_adc_regmap_config_meson8 = { |
255 | .reg_bits = 8, | |
256 | .val_bits = 32, | |
257 | .reg_stride = 4, | |
258 | .max_register = MESON_SAR_ADC_DELTA_10, | |
259 | }; | |
260 | ||
3adbf342 MB |
261 | static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev) |
262 | { | |
263 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
264 | u32 regval; | |
265 | ||
266 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
267 | ||
268 | return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval); | |
269 | } | |
270 | ||
48ba7c3c HK |
271 | static int meson_sar_adc_calib_val(struct iio_dev *indio_dev, int val) |
272 | { | |
273 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
274 | int tmp; | |
275 | ||
276 | /* use val_calib = scale * val_raw + offset calibration function */ | |
277 | tmp = div_s64((s64)val * priv->calibscale, MILLION) + priv->calibbias; | |
278 | ||
279 | return clamp(tmp, 0, (1 << priv->data->resolution) - 1); | |
280 | } | |
281 | ||
3adbf342 MB |
282 | static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev) |
283 | { | |
284 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
285 | int regval, timeout = 10000; | |
286 | ||
287 | /* | |
288 | * NOTE: we need a small delay before reading the status, otherwise | |
289 | * the sample engine may not have started internally (which would | |
290 | * seem to us that sampling is already finished). | |
291 | */ | |
292 | do { | |
293 | udelay(1); | |
294 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
295 | } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--); | |
296 | ||
297 | if (timeout < 0) | |
298 | return -ETIMEDOUT; | |
299 | ||
300 | return 0; | |
301 | } | |
302 | ||
303 | static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev, | |
304 | const struct iio_chan_spec *chan, | |
305 | int *val) | |
306 | { | |
307 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
6a882a2c | 308 | int regval, fifo_chan, fifo_val, count; |
3adbf342 | 309 | |
3af10913 HK |
310 | if(!wait_for_completion_timeout(&priv->done, |
311 | msecs_to_jiffies(MESON_SAR_ADC_TIMEOUT))) | |
312 | return -ETIMEDOUT; | |
3adbf342 | 313 | |
6a882a2c HK |
314 | count = meson_sar_adc_get_fifo_count(indio_dev); |
315 | if (count != 1) { | |
316 | dev_err(&indio_dev->dev, | |
317 | "ADC FIFO has %d element(s) instead of one\n", count); | |
318 | return -EINVAL; | |
3adbf342 MB |
319 | } |
320 | ||
6a882a2c HK |
321 | regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, ®val); |
322 | fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval); | |
323 | if (fifo_chan != chan->channel) { | |
324 | dev_err(&indio_dev->dev, | |
325 | "ADC FIFO entry belongs to channel %d instead of %d\n", | |
326 | fifo_chan, chan->channel); | |
327 | return -EINVAL; | |
328 | } | |
3adbf342 | 329 | |
6a882a2c HK |
330 | fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, regval); |
331 | fifo_val &= GENMASK(priv->data->resolution - 1, 0); | |
48ba7c3c | 332 | *val = meson_sar_adc_calib_val(indio_dev, fifo_val); |
3adbf342 MB |
333 | |
334 | return 0; | |
335 | } | |
336 | ||
337 | static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev, | |
338 | const struct iio_chan_spec *chan, | |
339 | enum meson_sar_adc_avg_mode mode, | |
340 | enum meson_sar_adc_num_samples samples) | |
341 | { | |
342 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
343 | int val, channel = chan->channel; | |
344 | ||
345 | val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel); | |
346 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, | |
347 | MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel), | |
348 | val); | |
349 | ||
350 | val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel); | |
351 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, | |
352 | MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val); | |
353 | } | |
354 | ||
355 | static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev, | |
356 | const struct iio_chan_spec *chan) | |
357 | { | |
358 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
359 | u32 regval; | |
360 | ||
361 | /* | |
362 | * the SAR ADC engine allows sampling multiple channels at the same | |
363 | * time. to keep it simple we're only working with one *internal* | |
364 | * channel, which starts counting at index 0 (which means: count = 1). | |
365 | */ | |
366 | regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0); | |
367 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, | |
368 | MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval); | |
369 | ||
370 | /* map channel index 0 to the channel which we want to read */ | |
371 | regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), | |
372 | chan->channel); | |
373 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, | |
374 | MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval); | |
375 | ||
376 | regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK, | |
377 | chan->channel); | |
378 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, | |
379 | MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK, | |
380 | regval); | |
381 | ||
382 | regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, | |
383 | chan->channel); | |
384 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, | |
385 | MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, | |
386 | regval); | |
387 | ||
388 | if (chan->channel == 6) | |
389 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | |
390 | MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0); | |
391 | } | |
392 | ||
393 | static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev, | |
394 | enum meson_sar_adc_chan7_mux_sel sel) | |
395 | { | |
396 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
397 | u32 regval; | |
398 | ||
399 | regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel); | |
400 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
401 | MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval); | |
402 | ||
403 | usleep_range(10, 20); | |
404 | } | |
405 | ||
406 | static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev) | |
407 | { | |
408 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
409 | ||
3af10913 HK |
410 | reinit_completion(&priv->done); |
411 | ||
412 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
413 | MESON_SAR_ADC_REG0_FIFO_IRQ_EN, | |
414 | MESON_SAR_ADC_REG0_FIFO_IRQ_EN); | |
415 | ||
3adbf342 MB |
416 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
417 | MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, | |
418 | MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE); | |
419 | ||
420 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
421 | MESON_SAR_ADC_REG0_SAMPLING_START, | |
422 | MESON_SAR_ADC_REG0_SAMPLING_START); | |
423 | } | |
424 | ||
425 | static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev) | |
426 | { | |
427 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
428 | ||
3af10913 HK |
429 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
430 | MESON_SAR_ADC_REG0_FIFO_IRQ_EN, 0); | |
431 | ||
3adbf342 MB |
432 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
433 | MESON_SAR_ADC_REG0_SAMPLING_STOP, | |
434 | MESON_SAR_ADC_REG0_SAMPLING_STOP); | |
435 | ||
436 | /* wait until all modules are stopped */ | |
437 | meson_sar_adc_wait_busy_clear(indio_dev); | |
438 | ||
439 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
440 | MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0); | |
441 | } | |
442 | ||
443 | static int meson_sar_adc_lock(struct iio_dev *indio_dev) | |
444 | { | |
445 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
446 | int val, timeout = 10000; | |
447 | ||
448 | mutex_lock(&indio_dev->mlock); | |
449 | ||
6c76ed31 MB |
450 | if (priv->data->has_bl30_integration) { |
451 | /* prevent BL30 from using the SAR ADC while we are using it */ | |
452 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
453 | MESON_SAR_ADC_DELAY_KERNEL_BUSY, | |
454 | MESON_SAR_ADC_DELAY_KERNEL_BUSY); | |
455 | ||
456 | /* | |
457 | * wait until BL30 releases it's lock (so we can use the SAR | |
458 | * ADC) | |
459 | */ | |
460 | do { | |
461 | udelay(1); | |
462 | regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val); | |
463 | } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--); | |
464 | ||
3c3e4b3a DC |
465 | if (timeout < 0) { |
466 | mutex_unlock(&indio_dev->mlock); | |
6c76ed31 | 467 | return -ETIMEDOUT; |
3c3e4b3a | 468 | } |
6c76ed31 | 469 | } |
3adbf342 MB |
470 | |
471 | return 0; | |
472 | } | |
473 | ||
474 | static void meson_sar_adc_unlock(struct iio_dev *indio_dev) | |
475 | { | |
476 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
477 | ||
6c76ed31 MB |
478 | if (priv->data->has_bl30_integration) |
479 | /* allow BL30 to use the SAR ADC again */ | |
480 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
481 | MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); | |
3adbf342 MB |
482 | |
483 | mutex_unlock(&indio_dev->mlock); | |
484 | } | |
485 | ||
486 | static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) | |
487 | { | |
488 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
103a07d4 | 489 | unsigned int count, tmp; |
3adbf342 MB |
490 | |
491 | for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) { | |
492 | if (!meson_sar_adc_get_fifo_count(indio_dev)) | |
493 | break; | |
494 | ||
103a07d4 | 495 | regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp); |
3adbf342 MB |
496 | } |
497 | } | |
498 | ||
499 | static int meson_sar_adc_get_sample(struct iio_dev *indio_dev, | |
500 | const struct iio_chan_spec *chan, | |
501 | enum meson_sar_adc_avg_mode avg_mode, | |
502 | enum meson_sar_adc_num_samples avg_samples, | |
503 | int *val) | |
504 | { | |
505 | int ret; | |
506 | ||
507 | ret = meson_sar_adc_lock(indio_dev); | |
508 | if (ret) | |
509 | return ret; | |
510 | ||
511 | /* clear the FIFO to make sure we're not reading old values */ | |
512 | meson_sar_adc_clear_fifo(indio_dev); | |
513 | ||
514 | meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples); | |
515 | ||
516 | meson_sar_adc_enable_channel(indio_dev, chan); | |
517 | ||
518 | meson_sar_adc_start_sample_engine(indio_dev); | |
519 | ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val); | |
520 | meson_sar_adc_stop_sample_engine(indio_dev); | |
521 | ||
522 | meson_sar_adc_unlock(indio_dev); | |
523 | ||
524 | if (ret) { | |
525 | dev_warn(indio_dev->dev.parent, | |
526 | "failed to read sample for channel %d: %d\n", | |
527 | chan->channel, ret); | |
528 | return ret; | |
529 | } | |
530 | ||
531 | return IIO_VAL_INT; | |
532 | } | |
533 | ||
534 | static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev, | |
535 | const struct iio_chan_spec *chan, | |
536 | int *val, int *val2, long mask) | |
537 | { | |
538 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
539 | int ret; | |
540 | ||
541 | switch (mask) { | |
542 | case IIO_CHAN_INFO_RAW: | |
543 | return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING, | |
544 | ONE_SAMPLE, val); | |
545 | break; | |
546 | ||
547 | case IIO_CHAN_INFO_AVERAGE_RAW: | |
548 | return meson_sar_adc_get_sample(indio_dev, chan, | |
549 | MEAN_AVERAGING, EIGHT_SAMPLES, | |
550 | val); | |
551 | break; | |
552 | ||
553 | case IIO_CHAN_INFO_SCALE: | |
554 | ret = regulator_get_voltage(priv->vref); | |
555 | if (ret < 0) { | |
556 | dev_err(indio_dev->dev.parent, | |
557 | "failed to get vref voltage: %d\n", ret); | |
558 | return ret; | |
559 | } | |
560 | ||
561 | *val = ret / 1000; | |
562 | *val2 = priv->data->resolution; | |
563 | return IIO_VAL_FRACTIONAL_LOG2; | |
564 | ||
48ba7c3c HK |
565 | case IIO_CHAN_INFO_CALIBBIAS: |
566 | *val = priv->calibbias; | |
567 | return IIO_VAL_INT; | |
568 | ||
569 | case IIO_CHAN_INFO_CALIBSCALE: | |
570 | *val = priv->calibscale / MILLION; | |
571 | *val2 = priv->calibscale % MILLION; | |
572 | return IIO_VAL_INT_PLUS_MICRO; | |
573 | ||
3adbf342 MB |
574 | default: |
575 | return -EINVAL; | |
576 | } | |
577 | } | |
578 | ||
579 | static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, | |
580 | void __iomem *base) | |
581 | { | |
582 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
583 | struct clk_init_data init; | |
584 | const char *clk_parents[1]; | |
585 | ||
3921db46 RH |
586 | init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_div", |
587 | indio_dev->dev.of_node); | |
3adbf342 MB |
588 | init.flags = 0; |
589 | init.ops = &clk_divider_ops; | |
590 | clk_parents[0] = __clk_get_name(priv->clkin); | |
591 | init.parent_names = clk_parents; | |
592 | init.num_parents = 1; | |
593 | ||
594 | priv->clk_div.reg = base + MESON_SAR_ADC_REG3; | |
595 | priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT; | |
596 | priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH; | |
597 | priv->clk_div.hw.init = &init; | |
598 | priv->clk_div.flags = 0; | |
599 | ||
600 | priv->adc_div_clk = devm_clk_register(&indio_dev->dev, | |
601 | &priv->clk_div.hw); | |
602 | if (WARN_ON(IS_ERR(priv->adc_div_clk))) | |
603 | return PTR_ERR(priv->adc_div_clk); | |
604 | ||
3921db46 RH |
605 | init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_en", |
606 | indio_dev->dev.of_node); | |
3adbf342 MB |
607 | init.flags = CLK_SET_RATE_PARENT; |
608 | init.ops = &clk_gate_ops; | |
609 | clk_parents[0] = __clk_get_name(priv->adc_div_clk); | |
610 | init.parent_names = clk_parents; | |
611 | init.num_parents = 1; | |
612 | ||
613 | priv->clk_gate.reg = base + MESON_SAR_ADC_REG3; | |
7a6b0420 | 614 | priv->clk_gate.bit_idx = __ffs(MESON_SAR_ADC_REG3_CLK_EN); |
3adbf342 MB |
615 | priv->clk_gate.hw.init = &init; |
616 | ||
617 | priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw); | |
618 | if (WARN_ON(IS_ERR(priv->adc_clk))) | |
619 | return PTR_ERR(priv->adc_clk); | |
620 | ||
621 | return 0; | |
622 | } | |
623 | ||
624 | static int meson_sar_adc_init(struct iio_dev *indio_dev) | |
625 | { | |
626 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
ab569a4c | 627 | int regval, i, ret; |
3adbf342 MB |
628 | |
629 | /* | |
630 | * make sure we start at CH7 input since the other muxes are only used | |
631 | * for internal calibration. | |
632 | */ | |
633 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); | |
634 | ||
6c76ed31 MB |
635 | if (priv->data->has_bl30_integration) { |
636 | /* | |
637 | * leave sampling delay and the input clocks as configured by | |
638 | * BL30 to make sure BL30 gets the values it expects when | |
639 | * reading the temperature sensor. | |
640 | */ | |
641 | regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val); | |
642 | if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) | |
643 | return 0; | |
644 | } | |
3adbf342 MB |
645 | |
646 | meson_sar_adc_stop_sample_engine(indio_dev); | |
647 | ||
648 | /* update the channel 6 MUX to select the temperature sensor */ | |
649 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
650 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, | |
651 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL); | |
652 | ||
653 | /* disable all channels by default */ | |
654 | regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); | |
655 | ||
656 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
657 | MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0); | |
658 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
659 | MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY, | |
660 | MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY); | |
661 | ||
662 | /* delay between two samples = (10+1) * 1uS */ | |
663 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
664 | MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
665 | FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK, | |
666 | 10)); | |
667 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
668 | MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, | |
669 | FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, | |
670 | 0)); | |
671 | ||
672 | /* delay between two samples = (10+1) * 1uS */ | |
673 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
674 | MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
675 | FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
676 | 10)); | |
677 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
678 | MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, | |
679 | FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, | |
680 | 1)); | |
681 | ||
ab569a4c MB |
682 | /* |
683 | * set up the input channel muxes in MESON_SAR_ADC_CHAN_10_SW | |
684 | * (0 = SAR_ADC_CH0, 1 = SAR_ADC_CH1) | |
685 | */ | |
686 | regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK, 0); | |
687 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, | |
688 | MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK, | |
689 | regval); | |
690 | regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK, 1); | |
691 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, | |
692 | MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK, | |
693 | regval); | |
694 | ||
695 | /* | |
696 | * set up the input channel muxes in MESON_SAR_ADC_AUX_SW | |
697 | * (2 = SAR_ADC_CH2, 3 = SAR_ADC_CH3, ...) and enable | |
698 | * MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW and | |
699 | * MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW like the vendor driver. | |
700 | */ | |
701 | regval = 0; | |
702 | for (i = 2; i <= 7; i++) | |
703 | regval |= i << MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(i); | |
704 | regval |= MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW; | |
705 | regval |= MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW; | |
706 | regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval); | |
707 | ||
3adbf342 MB |
708 | ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); |
709 | if (ret) { | |
710 | dev_err(indio_dev->dev.parent, | |
711 | "failed to set adc parent to clkin\n"); | |
712 | return ret; | |
713 | } | |
714 | ||
fda29dba | 715 | ret = clk_set_rate(priv->adc_clk, priv->data->clock_rate); |
3adbf342 MB |
716 | if (ret) { |
717 | dev_err(indio_dev->dev.parent, | |
718 | "failed to set adc clock rate\n"); | |
719 | return ret; | |
720 | } | |
721 | ||
722 | return 0; | |
723 | } | |
724 | ||
d85eed9f MB |
725 | static void meson_sar_adc_set_bandgap(struct iio_dev *indio_dev, bool on_off) |
726 | { | |
727 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
728 | u32 enable_mask; | |
729 | ||
730 | if (priv->data->bandgap_reg == MESON_SAR_ADC_REG11) | |
731 | enable_mask = MESON_SAR_ADC_REG11_BANDGAP_EN; | |
732 | else | |
733 | enable_mask = MESON_SAR_ADC_DELTA_10_TS_VBG_EN; | |
734 | ||
735 | regmap_update_bits(priv->regmap, priv->data->bandgap_reg, enable_mask, | |
736 | on_off ? enable_mask : 0); | |
737 | } | |
738 | ||
3adbf342 MB |
739 | static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev) |
740 | { | |
741 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
742 | int ret; | |
3af10913 | 743 | u32 regval; |
3adbf342 MB |
744 | |
745 | ret = meson_sar_adc_lock(indio_dev); | |
746 | if (ret) | |
747 | goto err_lock; | |
748 | ||
749 | ret = regulator_enable(priv->vref); | |
750 | if (ret < 0) { | |
751 | dev_err(indio_dev->dev.parent, | |
752 | "failed to enable vref regulator\n"); | |
753 | goto err_vref; | |
754 | } | |
755 | ||
756 | ret = clk_prepare_enable(priv->core_clk); | |
757 | if (ret) { | |
758 | dev_err(indio_dev->dev.parent, "failed to enable core clk\n"); | |
759 | goto err_core_clk; | |
760 | } | |
761 | ||
3af10913 HK |
762 | regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1); |
763 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
764 | MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); | |
d85eed9f MB |
765 | |
766 | meson_sar_adc_set_bandgap(indio_dev, true); | |
767 | ||
3adbf342 MB |
768 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, |
769 | MESON_SAR_ADC_REG3_ADC_EN, | |
770 | MESON_SAR_ADC_REG3_ADC_EN); | |
771 | ||
772 | udelay(5); | |
773 | ||
774 | ret = clk_prepare_enable(priv->adc_clk); | |
775 | if (ret) { | |
776 | dev_err(indio_dev->dev.parent, "failed to enable adc clk\n"); | |
777 | goto err_adc_clk; | |
778 | } | |
779 | ||
780 | meson_sar_adc_unlock(indio_dev); | |
781 | ||
782 | return 0; | |
783 | ||
784 | err_adc_clk: | |
785 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
786 | MESON_SAR_ADC_REG3_ADC_EN, 0); | |
d85eed9f | 787 | meson_sar_adc_set_bandgap(indio_dev, false); |
3adbf342 MB |
788 | clk_disable_unprepare(priv->core_clk); |
789 | err_core_clk: | |
790 | regulator_disable(priv->vref); | |
791 | err_vref: | |
792 | meson_sar_adc_unlock(indio_dev); | |
793 | err_lock: | |
794 | return ret; | |
795 | } | |
796 | ||
797 | static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev) | |
798 | { | |
799 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
800 | int ret; | |
801 | ||
802 | ret = meson_sar_adc_lock(indio_dev); | |
803 | if (ret) | |
804 | return ret; | |
805 | ||
806 | clk_disable_unprepare(priv->adc_clk); | |
807 | ||
808 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
809 | MESON_SAR_ADC_REG3_ADC_EN, 0); | |
d85eed9f MB |
810 | |
811 | meson_sar_adc_set_bandgap(indio_dev, false); | |
3adbf342 | 812 | |
3adbf342 MB |
813 | clk_disable_unprepare(priv->core_clk); |
814 | ||
815 | regulator_disable(priv->vref); | |
816 | ||
817 | meson_sar_adc_unlock(indio_dev); | |
818 | ||
819 | return 0; | |
820 | } | |
821 | ||
3af10913 HK |
822 | static irqreturn_t meson_sar_adc_irq(int irq, void *data) |
823 | { | |
824 | struct iio_dev *indio_dev = data; | |
825 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
826 | unsigned int cnt, threshold; | |
827 | u32 regval; | |
828 | ||
829 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
830 | cnt = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval); | |
831 | threshold = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); | |
832 | ||
833 | if (cnt < threshold) | |
834 | return IRQ_NONE; | |
835 | ||
836 | complete(&priv->done); | |
837 | ||
838 | return IRQ_HANDLED; | |
839 | } | |
840 | ||
48ba7c3c HK |
841 | static int meson_sar_adc_calib(struct iio_dev *indio_dev) |
842 | { | |
843 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
844 | int ret, nominal0, nominal1, value0, value1; | |
845 | ||
846 | /* use points 25% and 75% for calibration */ | |
847 | nominal0 = (1 << priv->data->resolution) / 4; | |
848 | nominal1 = (1 << priv->data->resolution) * 3 / 4; | |
849 | ||
850 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_DIV4); | |
851 | usleep_range(10, 20); | |
852 | ret = meson_sar_adc_get_sample(indio_dev, | |
853 | &meson_sar_adc_iio_channels[7], | |
854 | MEAN_AVERAGING, EIGHT_SAMPLES, &value0); | |
855 | if (ret < 0) | |
856 | goto out; | |
857 | ||
858 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_MUL3_DIV4); | |
859 | usleep_range(10, 20); | |
860 | ret = meson_sar_adc_get_sample(indio_dev, | |
861 | &meson_sar_adc_iio_channels[7], | |
862 | MEAN_AVERAGING, EIGHT_SAMPLES, &value1); | |
863 | if (ret < 0) | |
864 | goto out; | |
865 | ||
866 | if (value1 <= value0) { | |
867 | ret = -EINVAL; | |
868 | goto out; | |
869 | } | |
870 | ||
871 | priv->calibscale = div_s64((nominal1 - nominal0) * (s64)MILLION, | |
872 | value1 - value0); | |
873 | priv->calibbias = nominal0 - div_s64((s64)value0 * priv->calibscale, | |
874 | MILLION); | |
875 | ret = 0; | |
876 | out: | |
877 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); | |
878 | ||
879 | return ret; | |
880 | } | |
881 | ||
3adbf342 MB |
882 | static const struct iio_info meson_sar_adc_iio_info = { |
883 | .read_raw = meson_sar_adc_iio_info_read_raw, | |
3adbf342 MB |
884 | }; |
885 | ||
6c76ed31 MB |
886 | static const struct meson_sar_adc_data meson_sar_adc_meson8_data = { |
887 | .has_bl30_integration = false, | |
fda29dba | 888 | .clock_rate = 1150000, |
d85eed9f | 889 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, |
96748823 | 890 | .regmap_config = &meson_sar_adc_regmap_config_meson8, |
6c76ed31 MB |
891 | .resolution = 10, |
892 | .name = "meson-meson8-saradc", | |
893 | }; | |
894 | ||
895 | static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = { | |
896 | .has_bl30_integration = false, | |
fda29dba | 897 | .clock_rate = 1150000, |
d85eed9f | 898 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, |
96748823 | 899 | .regmap_config = &meson_sar_adc_regmap_config_meson8, |
6c76ed31 MB |
900 | .resolution = 10, |
901 | .name = "meson-meson8b-saradc", | |
902 | }; | |
903 | ||
c1c2de37 | 904 | static const struct meson_sar_adc_data meson_sar_adc_gxbb_data = { |
6c76ed31 | 905 | .has_bl30_integration = true, |
fda29dba | 906 | .clock_rate = 1200000, |
d85eed9f | 907 | .bandgap_reg = MESON_SAR_ADC_REG11, |
96748823 | 908 | .regmap_config = &meson_sar_adc_regmap_config_gxbb, |
3adbf342 MB |
909 | .resolution = 10, |
910 | .name = "meson-gxbb-saradc", | |
911 | }; | |
912 | ||
c1c2de37 | 913 | static const struct meson_sar_adc_data meson_sar_adc_gxl_data = { |
6c76ed31 | 914 | .has_bl30_integration = true, |
fda29dba | 915 | .clock_rate = 1200000, |
d85eed9f | 916 | .bandgap_reg = MESON_SAR_ADC_REG11, |
96748823 | 917 | .regmap_config = &meson_sar_adc_regmap_config_gxbb, |
3adbf342 MB |
918 | .resolution = 12, |
919 | .name = "meson-gxl-saradc", | |
920 | }; | |
921 | ||
c1c2de37 | 922 | static const struct meson_sar_adc_data meson_sar_adc_gxm_data = { |
6c76ed31 | 923 | .has_bl30_integration = true, |
fda29dba | 924 | .clock_rate = 1200000, |
d85eed9f | 925 | .bandgap_reg = MESON_SAR_ADC_REG11, |
96748823 | 926 | .regmap_config = &meson_sar_adc_regmap_config_gxbb, |
3adbf342 MB |
927 | .resolution = 12, |
928 | .name = "meson-gxm-saradc", | |
929 | }; | |
930 | ||
931 | static const struct of_device_id meson_sar_adc_of_match[] = { | |
6c76ed31 MB |
932 | { |
933 | .compatible = "amlogic,meson8-saradc", | |
934 | .data = &meson_sar_adc_meson8_data, | |
935 | }, | |
936 | { | |
937 | .compatible = "amlogic,meson8b-saradc", | |
938 | .data = &meson_sar_adc_meson8b_data, | |
939 | }, | |
3adbf342 MB |
940 | { |
941 | .compatible = "amlogic,meson-gxbb-saradc", | |
942 | .data = &meson_sar_adc_gxbb_data, | |
943 | }, { | |
944 | .compatible = "amlogic,meson-gxl-saradc", | |
945 | .data = &meson_sar_adc_gxl_data, | |
946 | }, { | |
947 | .compatible = "amlogic,meson-gxm-saradc", | |
948 | .data = &meson_sar_adc_gxm_data, | |
949 | }, | |
950 | {}, | |
951 | }; | |
952 | MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); | |
953 | ||
954 | static int meson_sar_adc_probe(struct platform_device *pdev) | |
955 | { | |
956 | struct meson_sar_adc_priv *priv; | |
957 | struct iio_dev *indio_dev; | |
958 | struct resource *res; | |
959 | void __iomem *base; | |
960 | const struct of_device_id *match; | |
3af10913 | 961 | int irq, ret; |
3adbf342 MB |
962 | |
963 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); | |
964 | if (!indio_dev) { | |
965 | dev_err(&pdev->dev, "failed allocating iio device\n"); | |
966 | return -ENOMEM; | |
967 | } | |
968 | ||
969 | priv = iio_priv(indio_dev); | |
3af10913 | 970 | init_completion(&priv->done); |
3adbf342 MB |
971 | |
972 | match = of_match_device(meson_sar_adc_of_match, &pdev->dev); | |
2f9aeeed GS |
973 | if (!match) { |
974 | dev_err(&pdev->dev, "failed to match device\n"); | |
975 | return -ENODEV; | |
976 | } | |
977 | ||
3adbf342 MB |
978 | priv->data = match->data; |
979 | ||
980 | indio_dev->name = priv->data->name; | |
981 | indio_dev->dev.parent = &pdev->dev; | |
982 | indio_dev->dev.of_node = pdev->dev.of_node; | |
983 | indio_dev->modes = INDIO_DIRECT_MODE; | |
984 | indio_dev->info = &meson_sar_adc_iio_info; | |
985 | ||
986 | indio_dev->channels = meson_sar_adc_iio_channels; | |
987 | indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels); | |
988 | ||
989 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
990 | base = devm_ioremap_resource(&pdev->dev, res); | |
991 | if (IS_ERR(base)) | |
992 | return PTR_ERR(base); | |
993 | ||
3af10913 HK |
994 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
995 | if (!irq) | |
996 | return -EINVAL; | |
997 | ||
998 | ret = devm_request_irq(&pdev->dev, irq, meson_sar_adc_irq, IRQF_SHARED, | |
999 | dev_name(&pdev->dev), indio_dev); | |
1000 | if (ret) | |
1001 | return ret; | |
1002 | ||
3adbf342 | 1003 | priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
96748823 | 1004 | priv->data->regmap_config); |
3adbf342 MB |
1005 | if (IS_ERR(priv->regmap)) |
1006 | return PTR_ERR(priv->regmap); | |
1007 | ||
1008 | priv->clkin = devm_clk_get(&pdev->dev, "clkin"); | |
1009 | if (IS_ERR(priv->clkin)) { | |
1010 | dev_err(&pdev->dev, "failed to get clkin\n"); | |
1011 | return PTR_ERR(priv->clkin); | |
1012 | } | |
1013 | ||
1014 | priv->core_clk = devm_clk_get(&pdev->dev, "core"); | |
1015 | if (IS_ERR(priv->core_clk)) { | |
1016 | dev_err(&pdev->dev, "failed to get core clk\n"); | |
1017 | return PTR_ERR(priv->core_clk); | |
1018 | } | |
1019 | ||
3adbf342 MB |
1020 | priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk"); |
1021 | if (IS_ERR(priv->adc_clk)) { | |
1022 | if (PTR_ERR(priv->adc_clk) == -ENOENT) { | |
1023 | priv->adc_clk = NULL; | |
1024 | } else { | |
1025 | dev_err(&pdev->dev, "failed to get adc clk\n"); | |
1026 | return PTR_ERR(priv->adc_clk); | |
1027 | } | |
1028 | } | |
1029 | ||
1030 | priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel"); | |
1031 | if (IS_ERR(priv->adc_sel_clk)) { | |
1032 | if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) { | |
1033 | priv->adc_sel_clk = NULL; | |
1034 | } else { | |
1035 | dev_err(&pdev->dev, "failed to get adc_sel clk\n"); | |
1036 | return PTR_ERR(priv->adc_sel_clk); | |
1037 | } | |
1038 | } | |
1039 | ||
1040 | /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */ | |
1041 | if (!priv->adc_clk) { | |
1042 | ret = meson_sar_adc_clk_init(indio_dev, base); | |
1043 | if (ret) | |
1044 | return ret; | |
1045 | } | |
1046 | ||
1047 | priv->vref = devm_regulator_get(&pdev->dev, "vref"); | |
1048 | if (IS_ERR(priv->vref)) { | |
1049 | dev_err(&pdev->dev, "failed to get vref regulator\n"); | |
1050 | return PTR_ERR(priv->vref); | |
1051 | } | |
1052 | ||
48ba7c3c HK |
1053 | priv->calibscale = MILLION; |
1054 | ||
3adbf342 MB |
1055 | ret = meson_sar_adc_init(indio_dev); |
1056 | if (ret) | |
1057 | goto err; | |
1058 | ||
1059 | ret = meson_sar_adc_hw_enable(indio_dev); | |
1060 | if (ret) | |
1061 | goto err; | |
1062 | ||
48ba7c3c HK |
1063 | ret = meson_sar_adc_calib(indio_dev); |
1064 | if (ret) | |
1065 | dev_warn(&pdev->dev, "calibration failed\n"); | |
1066 | ||
3adbf342 MB |
1067 | platform_set_drvdata(pdev, indio_dev); |
1068 | ||
1069 | ret = iio_device_register(indio_dev); | |
1070 | if (ret) | |
1071 | goto err_hw; | |
1072 | ||
1073 | return 0; | |
1074 | ||
1075 | err_hw: | |
1076 | meson_sar_adc_hw_disable(indio_dev); | |
1077 | err: | |
1078 | return ret; | |
1079 | } | |
1080 | ||
1081 | static int meson_sar_adc_remove(struct platform_device *pdev) | |
1082 | { | |
1083 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | |
1084 | ||
1085 | iio_device_unregister(indio_dev); | |
1086 | ||
1087 | return meson_sar_adc_hw_disable(indio_dev); | |
1088 | } | |
1089 | ||
1090 | static int __maybe_unused meson_sar_adc_suspend(struct device *dev) | |
1091 | { | |
1092 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
1093 | ||
1094 | return meson_sar_adc_hw_disable(indio_dev); | |
1095 | } | |
1096 | ||
1097 | static int __maybe_unused meson_sar_adc_resume(struct device *dev) | |
1098 | { | |
1099 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
1100 | ||
1101 | return meson_sar_adc_hw_enable(indio_dev); | |
1102 | } | |
1103 | ||
1104 | static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops, | |
1105 | meson_sar_adc_suspend, meson_sar_adc_resume); | |
1106 | ||
1107 | static struct platform_driver meson_sar_adc_driver = { | |
1108 | .probe = meson_sar_adc_probe, | |
1109 | .remove = meson_sar_adc_remove, | |
1110 | .driver = { | |
1111 | .name = "meson-saradc", | |
1112 | .of_match_table = meson_sar_adc_of_match, | |
1113 | .pm = &meson_sar_adc_pm_ops, | |
1114 | }, | |
1115 | }; | |
1116 | ||
1117 | module_platform_driver(meson_sar_adc_driver); | |
1118 | ||
1119 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | |
1120 | MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver"); | |
1121 | MODULE_LICENSE("GPL v2"); |