169c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich/*
269c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich * ADE7758 Poly Phase Multifunction Energy Metering IC driver
369c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich *
469c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich * Copyright 2010-2011 Analog Devices Inc.
569c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich *
669c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich * Licensed under the GPL-2.
769c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich */
869c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich
98210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song#include <linux/interrupt.h>
108210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song#include <linux/kernel.h>
118210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song#include <linux/spi/spi.h>
128e336a722bb234f9d7805647e0290f2a397ca04dPaul Gortmaker#include <linux/export.h>
138210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
148210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song#include "../iio.h"
158210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song#include "../trigger.h"
168210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song#include "ade7758.h"
178210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
188210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song/**
198210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig
208210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song **/
214be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameronstatic irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
228210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song{
234be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	disable_irq_nosync(irq);
244be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	iio_trigger_poll(private, iio_get_time_ns());
2569c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich
268210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	return IRQ_HANDLED;
278210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song}
288210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
298210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song/**
308210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
318210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song **/
328210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Songstatic int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
338210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song						bool state)
348210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song{
35a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	struct iio_dev *indio_dev = trig->private_data;
368210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
378210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
384be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	return ade7758_set_irq(&indio_dev->dev, state);
398210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song}
408210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
418210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song/**
428210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song * ade7758_trig_try_reen() try renabling irq for data rdy trigger
438210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song * @trig:	the datardy trigger
448210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song **/
458210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Songstatic int ade7758_trig_try_reen(struct iio_trigger *trig)
468210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song{
47a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	struct iio_dev *indio_dev = trig->private_data;
48a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	struct ade7758_state *st = iio_priv(indio_dev);
4969c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich
508210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	enable_irq(st->us->irq);
518210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	/* irq reenabled so success! */
528210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	return 0;
538210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song}
548210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
55d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameronstatic const struct iio_trigger_ops ade7758_trigger_ops = {
56d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameron	.owner = THIS_MODULE,
57d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameron	.set_trigger_state = &ade7758_data_rdy_trigger_set_state,
58d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameron	.try_reenable = &ade7758_trig_try_reen,
59d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameron};
60d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameron
618210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Songint ade7758_probe_trigger(struct iio_dev *indio_dev)
628210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song{
63a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	struct ade7758_state *st = iio_priv(indio_dev);
648210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	int ret;
658210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
6659c85e82c2e7a672cb4342dc5ccf9df8a3a14f73Jonathan Cameron	st->trig = iio_allocate_trigger("%s-dev%d",
6759c85e82c2e7a672cb4342dc5ccf9df8a3a14f73Jonathan Cameron					spi_get_device_id(st->us)->name,
6859c85e82c2e7a672cb4342dc5ccf9df8a3a14f73Jonathan Cameron					indio_dev->id);
694be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	if (st->trig == NULL) {
704be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron		ret = -ENOMEM;
7159c85e82c2e7a672cb4342dc5ccf9df8a3a14f73Jonathan Cameron		goto error_ret;
724be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	}
7369c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich
744be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	ret = request_irq(st->us->irq,
754be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron			  ade7758_data_rdy_trig_poll,
7669c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich			  IRQF_TRIGGER_LOW,
7769c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich			  spi_get_device_id(st->us)->name,
784be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron			  st->trig);
794be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	if (ret)
804be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron		goto error_free_trig;
814be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron
828210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	st->trig->dev.parent = &st->us->dev;
83d29f73db791098179af90e6a5b1df41f941b32cdJonathan Cameron	st->trig->ops = &ade7758_trigger_ops;
84a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	st->trig->private_data = indio_dev;
858210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	ret = iio_trigger_register(st->trig);
868210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
878210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	/* select default trigger */
888210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	indio_dev->trig = st->trig;
898210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	if (ret)
9069c272cc8edf3e5432859a9c1bcb51a64b2accb5Michael Hennerich		goto error_free_irq;
918210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
928210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	return 0;
938210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
944be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameronerror_free_irq:
954be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameron	free_irq(st->us->irq, st->trig);
968210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Songerror_free_trig:
978210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	iio_free_trigger(st->trig);
984be6f5dab712db9e7e16e6120865c5bb1af4a41dJonathan Cameronerror_ret:
998210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song	return ret;
1008210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song}
1018210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
1028210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Songvoid ade7758_remove_trigger(struct iio_dev *indio_dev)
1038210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song{
104a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	struct ade7758_state *st = iio_priv(indio_dev);
1058210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song
106a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	iio_trigger_unregister(st->trig);
107a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	free_irq(st->us->irq, st->trig);
108a3f02370c9fa6d85fbee2c11649ebc9c84bae919Michael Hennerich	iio_free_trigger(st->trig);
1098210cfe9bd99fd63fae0b60c40fa793b8454e381Barry Song}
110