]>
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 | |
99 | #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_MASK(_chan) \ | |
100 | (GENMASK(10, 8) << (((_chan) - 2) * 2)) | |
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; |
d85eed9f | 224 | u32 bandgap_reg; |
3adbf342 MB |
225 | unsigned int resolution; |
226 | const char *name; | |
96748823 | 227 | const struct regmap_config *regmap_config; |
3adbf342 MB |
228 | }; |
229 | ||
230 | struct meson_sar_adc_priv { | |
231 | struct regmap *regmap; | |
232 | struct regulator *vref; | |
233 | const struct meson_sar_adc_data *data; | |
234 | struct clk *clkin; | |
235 | struct clk *core_clk; | |
236 | struct clk *sana_clk; | |
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 | ||
465 | if (timeout < 0) | |
466 | return -ETIMEDOUT; | |
467 | } | |
3adbf342 MB |
468 | |
469 | return 0; | |
470 | } | |
471 | ||
472 | static void meson_sar_adc_unlock(struct iio_dev *indio_dev) | |
473 | { | |
474 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
475 | ||
6c76ed31 MB |
476 | if (priv->data->has_bl30_integration) |
477 | /* allow BL30 to use the SAR ADC again */ | |
478 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
479 | MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); | |
3adbf342 MB |
480 | |
481 | mutex_unlock(&indio_dev->mlock); | |
482 | } | |
483 | ||
484 | static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) | |
485 | { | |
486 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
103a07d4 | 487 | unsigned int count, tmp; |
3adbf342 MB |
488 | |
489 | for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) { | |
490 | if (!meson_sar_adc_get_fifo_count(indio_dev)) | |
491 | break; | |
492 | ||
103a07d4 | 493 | regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp); |
3adbf342 MB |
494 | } |
495 | } | |
496 | ||
497 | static int meson_sar_adc_get_sample(struct iio_dev *indio_dev, | |
498 | const struct iio_chan_spec *chan, | |
499 | enum meson_sar_adc_avg_mode avg_mode, | |
500 | enum meson_sar_adc_num_samples avg_samples, | |
501 | int *val) | |
502 | { | |
503 | int ret; | |
504 | ||
505 | ret = meson_sar_adc_lock(indio_dev); | |
506 | if (ret) | |
507 | return ret; | |
508 | ||
509 | /* clear the FIFO to make sure we're not reading old values */ | |
510 | meson_sar_adc_clear_fifo(indio_dev); | |
511 | ||
512 | meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples); | |
513 | ||
514 | meson_sar_adc_enable_channel(indio_dev, chan); | |
515 | ||
516 | meson_sar_adc_start_sample_engine(indio_dev); | |
517 | ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val); | |
518 | meson_sar_adc_stop_sample_engine(indio_dev); | |
519 | ||
520 | meson_sar_adc_unlock(indio_dev); | |
521 | ||
522 | if (ret) { | |
523 | dev_warn(indio_dev->dev.parent, | |
524 | "failed to read sample for channel %d: %d\n", | |
525 | chan->channel, ret); | |
526 | return ret; | |
527 | } | |
528 | ||
529 | return IIO_VAL_INT; | |
530 | } | |
531 | ||
532 | static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev, | |
533 | const struct iio_chan_spec *chan, | |
534 | int *val, int *val2, long mask) | |
535 | { | |
536 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
537 | int ret; | |
538 | ||
539 | switch (mask) { | |
540 | case IIO_CHAN_INFO_RAW: | |
541 | return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING, | |
542 | ONE_SAMPLE, val); | |
543 | break; | |
544 | ||
545 | case IIO_CHAN_INFO_AVERAGE_RAW: | |
546 | return meson_sar_adc_get_sample(indio_dev, chan, | |
547 | MEAN_AVERAGING, EIGHT_SAMPLES, | |
548 | val); | |
549 | break; | |
550 | ||
551 | case IIO_CHAN_INFO_SCALE: | |
552 | ret = regulator_get_voltage(priv->vref); | |
553 | if (ret < 0) { | |
554 | dev_err(indio_dev->dev.parent, | |
555 | "failed to get vref voltage: %d\n", ret); | |
556 | return ret; | |
557 | } | |
558 | ||
559 | *val = ret / 1000; | |
560 | *val2 = priv->data->resolution; | |
561 | return IIO_VAL_FRACTIONAL_LOG2; | |
562 | ||
48ba7c3c HK |
563 | case IIO_CHAN_INFO_CALIBBIAS: |
564 | *val = priv->calibbias; | |
565 | return IIO_VAL_INT; | |
566 | ||
567 | case IIO_CHAN_INFO_CALIBSCALE: | |
568 | *val = priv->calibscale / MILLION; | |
569 | *val2 = priv->calibscale % MILLION; | |
570 | return IIO_VAL_INT_PLUS_MICRO; | |
571 | ||
3adbf342 MB |
572 | default: |
573 | return -EINVAL; | |
574 | } | |
575 | } | |
576 | ||
577 | static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, | |
578 | void __iomem *base) | |
579 | { | |
580 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
581 | struct clk_init_data init; | |
582 | const char *clk_parents[1]; | |
583 | ||
3921db46 RH |
584 | init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_div", |
585 | indio_dev->dev.of_node); | |
3adbf342 MB |
586 | init.flags = 0; |
587 | init.ops = &clk_divider_ops; | |
588 | clk_parents[0] = __clk_get_name(priv->clkin); | |
589 | init.parent_names = clk_parents; | |
590 | init.num_parents = 1; | |
591 | ||
592 | priv->clk_div.reg = base + MESON_SAR_ADC_REG3; | |
593 | priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT; | |
594 | priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH; | |
595 | priv->clk_div.hw.init = &init; | |
596 | priv->clk_div.flags = 0; | |
597 | ||
598 | priv->adc_div_clk = devm_clk_register(&indio_dev->dev, | |
599 | &priv->clk_div.hw); | |
600 | if (WARN_ON(IS_ERR(priv->adc_div_clk))) | |
601 | return PTR_ERR(priv->adc_div_clk); | |
602 | ||
3921db46 RH |
603 | init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_en", |
604 | indio_dev->dev.of_node); | |
3adbf342 MB |
605 | init.flags = CLK_SET_RATE_PARENT; |
606 | init.ops = &clk_gate_ops; | |
607 | clk_parents[0] = __clk_get_name(priv->adc_div_clk); | |
608 | init.parent_names = clk_parents; | |
609 | init.num_parents = 1; | |
610 | ||
611 | priv->clk_gate.reg = base + MESON_SAR_ADC_REG3; | |
7a6b0420 | 612 | priv->clk_gate.bit_idx = __ffs(MESON_SAR_ADC_REG3_CLK_EN); |
3adbf342 MB |
613 | priv->clk_gate.hw.init = &init; |
614 | ||
615 | priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw); | |
616 | if (WARN_ON(IS_ERR(priv->adc_clk))) | |
617 | return PTR_ERR(priv->adc_clk); | |
618 | ||
619 | return 0; | |
620 | } | |
621 | ||
622 | static int meson_sar_adc_init(struct iio_dev *indio_dev) | |
623 | { | |
624 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
625 | int regval, ret; | |
626 | ||
627 | /* | |
628 | * make sure we start at CH7 input since the other muxes are only used | |
629 | * for internal calibration. | |
630 | */ | |
631 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); | |
632 | ||
6c76ed31 MB |
633 | if (priv->data->has_bl30_integration) { |
634 | /* | |
635 | * leave sampling delay and the input clocks as configured by | |
636 | * BL30 to make sure BL30 gets the values it expects when | |
637 | * reading the temperature sensor. | |
638 | */ | |
639 | regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val); | |
640 | if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) | |
641 | return 0; | |
642 | } | |
3adbf342 MB |
643 | |
644 | meson_sar_adc_stop_sample_engine(indio_dev); | |
645 | ||
646 | /* update the channel 6 MUX to select the temperature sensor */ | |
647 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
648 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, | |
649 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL); | |
650 | ||
651 | /* disable all channels by default */ | |
652 | regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); | |
653 | ||
654 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
655 | MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0); | |
656 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
657 | MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY, | |
658 | MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY); | |
659 | ||
660 | /* delay between two samples = (10+1) * 1uS */ | |
661 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
662 | MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
663 | FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK, | |
664 | 10)); | |
665 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
666 | MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, | |
667 | FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, | |
668 | 0)); | |
669 | ||
670 | /* delay between two samples = (10+1) * 1uS */ | |
671 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
672 | MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
673 | FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
674 | 10)); | |
675 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
676 | MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, | |
677 | FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, | |
678 | 1)); | |
679 | ||
680 | ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); | |
681 | if (ret) { | |
682 | dev_err(indio_dev->dev.parent, | |
683 | "failed to set adc parent to clkin\n"); | |
684 | return ret; | |
685 | } | |
686 | ||
687 | ret = clk_set_rate(priv->adc_clk, 1200000); | |
688 | if (ret) { | |
689 | dev_err(indio_dev->dev.parent, | |
690 | "failed to set adc clock rate\n"); | |
691 | return ret; | |
692 | } | |
693 | ||
694 | return 0; | |
695 | } | |
696 | ||
d85eed9f MB |
697 | static void meson_sar_adc_set_bandgap(struct iio_dev *indio_dev, bool on_off) |
698 | { | |
699 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
700 | u32 enable_mask; | |
701 | ||
702 | if (priv->data->bandgap_reg == MESON_SAR_ADC_REG11) | |
703 | enable_mask = MESON_SAR_ADC_REG11_BANDGAP_EN; | |
704 | else | |
705 | enable_mask = MESON_SAR_ADC_DELTA_10_TS_VBG_EN; | |
706 | ||
707 | regmap_update_bits(priv->regmap, priv->data->bandgap_reg, enable_mask, | |
708 | on_off ? enable_mask : 0); | |
709 | } | |
710 | ||
3adbf342 MB |
711 | static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev) |
712 | { | |
713 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
714 | int ret; | |
3af10913 | 715 | u32 regval; |
3adbf342 MB |
716 | |
717 | ret = meson_sar_adc_lock(indio_dev); | |
718 | if (ret) | |
719 | goto err_lock; | |
720 | ||
721 | ret = regulator_enable(priv->vref); | |
722 | if (ret < 0) { | |
723 | dev_err(indio_dev->dev.parent, | |
724 | "failed to enable vref regulator\n"); | |
725 | goto err_vref; | |
726 | } | |
727 | ||
728 | ret = clk_prepare_enable(priv->core_clk); | |
729 | if (ret) { | |
730 | dev_err(indio_dev->dev.parent, "failed to enable core clk\n"); | |
731 | goto err_core_clk; | |
732 | } | |
733 | ||
734 | ret = clk_prepare_enable(priv->sana_clk); | |
735 | if (ret) { | |
736 | dev_err(indio_dev->dev.parent, "failed to enable sana clk\n"); | |
737 | goto err_sana_clk; | |
738 | } | |
739 | ||
3af10913 HK |
740 | regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1); |
741 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
742 | MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); | |
d85eed9f MB |
743 | |
744 | meson_sar_adc_set_bandgap(indio_dev, true); | |
745 | ||
3adbf342 MB |
746 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, |
747 | MESON_SAR_ADC_REG3_ADC_EN, | |
748 | MESON_SAR_ADC_REG3_ADC_EN); | |
749 | ||
750 | udelay(5); | |
751 | ||
752 | ret = clk_prepare_enable(priv->adc_clk); | |
753 | if (ret) { | |
754 | dev_err(indio_dev->dev.parent, "failed to enable adc clk\n"); | |
755 | goto err_adc_clk; | |
756 | } | |
757 | ||
758 | meson_sar_adc_unlock(indio_dev); | |
759 | ||
760 | return 0; | |
761 | ||
762 | err_adc_clk: | |
763 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
764 | MESON_SAR_ADC_REG3_ADC_EN, 0); | |
d85eed9f | 765 | meson_sar_adc_set_bandgap(indio_dev, false); |
3adbf342 MB |
766 | clk_disable_unprepare(priv->sana_clk); |
767 | err_sana_clk: | |
768 | clk_disable_unprepare(priv->core_clk); | |
769 | err_core_clk: | |
770 | regulator_disable(priv->vref); | |
771 | err_vref: | |
772 | meson_sar_adc_unlock(indio_dev); | |
773 | err_lock: | |
774 | return ret; | |
775 | } | |
776 | ||
777 | static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev) | |
778 | { | |
779 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
780 | int ret; | |
781 | ||
782 | ret = meson_sar_adc_lock(indio_dev); | |
783 | if (ret) | |
784 | return ret; | |
785 | ||
786 | clk_disable_unprepare(priv->adc_clk); | |
787 | ||
788 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
789 | MESON_SAR_ADC_REG3_ADC_EN, 0); | |
d85eed9f MB |
790 | |
791 | meson_sar_adc_set_bandgap(indio_dev, false); | |
3adbf342 MB |
792 | |
793 | clk_disable_unprepare(priv->sana_clk); | |
794 | clk_disable_unprepare(priv->core_clk); | |
795 | ||
796 | regulator_disable(priv->vref); | |
797 | ||
798 | meson_sar_adc_unlock(indio_dev); | |
799 | ||
800 | return 0; | |
801 | } | |
802 | ||
3af10913 HK |
803 | static irqreturn_t meson_sar_adc_irq(int irq, void *data) |
804 | { | |
805 | struct iio_dev *indio_dev = data; | |
806 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
807 | unsigned int cnt, threshold; | |
808 | u32 regval; | |
809 | ||
810 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
811 | cnt = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval); | |
812 | threshold = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); | |
813 | ||
814 | if (cnt < threshold) | |
815 | return IRQ_NONE; | |
816 | ||
817 | complete(&priv->done); | |
818 | ||
819 | return IRQ_HANDLED; | |
820 | } | |
821 | ||
48ba7c3c HK |
822 | static int meson_sar_adc_calib(struct iio_dev *indio_dev) |
823 | { | |
824 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
825 | int ret, nominal0, nominal1, value0, value1; | |
826 | ||
827 | /* use points 25% and 75% for calibration */ | |
828 | nominal0 = (1 << priv->data->resolution) / 4; | |
829 | nominal1 = (1 << priv->data->resolution) * 3 / 4; | |
830 | ||
831 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_DIV4); | |
832 | usleep_range(10, 20); | |
833 | ret = meson_sar_adc_get_sample(indio_dev, | |
834 | &meson_sar_adc_iio_channels[7], | |
835 | MEAN_AVERAGING, EIGHT_SAMPLES, &value0); | |
836 | if (ret < 0) | |
837 | goto out; | |
838 | ||
839 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_MUL3_DIV4); | |
840 | usleep_range(10, 20); | |
841 | ret = meson_sar_adc_get_sample(indio_dev, | |
842 | &meson_sar_adc_iio_channels[7], | |
843 | MEAN_AVERAGING, EIGHT_SAMPLES, &value1); | |
844 | if (ret < 0) | |
845 | goto out; | |
846 | ||
847 | if (value1 <= value0) { | |
848 | ret = -EINVAL; | |
849 | goto out; | |
850 | } | |
851 | ||
852 | priv->calibscale = div_s64((nominal1 - nominal0) * (s64)MILLION, | |
853 | value1 - value0); | |
854 | priv->calibbias = nominal0 - div_s64((s64)value0 * priv->calibscale, | |
855 | MILLION); | |
856 | ret = 0; | |
857 | out: | |
858 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); | |
859 | ||
860 | return ret; | |
861 | } | |
862 | ||
3adbf342 MB |
863 | static const struct iio_info meson_sar_adc_iio_info = { |
864 | .read_raw = meson_sar_adc_iio_info_read_raw, | |
3adbf342 MB |
865 | }; |
866 | ||
6c76ed31 MB |
867 | static const struct meson_sar_adc_data meson_sar_adc_meson8_data = { |
868 | .has_bl30_integration = false, | |
d85eed9f | 869 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, |
96748823 | 870 | .regmap_config = &meson_sar_adc_regmap_config_meson8, |
6c76ed31 MB |
871 | .resolution = 10, |
872 | .name = "meson-meson8-saradc", | |
873 | }; | |
874 | ||
875 | static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = { | |
876 | .has_bl30_integration = false, | |
d85eed9f | 877 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, |
96748823 | 878 | .regmap_config = &meson_sar_adc_regmap_config_meson8, |
6c76ed31 MB |
879 | .resolution = 10, |
880 | .name = "meson-meson8b-saradc", | |
881 | }; | |
882 | ||
c1c2de37 | 883 | static const struct meson_sar_adc_data meson_sar_adc_gxbb_data = { |
6c76ed31 | 884 | .has_bl30_integration = true, |
d85eed9f | 885 | .bandgap_reg = MESON_SAR_ADC_REG11, |
96748823 | 886 | .regmap_config = &meson_sar_adc_regmap_config_gxbb, |
3adbf342 MB |
887 | .resolution = 10, |
888 | .name = "meson-gxbb-saradc", | |
889 | }; | |
890 | ||
c1c2de37 | 891 | static const struct meson_sar_adc_data meson_sar_adc_gxl_data = { |
6c76ed31 | 892 | .has_bl30_integration = true, |
d85eed9f | 893 | .bandgap_reg = MESON_SAR_ADC_REG11, |
96748823 | 894 | .regmap_config = &meson_sar_adc_regmap_config_gxbb, |
3adbf342 MB |
895 | .resolution = 12, |
896 | .name = "meson-gxl-saradc", | |
897 | }; | |
898 | ||
c1c2de37 | 899 | static const struct meson_sar_adc_data meson_sar_adc_gxm_data = { |
6c76ed31 | 900 | .has_bl30_integration = true, |
d85eed9f | 901 | .bandgap_reg = MESON_SAR_ADC_REG11, |
96748823 | 902 | .regmap_config = &meson_sar_adc_regmap_config_gxbb, |
3adbf342 MB |
903 | .resolution = 12, |
904 | .name = "meson-gxm-saradc", | |
905 | }; | |
906 | ||
907 | static const struct of_device_id meson_sar_adc_of_match[] = { | |
6c76ed31 MB |
908 | { |
909 | .compatible = "amlogic,meson8-saradc", | |
910 | .data = &meson_sar_adc_meson8_data, | |
911 | }, | |
912 | { | |
913 | .compatible = "amlogic,meson8b-saradc", | |
914 | .data = &meson_sar_adc_meson8b_data, | |
915 | }, | |
3adbf342 MB |
916 | { |
917 | .compatible = "amlogic,meson-gxbb-saradc", | |
918 | .data = &meson_sar_adc_gxbb_data, | |
919 | }, { | |
920 | .compatible = "amlogic,meson-gxl-saradc", | |
921 | .data = &meson_sar_adc_gxl_data, | |
922 | }, { | |
923 | .compatible = "amlogic,meson-gxm-saradc", | |
924 | .data = &meson_sar_adc_gxm_data, | |
925 | }, | |
926 | {}, | |
927 | }; | |
928 | MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); | |
929 | ||
930 | static int meson_sar_adc_probe(struct platform_device *pdev) | |
931 | { | |
932 | struct meson_sar_adc_priv *priv; | |
933 | struct iio_dev *indio_dev; | |
934 | struct resource *res; | |
935 | void __iomem *base; | |
936 | const struct of_device_id *match; | |
3af10913 | 937 | int irq, ret; |
3adbf342 MB |
938 | |
939 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); | |
940 | if (!indio_dev) { | |
941 | dev_err(&pdev->dev, "failed allocating iio device\n"); | |
942 | return -ENOMEM; | |
943 | } | |
944 | ||
945 | priv = iio_priv(indio_dev); | |
3af10913 | 946 | init_completion(&priv->done); |
3adbf342 MB |
947 | |
948 | match = of_match_device(meson_sar_adc_of_match, &pdev->dev); | |
2f9aeeed GS |
949 | if (!match) { |
950 | dev_err(&pdev->dev, "failed to match device\n"); | |
951 | return -ENODEV; | |
952 | } | |
953 | ||
3adbf342 MB |
954 | priv->data = match->data; |
955 | ||
956 | indio_dev->name = priv->data->name; | |
957 | indio_dev->dev.parent = &pdev->dev; | |
958 | indio_dev->dev.of_node = pdev->dev.of_node; | |
959 | indio_dev->modes = INDIO_DIRECT_MODE; | |
960 | indio_dev->info = &meson_sar_adc_iio_info; | |
961 | ||
962 | indio_dev->channels = meson_sar_adc_iio_channels; | |
963 | indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels); | |
964 | ||
965 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
966 | base = devm_ioremap_resource(&pdev->dev, res); | |
967 | if (IS_ERR(base)) | |
968 | return PTR_ERR(base); | |
969 | ||
3af10913 HK |
970 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
971 | if (!irq) | |
972 | return -EINVAL; | |
973 | ||
974 | ret = devm_request_irq(&pdev->dev, irq, meson_sar_adc_irq, IRQF_SHARED, | |
975 | dev_name(&pdev->dev), indio_dev); | |
976 | if (ret) | |
977 | return ret; | |
978 | ||
3adbf342 | 979 | priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
96748823 | 980 | priv->data->regmap_config); |
3adbf342 MB |
981 | if (IS_ERR(priv->regmap)) |
982 | return PTR_ERR(priv->regmap); | |
983 | ||
984 | priv->clkin = devm_clk_get(&pdev->dev, "clkin"); | |
985 | if (IS_ERR(priv->clkin)) { | |
986 | dev_err(&pdev->dev, "failed to get clkin\n"); | |
987 | return PTR_ERR(priv->clkin); | |
988 | } | |
989 | ||
990 | priv->core_clk = devm_clk_get(&pdev->dev, "core"); | |
991 | if (IS_ERR(priv->core_clk)) { | |
992 | dev_err(&pdev->dev, "failed to get core clk\n"); | |
993 | return PTR_ERR(priv->core_clk); | |
994 | } | |
995 | ||
996 | priv->sana_clk = devm_clk_get(&pdev->dev, "sana"); | |
997 | if (IS_ERR(priv->sana_clk)) { | |
998 | if (PTR_ERR(priv->sana_clk) == -ENOENT) { | |
999 | priv->sana_clk = NULL; | |
1000 | } else { | |
1001 | dev_err(&pdev->dev, "failed to get sana clk\n"); | |
1002 | return PTR_ERR(priv->sana_clk); | |
1003 | } | |
1004 | } | |
1005 | ||
1006 | priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk"); | |
1007 | if (IS_ERR(priv->adc_clk)) { | |
1008 | if (PTR_ERR(priv->adc_clk) == -ENOENT) { | |
1009 | priv->adc_clk = NULL; | |
1010 | } else { | |
1011 | dev_err(&pdev->dev, "failed to get adc clk\n"); | |
1012 | return PTR_ERR(priv->adc_clk); | |
1013 | } | |
1014 | } | |
1015 | ||
1016 | priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel"); | |
1017 | if (IS_ERR(priv->adc_sel_clk)) { | |
1018 | if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) { | |
1019 | priv->adc_sel_clk = NULL; | |
1020 | } else { | |
1021 | dev_err(&pdev->dev, "failed to get adc_sel clk\n"); | |
1022 | return PTR_ERR(priv->adc_sel_clk); | |
1023 | } | |
1024 | } | |
1025 | ||
1026 | /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */ | |
1027 | if (!priv->adc_clk) { | |
1028 | ret = meson_sar_adc_clk_init(indio_dev, base); | |
1029 | if (ret) | |
1030 | return ret; | |
1031 | } | |
1032 | ||
1033 | priv->vref = devm_regulator_get(&pdev->dev, "vref"); | |
1034 | if (IS_ERR(priv->vref)) { | |
1035 | dev_err(&pdev->dev, "failed to get vref regulator\n"); | |
1036 | return PTR_ERR(priv->vref); | |
1037 | } | |
1038 | ||
48ba7c3c HK |
1039 | priv->calibscale = MILLION; |
1040 | ||
3adbf342 MB |
1041 | ret = meson_sar_adc_init(indio_dev); |
1042 | if (ret) | |
1043 | goto err; | |
1044 | ||
1045 | ret = meson_sar_adc_hw_enable(indio_dev); | |
1046 | if (ret) | |
1047 | goto err; | |
1048 | ||
48ba7c3c HK |
1049 | ret = meson_sar_adc_calib(indio_dev); |
1050 | if (ret) | |
1051 | dev_warn(&pdev->dev, "calibration failed\n"); | |
1052 | ||
3adbf342 MB |
1053 | platform_set_drvdata(pdev, indio_dev); |
1054 | ||
1055 | ret = iio_device_register(indio_dev); | |
1056 | if (ret) | |
1057 | goto err_hw; | |
1058 | ||
1059 | return 0; | |
1060 | ||
1061 | err_hw: | |
1062 | meson_sar_adc_hw_disable(indio_dev); | |
1063 | err: | |
1064 | return ret; | |
1065 | } | |
1066 | ||
1067 | static int meson_sar_adc_remove(struct platform_device *pdev) | |
1068 | { | |
1069 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | |
1070 | ||
1071 | iio_device_unregister(indio_dev); | |
1072 | ||
1073 | return meson_sar_adc_hw_disable(indio_dev); | |
1074 | } | |
1075 | ||
1076 | static int __maybe_unused meson_sar_adc_suspend(struct device *dev) | |
1077 | { | |
1078 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
1079 | ||
1080 | return meson_sar_adc_hw_disable(indio_dev); | |
1081 | } | |
1082 | ||
1083 | static int __maybe_unused meson_sar_adc_resume(struct device *dev) | |
1084 | { | |
1085 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
1086 | ||
1087 | return meson_sar_adc_hw_enable(indio_dev); | |
1088 | } | |
1089 | ||
1090 | static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops, | |
1091 | meson_sar_adc_suspend, meson_sar_adc_resume); | |
1092 | ||
1093 | static struct platform_driver meson_sar_adc_driver = { | |
1094 | .probe = meson_sar_adc_probe, | |
1095 | .remove = meson_sar_adc_remove, | |
1096 | .driver = { | |
1097 | .name = "meson-saradc", | |
1098 | .of_match_table = meson_sar_adc_of_match, | |
1099 | .pm = &meson_sar_adc_pm_ops, | |
1100 | }, | |
1101 | }; | |
1102 | ||
1103 | module_platform_driver(meson_sar_adc_driver); | |
1104 | ||
1105 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | |
1106 | MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver"); | |
1107 | MODULE_LICENSE("GPL v2"); |