ade7758_trigger.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. #include <linux/interrupt.h>
  9. #include <linux/kernel.h>
  10. #include <linux/spi/spi.h>
  11. #include <linux/export.h>
  12. #include <linux/iio/iio.h>
  13. #include <linux/iio/trigger.h>
  14. #include "ade7758.h"
  15. /**
  16. * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig
  17. **/
  18. static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
  19. {
  20. disable_irq_nosync(irq);
  21. iio_trigger_poll(private);
  22. return IRQ_HANDLED;
  23. }
  24. /**
  25. * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
  26. **/
  27. static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
  28. bool state)
  29. {
  30. struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
  31. dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
  32. return ade7758_set_irq(&indio_dev->dev, state);
  33. }
  34. /**
  35. * ade7758_trig_try_reen() try renabling irq for data rdy trigger
  36. * @trig: the datardy trigger
  37. **/
  38. static int ade7758_trig_try_reen(struct iio_trigger *trig)
  39. {
  40. struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
  41. struct ade7758_state *st = iio_priv(indio_dev);
  42. enable_irq(st->us->irq);
  43. /* irq reenabled so success! */
  44. return 0;
  45. }
  46. static const struct iio_trigger_ops ade7758_trigger_ops = {
  47. .owner = THIS_MODULE,
  48. .set_trigger_state = &ade7758_data_rdy_trigger_set_state,
  49. .try_reenable = &ade7758_trig_try_reen,
  50. };
  51. int ade7758_probe_trigger(struct iio_dev *indio_dev)
  52. {
  53. struct ade7758_state *st = iio_priv(indio_dev);
  54. int ret;
  55. st->trig = iio_trigger_alloc("%s-dev%d",
  56. spi_get_device_id(st->us)->name,
  57. indio_dev->id);
  58. if (!st->trig) {
  59. ret = -ENOMEM;
  60. goto error_ret;
  61. }
  62. ret = request_irq(st->us->irq,
  63. ade7758_data_rdy_trig_poll,
  64. IRQF_TRIGGER_LOW,
  65. spi_get_device_id(st->us)->name,
  66. st->trig);
  67. if (ret)
  68. goto error_free_trig;
  69. st->trig->dev.parent = &st->us->dev;
  70. st->trig->ops = &ade7758_trigger_ops;
  71. iio_trigger_set_drvdata(st->trig, indio_dev);
  72. ret = iio_trigger_register(st->trig);
  73. /* select default trigger */
  74. indio_dev->trig = iio_trigger_get(st->trig);
  75. if (ret)
  76. goto error_free_irq;
  77. return 0;
  78. error_free_irq:
  79. free_irq(st->us->irq, st->trig);
  80. error_free_trig:
  81. iio_trigger_free(st->trig);
  82. error_ret:
  83. return ret;
  84. }
  85. void ade7758_remove_trigger(struct iio_dev *indio_dev)
  86. {
  87. struct ade7758_state *st = iio_priv(indio_dev);
  88. iio_trigger_unregister(st->trig);
  89. free_irq(st->us->irq, st->trig);
  90. iio_trigger_free(st->trig);
  91. }