Merge 3.9-rc5 into staging-next
[deliverable/linux.git] / drivers / staging / iio / meter / ade7758_trigger.c
CommitLineData
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 21static 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 **/
32static 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 **/
45static 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
55static 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
61int 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
94error_free_irq:
95 free_irq(st->us->irq, st->trig);
8210cfe9 96error_free_trig:
7cbb7537 97 iio_trigger_free(st->trig);
4be6f5da 98error_ret:
8210cfe9
BS
99 return ret;
100}
101
102void 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}
This page took 2.485547 seconds and 5 git commands to generate.