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