1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Rockchip Successive Approximation Register (SAR) A/D Converter |
4 | * Copyright (C) 2014 ROCKCHIP, Inc. |
5 | */ |
6 | |
7 | #include <linux/bitfield.h> |
8 | #include <linux/module.h> |
9 | #include <linux/mutex.h> |
10 | #include <linux/platform_device.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/io.h> |
13 | #include <linux/of.h> |
14 | #include <linux/clk.h> |
15 | #include <linux/completion.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/reset.h> |
18 | #include <linux/regulator/consumer.h> |
19 | #include <linux/iio/buffer.h> |
20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/trigger_consumer.h> |
22 | #include <linux/iio/triggered_buffer.h> |
23 | |
24 | #define SARADC_DATA 0x00 |
25 | |
26 | #define SARADC_STAS 0x04 |
27 | #define SARADC_STAS_BUSY BIT(0) |
28 | |
29 | #define SARADC_CTRL 0x08 |
30 | #define SARADC_CTRL_IRQ_STATUS BIT(6) |
31 | #define SARADC_CTRL_IRQ_ENABLE BIT(5) |
32 | #define SARADC_CTRL_POWER_CTRL BIT(3) |
33 | #define SARADC_CTRL_CHN_MASK 0x7 |
34 | |
35 | #define SARADC_DLY_PU_SOC 0x0c |
36 | #define SARADC_DLY_PU_SOC_MASK 0x3f |
37 | |
38 | #define SARADC_TIMEOUT msecs_to_jiffies(100) |
39 | #define SARADC_MAX_CHANNELS 8 |
40 | |
41 | /* v2 registers */ |
42 | #define SARADC2_CONV_CON 0x000 |
43 | #define SARADC_T_PD_SOC 0x004 |
44 | #define SARADC_T_DAS_SOC 0x00c |
45 | #define SARADC2_END_INT_EN 0x104 |
46 | #define SARADC2_ST_CON 0x108 |
47 | #define SARADC2_STATUS 0x10c |
48 | #define SARADC2_END_INT_ST 0x110 |
49 | #define SARADC2_DATA_BASE 0x120 |
50 | |
51 | #define SARADC2_EN_END_INT BIT(0) |
52 | #define SARADC2_START BIT(4) |
53 | #define SARADC2_SINGLE_MODE BIT(5) |
54 | |
55 | #define SARADC2_CONV_CHANNELS GENMASK(15, 0) |
56 | |
57 | struct rockchip_saradc; |
58 | |
59 | struct rockchip_saradc_data { |
60 | const struct iio_chan_spec *channels; |
61 | int num_channels; |
62 | unsigned long clk_rate; |
63 | void (*start)(struct rockchip_saradc *info, int chn); |
64 | int (*read)(struct rockchip_saradc *info); |
65 | void (*power_down)(struct rockchip_saradc *info); |
66 | }; |
67 | |
68 | struct rockchip_saradc { |
69 | void __iomem *regs; |
70 | struct clk *pclk; |
71 | struct clk *clk; |
72 | struct completion completion; |
73 | struct regulator *vref; |
74 | /* lock to protect against multiple access to the device */ |
75 | struct mutex lock; |
76 | int uv_vref; |
77 | struct reset_control *reset; |
78 | const struct rockchip_saradc_data *data; |
79 | u16 last_val; |
80 | const struct iio_chan_spec *last_chan; |
81 | struct notifier_block nb; |
82 | }; |
83 | |
84 | static void rockchip_saradc_reset_controller(struct reset_control *reset); |
85 | |
86 | static void rockchip_saradc_start_v1(struct rockchip_saradc *info, int chn) |
87 | { |
88 | /* 8 clock periods as delay between power up and start cmd */ |
89 | writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC); |
90 | /* Select the channel to be used and trigger conversion */ |
91 | writel(SARADC_CTRL_POWER_CTRL | (chn & SARADC_CTRL_CHN_MASK) | |
92 | SARADC_CTRL_IRQ_ENABLE, addr: info->regs + SARADC_CTRL); |
93 | } |
94 | |
95 | static void rockchip_saradc_start_v2(struct rockchip_saradc *info, int chn) |
96 | { |
97 | int val; |
98 | |
99 | if (info->reset) |
100 | rockchip_saradc_reset_controller(reset: info->reset); |
101 | |
102 | writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC); |
103 | writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC); |
104 | val = FIELD_PREP(SARADC2_EN_END_INT, 1); |
105 | val |= val << 16; |
106 | writel_relaxed(val, info->regs + SARADC2_END_INT_EN); |
107 | val = FIELD_PREP(SARADC2_START, 1) | |
108 | FIELD_PREP(SARADC2_SINGLE_MODE, 1) | |
109 | FIELD_PREP(SARADC2_CONV_CHANNELS, chn); |
110 | val |= val << 16; |
111 | writel(val, addr: info->regs + SARADC2_CONV_CON); |
112 | } |
113 | |
114 | static void rockchip_saradc_start(struct rockchip_saradc *info, int chn) |
115 | { |
116 | info->data->start(info, chn); |
117 | } |
118 | |
119 | static int rockchip_saradc_read_v1(struct rockchip_saradc *info) |
120 | { |
121 | return readl_relaxed(info->regs + SARADC_DATA); |
122 | } |
123 | |
124 | static int rockchip_saradc_read_v2(struct rockchip_saradc *info) |
125 | { |
126 | int offset; |
127 | |
128 | /* Clear irq */ |
129 | writel_relaxed(0x1, info->regs + SARADC2_END_INT_ST); |
130 | |
131 | offset = SARADC2_DATA_BASE + info->last_chan->channel * 0x4; |
132 | |
133 | return readl_relaxed(info->regs + offset); |
134 | } |
135 | |
136 | static int rockchip_saradc_read(struct rockchip_saradc *info) |
137 | { |
138 | return info->data->read(info); |
139 | } |
140 | |
141 | static void rockchip_saradc_power_down_v1(struct rockchip_saradc *info) |
142 | { |
143 | writel_relaxed(0, info->regs + SARADC_CTRL); |
144 | } |
145 | |
146 | static void rockchip_saradc_power_down(struct rockchip_saradc *info) |
147 | { |
148 | if (info->data->power_down) |
149 | info->data->power_down(info); |
150 | } |
151 | |
152 | static int rockchip_saradc_conversion(struct rockchip_saradc *info, |
153 | struct iio_chan_spec const *chan) |
154 | { |
155 | reinit_completion(x: &info->completion); |
156 | |
157 | info->last_chan = chan; |
158 | rockchip_saradc_start(info, chn: chan->channel); |
159 | |
160 | if (!wait_for_completion_timeout(x: &info->completion, SARADC_TIMEOUT)) |
161 | return -ETIMEDOUT; |
162 | |
163 | return 0; |
164 | } |
165 | |
166 | static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, |
167 | struct iio_chan_spec const *chan, |
168 | int *val, int *val2, long mask) |
169 | { |
170 | struct rockchip_saradc *info = iio_priv(indio_dev); |
171 | int ret; |
172 | |
173 | switch (mask) { |
174 | case IIO_CHAN_INFO_RAW: |
175 | mutex_lock(&info->lock); |
176 | |
177 | ret = rockchip_saradc_conversion(info, chan); |
178 | if (ret) { |
179 | rockchip_saradc_power_down(info); |
180 | mutex_unlock(lock: &info->lock); |
181 | return ret; |
182 | } |
183 | |
184 | *val = info->last_val; |
185 | mutex_unlock(lock: &info->lock); |
186 | return IIO_VAL_INT; |
187 | case IIO_CHAN_INFO_SCALE: |
188 | *val = info->uv_vref / 1000; |
189 | *val2 = chan->scan_type.realbits; |
190 | return IIO_VAL_FRACTIONAL_LOG2; |
191 | default: |
192 | return -EINVAL; |
193 | } |
194 | } |
195 | |
196 | static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) |
197 | { |
198 | struct rockchip_saradc *info = dev_id; |
199 | |
200 | /* Read value */ |
201 | info->last_val = rockchip_saradc_read(info); |
202 | info->last_val &= GENMASK(info->last_chan->scan_type.realbits - 1, 0); |
203 | |
204 | rockchip_saradc_power_down(info); |
205 | |
206 | complete(&info->completion); |
207 | |
208 | return IRQ_HANDLED; |
209 | } |
210 | |
211 | static const struct iio_info rockchip_saradc_iio_info = { |
212 | .read_raw = rockchip_saradc_read_raw, |
213 | }; |
214 | |
215 | #define SARADC_CHANNEL(_index, _id, _res) { \ |
216 | .type = IIO_VOLTAGE, \ |
217 | .indexed = 1, \ |
218 | .channel = _index, \ |
219 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
220 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
221 | .datasheet_name = _id, \ |
222 | .scan_index = _index, \ |
223 | .scan_type = { \ |
224 | .sign = 'u', \ |
225 | .realbits = _res, \ |
226 | .storagebits = 16, \ |
227 | .endianness = IIO_CPU, \ |
228 | }, \ |
229 | } |
230 | |
231 | static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { |
232 | SARADC_CHANNEL(0, "adc0" , 10), |
233 | SARADC_CHANNEL(1, "adc1" , 10), |
234 | SARADC_CHANNEL(2, "adc2" , 10), |
235 | }; |
236 | |
237 | static const struct rockchip_saradc_data saradc_data = { |
238 | .channels = rockchip_saradc_iio_channels, |
239 | .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels), |
240 | .clk_rate = 1000000, |
241 | .start = rockchip_saradc_start_v1, |
242 | .read = rockchip_saradc_read_v1, |
243 | .power_down = rockchip_saradc_power_down_v1, |
244 | }; |
245 | |
246 | static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = { |
247 | SARADC_CHANNEL(0, "adc0" , 12), |
248 | SARADC_CHANNEL(1, "adc1" , 12), |
249 | }; |
250 | |
251 | static const struct rockchip_saradc_data rk3066_tsadc_data = { |
252 | .channels = rockchip_rk3066_tsadc_iio_channels, |
253 | .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels), |
254 | .clk_rate = 50000, |
255 | .start = rockchip_saradc_start_v1, |
256 | .read = rockchip_saradc_read_v1, |
257 | .power_down = rockchip_saradc_power_down_v1, |
258 | }; |
259 | |
260 | static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = { |
261 | SARADC_CHANNEL(0, "adc0" , 10), |
262 | SARADC_CHANNEL(1, "adc1" , 10), |
263 | SARADC_CHANNEL(2, "adc2" , 10), |
264 | SARADC_CHANNEL(3, "adc3" , 10), |
265 | SARADC_CHANNEL(4, "adc4" , 10), |
266 | SARADC_CHANNEL(5, "adc5" , 10), |
267 | }; |
268 | |
269 | static const struct rockchip_saradc_data rk3399_saradc_data = { |
270 | .channels = rockchip_rk3399_saradc_iio_channels, |
271 | .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels), |
272 | .clk_rate = 1000000, |
273 | .start = rockchip_saradc_start_v1, |
274 | .read = rockchip_saradc_read_v1, |
275 | .power_down = rockchip_saradc_power_down_v1, |
276 | }; |
277 | |
278 | static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = { |
279 | SARADC_CHANNEL(0, "adc0" , 10), |
280 | SARADC_CHANNEL(1, "adc1" , 10), |
281 | SARADC_CHANNEL(2, "adc2" , 10), |
282 | SARADC_CHANNEL(3, "adc3" , 10), |
283 | SARADC_CHANNEL(4, "adc4" , 10), |
284 | SARADC_CHANNEL(5, "adc5" , 10), |
285 | SARADC_CHANNEL(6, "adc6" , 10), |
286 | SARADC_CHANNEL(7, "adc7" , 10), |
287 | }; |
288 | |
289 | static const struct rockchip_saradc_data rk3568_saradc_data = { |
290 | .channels = rockchip_rk3568_saradc_iio_channels, |
291 | .num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels), |
292 | .clk_rate = 1000000, |
293 | .start = rockchip_saradc_start_v1, |
294 | .read = rockchip_saradc_read_v1, |
295 | .power_down = rockchip_saradc_power_down_v1, |
296 | }; |
297 | |
298 | static const struct iio_chan_spec rockchip_rk3588_saradc_iio_channels[] = { |
299 | SARADC_CHANNEL(0, "adc0" , 12), |
300 | SARADC_CHANNEL(1, "adc1" , 12), |
301 | SARADC_CHANNEL(2, "adc2" , 12), |
302 | SARADC_CHANNEL(3, "adc3" , 12), |
303 | SARADC_CHANNEL(4, "adc4" , 12), |
304 | SARADC_CHANNEL(5, "adc5" , 12), |
305 | SARADC_CHANNEL(6, "adc6" , 12), |
306 | SARADC_CHANNEL(7, "adc7" , 12), |
307 | }; |
308 | |
309 | static const struct rockchip_saradc_data rk3588_saradc_data = { |
310 | .channels = rockchip_rk3588_saradc_iio_channels, |
311 | .num_channels = ARRAY_SIZE(rockchip_rk3588_saradc_iio_channels), |
312 | .clk_rate = 1000000, |
313 | .start = rockchip_saradc_start_v2, |
314 | .read = rockchip_saradc_read_v2, |
315 | }; |
316 | |
317 | static const struct of_device_id rockchip_saradc_match[] = { |
318 | { |
319 | .compatible = "rockchip,saradc" , |
320 | .data = &saradc_data, |
321 | }, { |
322 | .compatible = "rockchip,rk3066-tsadc" , |
323 | .data = &rk3066_tsadc_data, |
324 | }, { |
325 | .compatible = "rockchip,rk3399-saradc" , |
326 | .data = &rk3399_saradc_data, |
327 | }, { |
328 | .compatible = "rockchip,rk3568-saradc" , |
329 | .data = &rk3568_saradc_data, |
330 | }, { |
331 | .compatible = "rockchip,rk3588-saradc" , |
332 | .data = &rk3588_saradc_data, |
333 | }, |
334 | {}, |
335 | }; |
336 | MODULE_DEVICE_TABLE(of, rockchip_saradc_match); |
337 | |
338 | /* |
339 | * Reset SARADC Controller. |
340 | */ |
341 | static void rockchip_saradc_reset_controller(struct reset_control *reset) |
342 | { |
343 | reset_control_assert(rstc: reset); |
344 | usleep_range(min: 10, max: 20); |
345 | reset_control_deassert(rstc: reset); |
346 | } |
347 | |
348 | static void rockchip_saradc_regulator_disable(void *data) |
349 | { |
350 | struct rockchip_saradc *info = data; |
351 | |
352 | regulator_disable(regulator: info->vref); |
353 | } |
354 | |
355 | static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) |
356 | { |
357 | struct iio_poll_func *pf = p; |
358 | struct iio_dev *i_dev = pf->indio_dev; |
359 | struct rockchip_saradc *info = iio_priv(indio_dev: i_dev); |
360 | /* |
361 | * @values: each channel takes an u16 value |
362 | * @timestamp: will be 8-byte aligned automatically |
363 | */ |
364 | struct { |
365 | u16 values[SARADC_MAX_CHANNELS]; |
366 | int64_t timestamp; |
367 | } data; |
368 | int ret; |
369 | int i, j = 0; |
370 | |
371 | mutex_lock(&info->lock); |
372 | |
373 | for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) { |
374 | const struct iio_chan_spec *chan = &i_dev->channels[i]; |
375 | |
376 | ret = rockchip_saradc_conversion(info, chan); |
377 | if (ret) { |
378 | rockchip_saradc_power_down(info); |
379 | goto out; |
380 | } |
381 | |
382 | data.values[j] = info->last_val; |
383 | j++; |
384 | } |
385 | |
386 | iio_push_to_buffers_with_timestamp(indio_dev: i_dev, data: &data, timestamp: iio_get_time_ns(indio_dev: i_dev)); |
387 | out: |
388 | mutex_unlock(lock: &info->lock); |
389 | |
390 | iio_trigger_notify_done(trig: i_dev->trig); |
391 | |
392 | return IRQ_HANDLED; |
393 | } |
394 | |
395 | static int rockchip_saradc_volt_notify(struct notifier_block *nb, |
396 | unsigned long event, void *data) |
397 | { |
398 | struct rockchip_saradc *info = |
399 | container_of(nb, struct rockchip_saradc, nb); |
400 | |
401 | if (event & REGULATOR_EVENT_VOLTAGE_CHANGE) |
402 | info->uv_vref = (unsigned long)data; |
403 | |
404 | return NOTIFY_OK; |
405 | } |
406 | |
407 | static void rockchip_saradc_regulator_unreg_notifier(void *data) |
408 | { |
409 | struct rockchip_saradc *info = data; |
410 | |
411 | regulator_unregister_notifier(regulator: info->vref, nb: &info->nb); |
412 | } |
413 | |
414 | static int rockchip_saradc_probe(struct platform_device *pdev) |
415 | { |
416 | const struct rockchip_saradc_data *match_data; |
417 | struct rockchip_saradc *info = NULL; |
418 | struct device_node *np = pdev->dev.of_node; |
419 | struct iio_dev *indio_dev = NULL; |
420 | int ret; |
421 | int irq; |
422 | |
423 | if (!np) |
424 | return -ENODEV; |
425 | |
426 | indio_dev = devm_iio_device_alloc(parent: &pdev->dev, sizeof_priv: sizeof(*info)); |
427 | if (!indio_dev) |
428 | return dev_err_probe(dev: &pdev->dev, err: -ENOMEM, |
429 | fmt: "failed allocating iio device\n" ); |
430 | |
431 | info = iio_priv(indio_dev); |
432 | |
433 | match_data = of_device_get_match_data(dev: &pdev->dev); |
434 | if (!match_data) |
435 | return dev_err_probe(dev: &pdev->dev, err: -ENODEV, |
436 | fmt: "failed to match device\n" ); |
437 | |
438 | info->data = match_data; |
439 | |
440 | /* Sanity check for possible later IP variants with more channels */ |
441 | if (info->data->num_channels > SARADC_MAX_CHANNELS) |
442 | return dev_err_probe(dev: &pdev->dev, err: -EINVAL, |
443 | fmt: "max channels exceeded" ); |
444 | |
445 | info->regs = devm_platform_ioremap_resource(pdev, index: 0); |
446 | if (IS_ERR(ptr: info->regs)) |
447 | return PTR_ERR(ptr: info->regs); |
448 | |
449 | /* |
450 | * The reset should be an optional property, as it should work |
451 | * with old devicetrees as well |
452 | */ |
453 | info->reset = devm_reset_control_get_exclusive(dev: &pdev->dev, |
454 | id: "saradc-apb" ); |
455 | if (IS_ERR(ptr: info->reset)) { |
456 | ret = PTR_ERR(ptr: info->reset); |
457 | if (ret != -ENOENT) |
458 | return dev_err_probe(dev: &pdev->dev, err: ret, |
459 | fmt: "failed to get saradc-apb\n" ); |
460 | |
461 | dev_dbg(&pdev->dev, "no reset control found\n" ); |
462 | info->reset = NULL; |
463 | } |
464 | |
465 | init_completion(x: &info->completion); |
466 | |
467 | irq = platform_get_irq(pdev, 0); |
468 | if (irq < 0) |
469 | return irq; |
470 | |
471 | ret = devm_request_irq(dev: &pdev->dev, irq, handler: rockchip_saradc_isr, |
472 | irqflags: 0, devname: dev_name(dev: &pdev->dev), dev_id: info); |
473 | if (ret < 0) { |
474 | dev_err(&pdev->dev, "failed requesting irq %d\n" , irq); |
475 | return ret; |
476 | } |
477 | |
478 | info->vref = devm_regulator_get(dev: &pdev->dev, id: "vref" ); |
479 | if (IS_ERR(ptr: info->vref)) |
480 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: info->vref), |
481 | fmt: "failed to get regulator\n" ); |
482 | |
483 | if (info->reset) |
484 | rockchip_saradc_reset_controller(reset: info->reset); |
485 | |
486 | /* |
487 | * Use a default value for the converter clock. |
488 | * This may become user-configurable in the future. |
489 | */ |
490 | ret = clk_set_rate(clk: info->clk, rate: info->data->clk_rate); |
491 | if (ret < 0) |
492 | return dev_err_probe(dev: &pdev->dev, err: ret, |
493 | fmt: "failed to set adc clk rate\n" ); |
494 | |
495 | ret = regulator_enable(regulator: info->vref); |
496 | if (ret < 0) |
497 | return dev_err_probe(dev: &pdev->dev, err: ret, |
498 | fmt: "failed to enable vref regulator\n" ); |
499 | |
500 | ret = devm_add_action_or_reset(&pdev->dev, |
501 | rockchip_saradc_regulator_disable, info); |
502 | if (ret) |
503 | return dev_err_probe(dev: &pdev->dev, err: ret, |
504 | fmt: "failed to register devm action\n" ); |
505 | |
506 | ret = regulator_get_voltage(regulator: info->vref); |
507 | if (ret < 0) |
508 | return ret; |
509 | |
510 | info->uv_vref = ret; |
511 | |
512 | info->pclk = devm_clk_get_enabled(dev: &pdev->dev, id: "apb_pclk" ); |
513 | if (IS_ERR(ptr: info->pclk)) |
514 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: info->pclk), |
515 | fmt: "failed to get pclk\n" ); |
516 | |
517 | info->clk = devm_clk_get_enabled(dev: &pdev->dev, id: "saradc" ); |
518 | if (IS_ERR(ptr: info->clk)) |
519 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: info->clk), |
520 | fmt: "failed to get adc clock\n" ); |
521 | |
522 | platform_set_drvdata(pdev, data: indio_dev); |
523 | |
524 | indio_dev->name = dev_name(dev: &pdev->dev); |
525 | indio_dev->info = &rockchip_saradc_iio_info; |
526 | indio_dev->modes = INDIO_DIRECT_MODE; |
527 | |
528 | indio_dev->channels = info->data->channels; |
529 | indio_dev->num_channels = info->data->num_channels; |
530 | ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL, |
531 | rockchip_saradc_trigger_handler, |
532 | NULL); |
533 | if (ret) |
534 | return ret; |
535 | |
536 | info->nb.notifier_call = rockchip_saradc_volt_notify; |
537 | ret = regulator_register_notifier(regulator: info->vref, nb: &info->nb); |
538 | if (ret) |
539 | return ret; |
540 | |
541 | ret = devm_add_action_or_reset(&pdev->dev, |
542 | rockchip_saradc_regulator_unreg_notifier, |
543 | info); |
544 | if (ret) |
545 | return ret; |
546 | |
547 | mutex_init(&info->lock); |
548 | |
549 | return devm_iio_device_register(&pdev->dev, indio_dev); |
550 | } |
551 | |
552 | static int rockchip_saradc_suspend(struct device *dev) |
553 | { |
554 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
555 | struct rockchip_saradc *info = iio_priv(indio_dev); |
556 | |
557 | clk_disable_unprepare(clk: info->clk); |
558 | clk_disable_unprepare(clk: info->pclk); |
559 | regulator_disable(regulator: info->vref); |
560 | |
561 | return 0; |
562 | } |
563 | |
564 | static int rockchip_saradc_resume(struct device *dev) |
565 | { |
566 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
567 | struct rockchip_saradc *info = iio_priv(indio_dev); |
568 | int ret; |
569 | |
570 | ret = regulator_enable(regulator: info->vref); |
571 | if (ret) |
572 | return ret; |
573 | |
574 | ret = clk_prepare_enable(clk: info->pclk); |
575 | if (ret) |
576 | return ret; |
577 | |
578 | ret = clk_prepare_enable(clk: info->clk); |
579 | if (ret) |
580 | clk_disable_unprepare(clk: info->pclk); |
581 | |
582 | return ret; |
583 | } |
584 | |
585 | static DEFINE_SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, |
586 | rockchip_saradc_suspend, |
587 | rockchip_saradc_resume); |
588 | |
589 | static struct platform_driver rockchip_saradc_driver = { |
590 | .probe = rockchip_saradc_probe, |
591 | .driver = { |
592 | .name = "rockchip-saradc" , |
593 | .of_match_table = rockchip_saradc_match, |
594 | .pm = pm_sleep_ptr(&rockchip_saradc_pm_ops), |
595 | }, |
596 | }; |
597 | |
598 | module_platform_driver(rockchip_saradc_driver); |
599 | |
600 | MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>" ); |
601 | MODULE_DESCRIPTION("Rockchip SARADC driver" ); |
602 | MODULE_LICENSE("GPL v2" ); |
603 | |