Commit | Line | Data |
---|---|---|
69c272cc MH |
1 | /* |
2 | * ADE7758 Poly Phase Multifunction Energy Metering IC driver | |
3 | * | |
4 | * Copyright 2010-2011 Analog Devices Inc. | |
5 | * | |
6 | * Licensed under the GPL-2. | |
7 | */ | |
8 | ||
8210cfe9 | 9 | #include <linux/interrupt.h> |
8210cfe9 | 10 | #include <linux/kernel.h> |
8210cfe9 | 11 | #include <linux/spi/spi.h> |
8e336a72 | 12 | #include <linux/export.h> |
8210cfe9 | 13 | |
06458e27 JC |
14 | #include <linux/iio/iio.h> |
15 | #include <linux/iio/trigger.h> | |
8210cfe9 BS |
16 | #include "ade7758.h" |
17 | ||
18 | /** | |
19 | * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig | |
20 | **/ | |
4be6f5da | 21 | static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private) |
8210cfe9 | 22 | { |
4be6f5da JC |
23 | disable_irq_nosync(irq); |
24 | iio_trigger_poll(private, iio_get_time_ns()); | |
69c272cc | 25 | |
8210cfe9 BS |
26 | return IRQ_HANDLED; |
27 | } | |
28 | ||
8210cfe9 BS |
29 | /** |
30 | * ade7758_data_rdy_trigger_set_state() set datardy interrupt state | |
31 | **/ | |
32 | static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig, | |
33 | bool state) | |
34 | { | |
1e9663c6 | 35 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
8210cfe9 BS |
36 | |
37 | dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); | |
4be6f5da | 38 | return ade7758_set_irq(&indio_dev->dev, state); |
8210cfe9 BS |
39 | } |
40 | ||
41 | /** | |
42 | * ade7758_trig_try_reen() try renabling irq for data rdy trigger | |
43 | * @trig: the datardy trigger | |
44 | **/ | |
45 | static int ade7758_trig_try_reen(struct iio_trigger *trig) | |
46 | { | |
1e9663c6 | 47 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
a3f02370 | 48 | struct ade7758_state *st = iio_priv(indio_dev); |
69c272cc | 49 | |
8210cfe9 BS |
50 | enable_irq(st->us->irq); |
51 | /* irq reenabled so success! */ | |
52 | return 0; | |
53 | } | |
54 | ||
d29f73db JC |
55 | static const struct iio_trigger_ops ade7758_trigger_ops = { |
56 | .owner = THIS_MODULE, | |
57 | .set_trigger_state = &ade7758_data_rdy_trigger_set_state, | |
58 | .try_reenable = &ade7758_trig_try_reen, | |
59 | }; | |
60 | ||
8210cfe9 BS |
61 | int ade7758_probe_trigger(struct iio_dev *indio_dev) |
62 | { | |
a3f02370 | 63 | struct ade7758_state *st = iio_priv(indio_dev); |
8210cfe9 | 64 | int ret; |
8210cfe9 | 65 | |
7cbb7537 | 66 | st->trig = iio_trigger_alloc("%s-dev%d", |
59c85e82 JC |
67 | spi_get_device_id(st->us)->name, |
68 | indio_dev->id); | |
4be6f5da JC |
69 | if (st->trig == NULL) { |
70 | ret = -ENOMEM; | |
59c85e82 | 71 | goto error_ret; |
4be6f5da | 72 | } |
69c272cc | 73 | |
4be6f5da JC |
74 | ret = request_irq(st->us->irq, |
75 | ade7758_data_rdy_trig_poll, | |
69c272cc MH |
76 | IRQF_TRIGGER_LOW, |
77 | spi_get_device_id(st->us)->name, | |
4be6f5da JC |
78 | st->trig); |
79 | if (ret) | |
80 | goto error_free_trig; | |
81 | ||
8210cfe9 | 82 | st->trig->dev.parent = &st->us->dev; |
d29f73db | 83 | st->trig->ops = &ade7758_trigger_ops; |
1e9663c6 | 84 | iio_trigger_set_drvdata(st->trig, indio_dev); |
8210cfe9 BS |
85 | ret = iio_trigger_register(st->trig); |
86 | ||
87 | /* select default trigger */ | |
88 | indio_dev->trig = st->trig; | |
89 | if (ret) | |
69c272cc | 90 | goto error_free_irq; |
8210cfe9 BS |
91 | |
92 | return 0; | |
93 | ||
4be6f5da JC |
94 | error_free_irq: |
95 | free_irq(st->us->irq, st->trig); | |
8210cfe9 | 96 | error_free_trig: |
7cbb7537 | 97 | iio_trigger_free(st->trig); |
4be6f5da | 98 | error_ret: |
8210cfe9 BS |
99 | return ret; |
100 | } | |
101 | ||
102 | void ade7758_remove_trigger(struct iio_dev *indio_dev) | |
103 | { | |
a3f02370 | 104 | struct ade7758_state *st = iio_priv(indio_dev); |
8210cfe9 | 105 | |
a3f02370 MH |
106 | iio_trigger_unregister(st->trig); |
107 | free_irq(st->us->irq, st->trig); | |
7cbb7537 | 108 | iio_trigger_free(st->trig); |
8210cfe9 | 109 | } |