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; |
3adbf342 MB |
224 | unsigned int resolution; |
225 | const char *name; | |
226 | }; | |
227 | ||
228 | struct meson_sar_adc_priv { | |
229 | struct regmap *regmap; | |
230 | struct regulator *vref; | |
231 | const struct meson_sar_adc_data *data; | |
232 | struct clk *clkin; | |
233 | struct clk *core_clk; | |
234 | struct clk *sana_clk; | |
235 | struct clk *adc_sel_clk; | |
236 | struct clk *adc_clk; | |
237 | struct clk_gate clk_gate; | |
238 | struct clk *adc_div_clk; | |
239 | struct clk_divider clk_div; | |
3af10913 | 240 | struct completion done; |
48ba7c3c HK |
241 | int calibbias; |
242 | int calibscale; | |
3adbf342 MB |
243 | }; |
244 | ||
245 | static const struct regmap_config meson_sar_adc_regmap_config = { | |
246 | .reg_bits = 8, | |
247 | .val_bits = 32, | |
248 | .reg_stride = 4, | |
249 | .max_register = MESON_SAR_ADC_REG13, | |
250 | }; | |
251 | ||
252 | static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev) | |
253 | { | |
254 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
255 | u32 regval; | |
256 | ||
257 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
258 | ||
259 | return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval); | |
260 | } | |
261 | ||
48ba7c3c HK |
262 | static int meson_sar_adc_calib_val(struct iio_dev *indio_dev, int val) |
263 | { | |
264 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
265 | int tmp; | |
266 | ||
267 | /* use val_calib = scale * val_raw + offset calibration function */ | |
268 | tmp = div_s64((s64)val * priv->calibscale, MILLION) + priv->calibbias; | |
269 | ||
270 | return clamp(tmp, 0, (1 << priv->data->resolution) - 1); | |
271 | } | |
272 | ||
3adbf342 MB |
273 | static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev) |
274 | { | |
275 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
276 | int regval, timeout = 10000; | |
277 | ||
278 | /* | |
279 | * NOTE: we need a small delay before reading the status, otherwise | |
280 | * the sample engine may not have started internally (which would | |
281 | * seem to us that sampling is already finished). | |
282 | */ | |
283 | do { | |
284 | udelay(1); | |
285 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
286 | } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--); | |
287 | ||
288 | if (timeout < 0) | |
289 | return -ETIMEDOUT; | |
290 | ||
291 | return 0; | |
292 | } | |
293 | ||
294 | static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev, | |
295 | const struct iio_chan_spec *chan, | |
296 | int *val) | |
297 | { | |
298 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
6a882a2c | 299 | int regval, fifo_chan, fifo_val, count; |
3adbf342 | 300 | |
3af10913 HK |
301 | if(!wait_for_completion_timeout(&priv->done, |
302 | msecs_to_jiffies(MESON_SAR_ADC_TIMEOUT))) | |
303 | return -ETIMEDOUT; | |
3adbf342 | 304 | |
6a882a2c HK |
305 | count = meson_sar_adc_get_fifo_count(indio_dev); |
306 | if (count != 1) { | |
307 | dev_err(&indio_dev->dev, | |
308 | "ADC FIFO has %d element(s) instead of one\n", count); | |
309 | return -EINVAL; | |
3adbf342 MB |
310 | } |
311 | ||
6a882a2c HK |
312 | regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, ®val); |
313 | fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval); | |
314 | if (fifo_chan != chan->channel) { | |
315 | dev_err(&indio_dev->dev, | |
316 | "ADC FIFO entry belongs to channel %d instead of %d\n", | |
317 | fifo_chan, chan->channel); | |
318 | return -EINVAL; | |
319 | } | |
3adbf342 | 320 | |
6a882a2c HK |
321 | fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, regval); |
322 | fifo_val &= GENMASK(priv->data->resolution - 1, 0); | |
48ba7c3c | 323 | *val = meson_sar_adc_calib_val(indio_dev, fifo_val); |
3adbf342 MB |
324 | |
325 | return 0; | |
326 | } | |
327 | ||
328 | static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev, | |
329 | const struct iio_chan_spec *chan, | |
330 | enum meson_sar_adc_avg_mode mode, | |
331 | enum meson_sar_adc_num_samples samples) | |
332 | { | |
333 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
334 | int val, channel = chan->channel; | |
335 | ||
336 | val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel); | |
337 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, | |
338 | MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel), | |
339 | val); | |
340 | ||
341 | val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel); | |
342 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, | |
343 | MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val); | |
344 | } | |
345 | ||
346 | static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev, | |
347 | const struct iio_chan_spec *chan) | |
348 | { | |
349 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
350 | u32 regval; | |
351 | ||
352 | /* | |
353 | * the SAR ADC engine allows sampling multiple channels at the same | |
354 | * time. to keep it simple we're only working with one *internal* | |
355 | * channel, which starts counting at index 0 (which means: count = 1). | |
356 | */ | |
357 | regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0); | |
358 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, | |
359 | MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval); | |
360 | ||
361 | /* map channel index 0 to the channel which we want to read */ | |
362 | regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), | |
363 | chan->channel); | |
364 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, | |
365 | MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval); | |
366 | ||
367 | regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK, | |
368 | chan->channel); | |
369 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, | |
370 | MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK, | |
371 | regval); | |
372 | ||
373 | regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, | |
374 | chan->channel); | |
375 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, | |
376 | MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, | |
377 | regval); | |
378 | ||
379 | if (chan->channel == 6) | |
380 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | |
381 | MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0); | |
382 | } | |
383 | ||
384 | static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev, | |
385 | enum meson_sar_adc_chan7_mux_sel sel) | |
386 | { | |
387 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
388 | u32 regval; | |
389 | ||
390 | regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel); | |
391 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
392 | MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval); | |
393 | ||
394 | usleep_range(10, 20); | |
395 | } | |
396 | ||
397 | static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev) | |
398 | { | |
399 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
400 | ||
3af10913 HK |
401 | reinit_completion(&priv->done); |
402 | ||
403 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
404 | MESON_SAR_ADC_REG0_FIFO_IRQ_EN, | |
405 | MESON_SAR_ADC_REG0_FIFO_IRQ_EN); | |
406 | ||
3adbf342 MB |
407 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
408 | MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, | |
409 | MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE); | |
410 | ||
411 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
412 | MESON_SAR_ADC_REG0_SAMPLING_START, | |
413 | MESON_SAR_ADC_REG0_SAMPLING_START); | |
414 | } | |
415 | ||
416 | static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev) | |
417 | { | |
418 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
419 | ||
3af10913 HK |
420 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
421 | MESON_SAR_ADC_REG0_FIFO_IRQ_EN, 0); | |
422 | ||
3adbf342 MB |
423 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
424 | MESON_SAR_ADC_REG0_SAMPLING_STOP, | |
425 | MESON_SAR_ADC_REG0_SAMPLING_STOP); | |
426 | ||
427 | /* wait until all modules are stopped */ | |
428 | meson_sar_adc_wait_busy_clear(indio_dev); | |
429 | ||
430 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
431 | MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0); | |
432 | } | |
433 | ||
434 | static int meson_sar_adc_lock(struct iio_dev *indio_dev) | |
435 | { | |
436 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
437 | int val, timeout = 10000; | |
438 | ||
439 | mutex_lock(&indio_dev->mlock); | |
440 | ||
6c76ed31 MB |
441 | if (priv->data->has_bl30_integration) { |
442 | /* prevent BL30 from using the SAR ADC while we are using it */ | |
443 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
444 | MESON_SAR_ADC_DELAY_KERNEL_BUSY, | |
445 | MESON_SAR_ADC_DELAY_KERNEL_BUSY); | |
446 | ||
447 | /* | |
448 | * wait until BL30 releases it's lock (so we can use the SAR | |
449 | * ADC) | |
450 | */ | |
451 | do { | |
452 | udelay(1); | |
453 | regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val); | |
454 | } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--); | |
455 | ||
456 | if (timeout < 0) | |
457 | return -ETIMEDOUT; | |
458 | } | |
3adbf342 MB |
459 | |
460 | return 0; | |
461 | } | |
462 | ||
463 | static void meson_sar_adc_unlock(struct iio_dev *indio_dev) | |
464 | { | |
465 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
466 | ||
6c76ed31 MB |
467 | if (priv->data->has_bl30_integration) |
468 | /* allow BL30 to use the SAR ADC again */ | |
469 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
470 | MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); | |
3adbf342 MB |
471 | |
472 | mutex_unlock(&indio_dev->mlock); | |
473 | } | |
474 | ||
475 | static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) | |
476 | { | |
477 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
103a07d4 | 478 | unsigned int count, tmp; |
3adbf342 MB |
479 | |
480 | for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) { | |
481 | if (!meson_sar_adc_get_fifo_count(indio_dev)) | |
482 | break; | |
483 | ||
103a07d4 | 484 | regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp); |
3adbf342 MB |
485 | } |
486 | } | |
487 | ||
488 | static int meson_sar_adc_get_sample(struct iio_dev *indio_dev, | |
489 | const struct iio_chan_spec *chan, | |
490 | enum meson_sar_adc_avg_mode avg_mode, | |
491 | enum meson_sar_adc_num_samples avg_samples, | |
492 | int *val) | |
493 | { | |
494 | int ret; | |
495 | ||
496 | ret = meson_sar_adc_lock(indio_dev); | |
497 | if (ret) | |
498 | return ret; | |
499 | ||
500 | /* clear the FIFO to make sure we're not reading old values */ | |
501 | meson_sar_adc_clear_fifo(indio_dev); | |
502 | ||
503 | meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples); | |
504 | ||
505 | meson_sar_adc_enable_channel(indio_dev, chan); | |
506 | ||
507 | meson_sar_adc_start_sample_engine(indio_dev); | |
508 | ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val); | |
509 | meson_sar_adc_stop_sample_engine(indio_dev); | |
510 | ||
511 | meson_sar_adc_unlock(indio_dev); | |
512 | ||
513 | if (ret) { | |
514 | dev_warn(indio_dev->dev.parent, | |
515 | "failed to read sample for channel %d: %d\n", | |
516 | chan->channel, ret); | |
517 | return ret; | |
518 | } | |
519 | ||
520 | return IIO_VAL_INT; | |
521 | } | |
522 | ||
523 | static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev, | |
524 | const struct iio_chan_spec *chan, | |
525 | int *val, int *val2, long mask) | |
526 | { | |
527 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
528 | int ret; | |
529 | ||
530 | switch (mask) { | |
531 | case IIO_CHAN_INFO_RAW: | |
532 | return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING, | |
533 | ONE_SAMPLE, val); | |
534 | break; | |
535 | ||
536 | case IIO_CHAN_INFO_AVERAGE_RAW: | |
537 | return meson_sar_adc_get_sample(indio_dev, chan, | |
538 | MEAN_AVERAGING, EIGHT_SAMPLES, | |
539 | val); | |
540 | break; | |
541 | ||
542 | case IIO_CHAN_INFO_SCALE: | |
543 | ret = regulator_get_voltage(priv->vref); | |
544 | if (ret < 0) { | |
545 | dev_err(indio_dev->dev.parent, | |
546 | "failed to get vref voltage: %d\n", ret); | |
547 | return ret; | |
548 | } | |
549 | ||
550 | *val = ret / 1000; | |
551 | *val2 = priv->data->resolution; | |
552 | return IIO_VAL_FRACTIONAL_LOG2; | |
553 | ||
48ba7c3c HK |
554 | case IIO_CHAN_INFO_CALIBBIAS: |
555 | *val = priv->calibbias; | |
556 | return IIO_VAL_INT; | |
557 | ||
558 | case IIO_CHAN_INFO_CALIBSCALE: | |
559 | *val = priv->calibscale / MILLION; | |
560 | *val2 = priv->calibscale % MILLION; | |
561 | return IIO_VAL_INT_PLUS_MICRO; | |
562 | ||
3adbf342 MB |
563 | default: |
564 | return -EINVAL; | |
565 | } | |
566 | } | |
567 | ||
568 | static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, | |
569 | void __iomem *base) | |
570 | { | |
571 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
572 | struct clk_init_data init; | |
573 | const char *clk_parents[1]; | |
574 | ||
3921db46 RH |
575 | init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_div", |
576 | indio_dev->dev.of_node); | |
3adbf342 MB |
577 | init.flags = 0; |
578 | init.ops = &clk_divider_ops; | |
579 | clk_parents[0] = __clk_get_name(priv->clkin); | |
580 | init.parent_names = clk_parents; | |
581 | init.num_parents = 1; | |
582 | ||
583 | priv->clk_div.reg = base + MESON_SAR_ADC_REG3; | |
584 | priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT; | |
585 | priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH; | |
586 | priv->clk_div.hw.init = &init; | |
587 | priv->clk_div.flags = 0; | |
588 | ||
589 | priv->adc_div_clk = devm_clk_register(&indio_dev->dev, | |
590 | &priv->clk_div.hw); | |
591 | if (WARN_ON(IS_ERR(priv->adc_div_clk))) | |
592 | return PTR_ERR(priv->adc_div_clk); | |
593 | ||
3921db46 RH |
594 | init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_en", |
595 | indio_dev->dev.of_node); | |
3adbf342 MB |
596 | init.flags = CLK_SET_RATE_PARENT; |
597 | init.ops = &clk_gate_ops; | |
598 | clk_parents[0] = __clk_get_name(priv->adc_div_clk); | |
599 | init.parent_names = clk_parents; | |
600 | init.num_parents = 1; | |
601 | ||
602 | priv->clk_gate.reg = base + MESON_SAR_ADC_REG3; | |
603 | priv->clk_gate.bit_idx = fls(MESON_SAR_ADC_REG3_CLK_EN); | |
604 | priv->clk_gate.hw.init = &init; | |
605 | ||
606 | priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw); | |
607 | if (WARN_ON(IS_ERR(priv->adc_clk))) | |
608 | return PTR_ERR(priv->adc_clk); | |
609 | ||
610 | return 0; | |
611 | } | |
612 | ||
613 | static int meson_sar_adc_init(struct iio_dev *indio_dev) | |
614 | { | |
615 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
616 | int regval, ret; | |
617 | ||
618 | /* | |
619 | * make sure we start at CH7 input since the other muxes are only used | |
620 | * for internal calibration. | |
621 | */ | |
622 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); | |
623 | ||
6c76ed31 MB |
624 | if (priv->data->has_bl30_integration) { |
625 | /* | |
626 | * leave sampling delay and the input clocks as configured by | |
627 | * BL30 to make sure BL30 gets the values it expects when | |
628 | * reading the temperature sensor. | |
629 | */ | |
630 | regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val); | |
631 | if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) | |
632 | return 0; | |
633 | } | |
3adbf342 MB |
634 | |
635 | meson_sar_adc_stop_sample_engine(indio_dev); | |
636 | ||
637 | /* update the channel 6 MUX to select the temperature sensor */ | |
638 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
639 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, | |
640 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL); | |
641 | ||
642 | /* disable all channels by default */ | |
643 | regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); | |
644 | ||
645 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
646 | MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0); | |
647 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
648 | MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY, | |
649 | MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY); | |
650 | ||
651 | /* delay between two samples = (10+1) * 1uS */ | |
652 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
653 | MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
654 | FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK, | |
655 | 10)); | |
656 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
657 | MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, | |
658 | FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, | |
659 | 0)); | |
660 | ||
661 | /* delay between two samples = (10+1) * 1uS */ | |
662 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
663 | MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
664 | FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, | |
665 | 10)); | |
666 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, | |
667 | MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, | |
668 | FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, | |
669 | 1)); | |
670 | ||
671 | ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); | |
672 | if (ret) { | |
673 | dev_err(indio_dev->dev.parent, | |
674 | "failed to set adc parent to clkin\n"); | |
675 | return ret; | |
676 | } | |
677 | ||
678 | ret = clk_set_rate(priv->adc_clk, 1200000); | |
679 | if (ret) { | |
680 | dev_err(indio_dev->dev.parent, | |
681 | "failed to set adc clock rate\n"); | |
682 | return ret; | |
683 | } | |
684 | ||
685 | return 0; | |
686 | } | |
687 | ||
688 | static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev) | |
689 | { | |
690 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
691 | int ret; | |
3af10913 | 692 | u32 regval; |
3adbf342 MB |
693 | |
694 | ret = meson_sar_adc_lock(indio_dev); | |
695 | if (ret) | |
696 | goto err_lock; | |
697 | ||
698 | ret = regulator_enable(priv->vref); | |
699 | if (ret < 0) { | |
700 | dev_err(indio_dev->dev.parent, | |
701 | "failed to enable vref regulator\n"); | |
702 | goto err_vref; | |
703 | } | |
704 | ||
705 | ret = clk_prepare_enable(priv->core_clk); | |
706 | if (ret) { | |
707 | dev_err(indio_dev->dev.parent, "failed to enable core clk\n"); | |
708 | goto err_core_clk; | |
709 | } | |
710 | ||
711 | ret = clk_prepare_enable(priv->sana_clk); | |
712 | if (ret) { | |
713 | dev_err(indio_dev->dev.parent, "failed to enable sana clk\n"); | |
714 | goto err_sana_clk; | |
715 | } | |
716 | ||
3af10913 HK |
717 | regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1); |
718 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | |
719 | MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); | |
3adbf342 MB |
720 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, |
721 | MESON_SAR_ADC_REG11_BANDGAP_EN, | |
722 | MESON_SAR_ADC_REG11_BANDGAP_EN); | |
723 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
724 | MESON_SAR_ADC_REG3_ADC_EN, | |
725 | MESON_SAR_ADC_REG3_ADC_EN); | |
726 | ||
727 | udelay(5); | |
728 | ||
729 | ret = clk_prepare_enable(priv->adc_clk); | |
730 | if (ret) { | |
731 | dev_err(indio_dev->dev.parent, "failed to enable adc clk\n"); | |
732 | goto err_adc_clk; | |
733 | } | |
734 | ||
735 | meson_sar_adc_unlock(indio_dev); | |
736 | ||
737 | return 0; | |
738 | ||
739 | err_adc_clk: | |
740 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
741 | MESON_SAR_ADC_REG3_ADC_EN, 0); | |
742 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, | |
743 | MESON_SAR_ADC_REG11_BANDGAP_EN, 0); | |
744 | clk_disable_unprepare(priv->sana_clk); | |
745 | err_sana_clk: | |
746 | clk_disable_unprepare(priv->core_clk); | |
747 | err_core_clk: | |
748 | regulator_disable(priv->vref); | |
749 | err_vref: | |
750 | meson_sar_adc_unlock(indio_dev); | |
751 | err_lock: | |
752 | return ret; | |
753 | } | |
754 | ||
755 | static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev) | |
756 | { | |
757 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
758 | int ret; | |
759 | ||
760 | ret = meson_sar_adc_lock(indio_dev); | |
761 | if (ret) | |
762 | return ret; | |
763 | ||
764 | clk_disable_unprepare(priv->adc_clk); | |
765 | ||
766 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, | |
767 | MESON_SAR_ADC_REG3_ADC_EN, 0); | |
768 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, | |
769 | MESON_SAR_ADC_REG11_BANDGAP_EN, 0); | |
770 | ||
771 | clk_disable_unprepare(priv->sana_clk); | |
772 | clk_disable_unprepare(priv->core_clk); | |
773 | ||
774 | regulator_disable(priv->vref); | |
775 | ||
776 | meson_sar_adc_unlock(indio_dev); | |
777 | ||
778 | return 0; | |
779 | } | |
780 | ||
3af10913 HK |
781 | static irqreturn_t meson_sar_adc_irq(int irq, void *data) |
782 | { | |
783 | struct iio_dev *indio_dev = data; | |
784 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
785 | unsigned int cnt, threshold; | |
786 | u32 regval; | |
787 | ||
788 | regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); | |
789 | cnt = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval); | |
790 | threshold = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); | |
791 | ||
792 | if (cnt < threshold) | |
793 | return IRQ_NONE; | |
794 | ||
795 | complete(&priv->done); | |
796 | ||
797 | return IRQ_HANDLED; | |
798 | } | |
799 | ||
48ba7c3c HK |
800 | static int meson_sar_adc_calib(struct iio_dev *indio_dev) |
801 | { | |
802 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
803 | int ret, nominal0, nominal1, value0, value1; | |
804 | ||
805 | /* use points 25% and 75% for calibration */ | |
806 | nominal0 = (1 << priv->data->resolution) / 4; | |
807 | nominal1 = (1 << priv->data->resolution) * 3 / 4; | |
808 | ||
809 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_DIV4); | |
810 | usleep_range(10, 20); | |
811 | ret = meson_sar_adc_get_sample(indio_dev, | |
812 | &meson_sar_adc_iio_channels[7], | |
813 | MEAN_AVERAGING, EIGHT_SAMPLES, &value0); | |
814 | if (ret < 0) | |
815 | goto out; | |
816 | ||
817 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_MUL3_DIV4); | |
818 | usleep_range(10, 20); | |
819 | ret = meson_sar_adc_get_sample(indio_dev, | |
820 | &meson_sar_adc_iio_channels[7], | |
821 | MEAN_AVERAGING, EIGHT_SAMPLES, &value1); | |
822 | if (ret < 0) | |
823 | goto out; | |
824 | ||
825 | if (value1 <= value0) { | |
826 | ret = -EINVAL; | |
827 | goto out; | |
828 | } | |
829 | ||
830 | priv->calibscale = div_s64((nominal1 - nominal0) * (s64)MILLION, | |
831 | value1 - value0); | |
832 | priv->calibbias = nominal0 - div_s64((s64)value0 * priv->calibscale, | |
833 | MILLION); | |
834 | ret = 0; | |
835 | out: | |
836 | meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); | |
837 | ||
838 | return ret; | |
839 | } | |
840 | ||
3adbf342 MB |
841 | static const struct iio_info meson_sar_adc_iio_info = { |
842 | .read_raw = meson_sar_adc_iio_info_read_raw, | |
843 | .driver_module = THIS_MODULE, | |
844 | }; | |
845 | ||
6c76ed31 MB |
846 | static const struct meson_sar_adc_data meson_sar_adc_meson8_data = { |
847 | .has_bl30_integration = false, | |
848 | .resolution = 10, | |
849 | .name = "meson-meson8-saradc", | |
850 | }; | |
851 | ||
852 | static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = { | |
853 | .has_bl30_integration = false, | |
854 | .resolution = 10, | |
855 | .name = "meson-meson8b-saradc", | |
856 | }; | |
857 | ||
c1c2de37 | 858 | static const struct meson_sar_adc_data meson_sar_adc_gxbb_data = { |
6c76ed31 | 859 | .has_bl30_integration = true, |
3adbf342 MB |
860 | .resolution = 10, |
861 | .name = "meson-gxbb-saradc", | |
862 | }; | |
863 | ||
c1c2de37 | 864 | static const struct meson_sar_adc_data meson_sar_adc_gxl_data = { |
6c76ed31 | 865 | .has_bl30_integration = true, |
3adbf342 MB |
866 | .resolution = 12, |
867 | .name = "meson-gxl-saradc", | |
868 | }; | |
869 | ||
c1c2de37 | 870 | static const struct meson_sar_adc_data meson_sar_adc_gxm_data = { |
6c76ed31 | 871 | .has_bl30_integration = true, |
3adbf342 MB |
872 | .resolution = 12, |
873 | .name = "meson-gxm-saradc", | |
874 | }; | |
875 | ||
876 | static const struct of_device_id meson_sar_adc_of_match[] = { | |
6c76ed31 MB |
877 | { |
878 | .compatible = "amlogic,meson8-saradc", | |
879 | .data = &meson_sar_adc_meson8_data, | |
880 | }, | |
881 | { | |
882 | .compatible = "amlogic,meson8b-saradc", | |
883 | .data = &meson_sar_adc_meson8b_data, | |
884 | }, | |
3adbf342 MB |
885 | { |
886 | .compatible = "amlogic,meson-gxbb-saradc", | |
887 | .data = &meson_sar_adc_gxbb_data, | |
888 | }, { | |
889 | .compatible = "amlogic,meson-gxl-saradc", | |
890 | .data = &meson_sar_adc_gxl_data, | |
891 | }, { | |
892 | .compatible = "amlogic,meson-gxm-saradc", | |
893 | .data = &meson_sar_adc_gxm_data, | |
894 | }, | |
895 | {}, | |
896 | }; | |
897 | MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); | |
898 | ||
899 | static int meson_sar_adc_probe(struct platform_device *pdev) | |
900 | { | |
901 | struct meson_sar_adc_priv *priv; | |
902 | struct iio_dev *indio_dev; | |
903 | struct resource *res; | |
904 | void __iomem *base; | |
905 | const struct of_device_id *match; | |
3af10913 | 906 | int irq, ret; |
3adbf342 MB |
907 | |
908 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); | |
909 | if (!indio_dev) { | |
910 | dev_err(&pdev->dev, "failed allocating iio device\n"); | |
911 | return -ENOMEM; | |
912 | } | |
913 | ||
914 | priv = iio_priv(indio_dev); | |
3af10913 | 915 | init_completion(&priv->done); |
3adbf342 MB |
916 | |
917 | match = of_match_device(meson_sar_adc_of_match, &pdev->dev); | |
2f9aeeed GS |
918 | if (!match) { |
919 | dev_err(&pdev->dev, "failed to match device\n"); | |
920 | return -ENODEV; | |
921 | } | |
922 | ||
3adbf342 MB |
923 | priv->data = match->data; |
924 | ||
925 | indio_dev->name = priv->data->name; | |
926 | indio_dev->dev.parent = &pdev->dev; | |
927 | indio_dev->dev.of_node = pdev->dev.of_node; | |
928 | indio_dev->modes = INDIO_DIRECT_MODE; | |
929 | indio_dev->info = &meson_sar_adc_iio_info; | |
930 | ||
931 | indio_dev->channels = meson_sar_adc_iio_channels; | |
932 | indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels); | |
933 | ||
934 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
935 | base = devm_ioremap_resource(&pdev->dev, res); | |
936 | if (IS_ERR(base)) | |
937 | return PTR_ERR(base); | |
938 | ||
3af10913 HK |
939 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
940 | if (!irq) | |
941 | return -EINVAL; | |
942 | ||
943 | ret = devm_request_irq(&pdev->dev, irq, meson_sar_adc_irq, IRQF_SHARED, | |
944 | dev_name(&pdev->dev), indio_dev); | |
945 | if (ret) | |
946 | return ret; | |
947 | ||
3adbf342 MB |
948 | priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
949 | &meson_sar_adc_regmap_config); | |
950 | if (IS_ERR(priv->regmap)) | |
951 | return PTR_ERR(priv->regmap); | |
952 | ||
953 | priv->clkin = devm_clk_get(&pdev->dev, "clkin"); | |
954 | if (IS_ERR(priv->clkin)) { | |
955 | dev_err(&pdev->dev, "failed to get clkin\n"); | |
956 | return PTR_ERR(priv->clkin); | |
957 | } | |
958 | ||
959 | priv->core_clk = devm_clk_get(&pdev->dev, "core"); | |
960 | if (IS_ERR(priv->core_clk)) { | |
961 | dev_err(&pdev->dev, "failed to get core clk\n"); | |
962 | return PTR_ERR(priv->core_clk); | |
963 | } | |
964 | ||
965 | priv->sana_clk = devm_clk_get(&pdev->dev, "sana"); | |
966 | if (IS_ERR(priv->sana_clk)) { | |
967 | if (PTR_ERR(priv->sana_clk) == -ENOENT) { | |
968 | priv->sana_clk = NULL; | |
969 | } else { | |
970 | dev_err(&pdev->dev, "failed to get sana clk\n"); | |
971 | return PTR_ERR(priv->sana_clk); | |
972 | } | |
973 | } | |
974 | ||
975 | priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk"); | |
976 | if (IS_ERR(priv->adc_clk)) { | |
977 | if (PTR_ERR(priv->adc_clk) == -ENOENT) { | |
978 | priv->adc_clk = NULL; | |
979 | } else { | |
980 | dev_err(&pdev->dev, "failed to get adc clk\n"); | |
981 | return PTR_ERR(priv->adc_clk); | |
982 | } | |
983 | } | |
984 | ||
985 | priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel"); | |
986 | if (IS_ERR(priv->adc_sel_clk)) { | |
987 | if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) { | |
988 | priv->adc_sel_clk = NULL; | |
989 | } else { | |
990 | dev_err(&pdev->dev, "failed to get adc_sel clk\n"); | |
991 | return PTR_ERR(priv->adc_sel_clk); | |
992 | } | |
993 | } | |
994 | ||
995 | /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */ | |
996 | if (!priv->adc_clk) { | |
997 | ret = meson_sar_adc_clk_init(indio_dev, base); | |
998 | if (ret) | |
999 | return ret; | |
1000 | } | |
1001 | ||
1002 | priv->vref = devm_regulator_get(&pdev->dev, "vref"); | |
1003 | if (IS_ERR(priv->vref)) { | |
1004 | dev_err(&pdev->dev, "failed to get vref regulator\n"); | |
1005 | return PTR_ERR(priv->vref); | |
1006 | } | |
1007 | ||
48ba7c3c HK |
1008 | priv->calibscale = MILLION; |
1009 | ||
3adbf342 MB |
1010 | ret = meson_sar_adc_init(indio_dev); |
1011 | if (ret) | |
1012 | goto err; | |
1013 | ||
1014 | ret = meson_sar_adc_hw_enable(indio_dev); | |
1015 | if (ret) | |
1016 | goto err; | |
1017 | ||
48ba7c3c HK |
1018 | ret = meson_sar_adc_calib(indio_dev); |
1019 | if (ret) | |
1020 | dev_warn(&pdev->dev, "calibration failed\n"); | |
1021 | ||
3adbf342 MB |
1022 | platform_set_drvdata(pdev, indio_dev); |
1023 | ||
1024 | ret = iio_device_register(indio_dev); | |
1025 | if (ret) | |
1026 | goto err_hw; | |
1027 | ||
1028 | return 0; | |
1029 | ||
1030 | err_hw: | |
1031 | meson_sar_adc_hw_disable(indio_dev); | |
1032 | err: | |
1033 | return ret; | |
1034 | } | |
1035 | ||
1036 | static int meson_sar_adc_remove(struct platform_device *pdev) | |
1037 | { | |
1038 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | |
1039 | ||
1040 | iio_device_unregister(indio_dev); | |
1041 | ||
1042 | return meson_sar_adc_hw_disable(indio_dev); | |
1043 | } | |
1044 | ||
1045 | static int __maybe_unused meson_sar_adc_suspend(struct device *dev) | |
1046 | { | |
1047 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
1048 | ||
1049 | return meson_sar_adc_hw_disable(indio_dev); | |
1050 | } | |
1051 | ||
1052 | static int __maybe_unused meson_sar_adc_resume(struct device *dev) | |
1053 | { | |
1054 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
1055 | ||
1056 | return meson_sar_adc_hw_enable(indio_dev); | |
1057 | } | |
1058 | ||
1059 | static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops, | |
1060 | meson_sar_adc_suspend, meson_sar_adc_resume); | |
1061 | ||
1062 | static struct platform_driver meson_sar_adc_driver = { | |
1063 | .probe = meson_sar_adc_probe, | |
1064 | .remove = meson_sar_adc_remove, | |
1065 | .driver = { | |
1066 | .name = "meson-saradc", | |
1067 | .of_match_table = meson_sar_adc_of_match, | |
1068 | .pm = &meson_sar_adc_pm_ops, | |
1069 | }, | |
1070 | }; | |
1071 | ||
1072 | module_platform_driver(meson_sar_adc_driver); | |
1073 | ||
1074 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | |
1075 | MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver"); | |
1076 | MODULE_LICENSE("GPL v2"); |