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 9#include <linux/interrupt.h> 10#include <linux/kernel.h> 11#include <linux/spi/spi.h> 12#include <linux/export.h> 13 14#include <linux/iio/iio.h> 15#include <linux/iio/trigger.h> 16#include "ade7758.h" 17 18/** 19 * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig 20 **/ 21static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private) 22{ 23 disable_irq_nosync(irq); 24 iio_trigger_poll(private); 25 26 return IRQ_HANDLED; 27} 28 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{ 35 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 36 37 dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); 38 return ade7758_set_irq(&indio_dev->dev, state); 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{ 47 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 48 struct ade7758_state *st = iio_priv(indio_dev); 49 50 enable_irq(st->us->irq); 51 /* irq reenabled so success! */ 52 return 0; 53} 54 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 61int ade7758_probe_trigger(struct iio_dev *indio_dev) 62{ 63 struct ade7758_state *st = iio_priv(indio_dev); 64 int ret; 65 66 st->trig = iio_trigger_alloc("%s-dev%d", 67 spi_get_device_id(st->us)->name, 68 indio_dev->id); 69 if (st->trig == NULL) { 70 ret = -ENOMEM; 71 goto error_ret; 72 } 73 74 ret = request_irq(st->us->irq, 75 ade7758_data_rdy_trig_poll, 76 IRQF_TRIGGER_LOW, 77 spi_get_device_id(st->us)->name, 78 st->trig); 79 if (ret) 80 goto error_free_trig; 81 82 st->trig->dev.parent = &st->us->dev; 83 st->trig->ops = &ade7758_trigger_ops; 84 iio_trigger_set_drvdata(st->trig, indio_dev); 85 ret = iio_trigger_register(st->trig); 86 87 /* select default trigger */ 88 indio_dev->trig = iio_trigger_get(st->trig); 89 if (ret) 90 goto error_free_irq; 91 92 return 0; 93 94error_free_irq: 95 free_irq(st->us->irq, st->trig); 96error_free_trig: 97 iio_trigger_free(st->trig); 98error_ret: 99 return ret; 100} 101 102void ade7758_remove_trigger(struct iio_dev *indio_dev) 103{ 104 struct ade7758_state *st = iio_priv(indio_dev); 105 106 iio_trigger_unregister(st->trig); 107 free_irq(st->us->irq, st->trig); 108 iio_trigger_free(st->trig); 109} 110