iio_simple_dummy_events.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /**
  2. * Copyright (c) 2011 Jonathan Cameron
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License version 2 as published by
  6. * the Free Software Foundation.
  7. *
  8. * Event handling elements of industrial I/O reference driver.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/slab.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/irq.h>
  14. #include <linux/iio/iio.h>
  15. #include <linux/iio/sysfs.h>
  16. #include <linux/iio/events.h>
  17. #include "iio_simple_dummy.h"
  18. /* Evgen 'fakes' interrupt events for this example */
  19. #include "iio_dummy_evgen.h"
  20. /**
  21. * iio_simple_dummy_read_event_config() - is event enabled?
  22. * @indio_dev: the device instance data
  23. * @chan: channel for the event whose state is being queried
  24. * @type: type of the event whose state is being queried
  25. * @dir: direction of the vent whose state is being queried
  26. *
  27. * This function would normally query the relevant registers or a cache to
  28. * discover if the event generation is enabled on the device.
  29. */
  30. int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
  31. const struct iio_chan_spec *chan,
  32. enum iio_event_type type,
  33. enum iio_event_direction dir)
  34. {
  35. struct iio_dummy_state *st = iio_priv(indio_dev);
  36. return st->event_en;
  37. }
  38. /**
  39. * iio_simple_dummy_write_event_config() - set whether event is enabled
  40. * @indio_dev: the device instance data
  41. * @chan: channel for the event whose state is being set
  42. * @type: type of the event whose state is being set
  43. * @dir: direction of the vent whose state is being set
  44. * @state: whether to enable or disable the device.
  45. *
  46. * This function would normally set the relevant registers on the devices
  47. * so that it generates the specified event. Here it just sets up a cached
  48. * value.
  49. */
  50. int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
  51. const struct iio_chan_spec *chan,
  52. enum iio_event_type type,
  53. enum iio_event_direction dir,
  54. int state)
  55. {
  56. struct iio_dummy_state *st = iio_priv(indio_dev);
  57. /*
  58. * Deliberately over the top code splitting to illustrate
  59. * how this is done when multiple events exist.
  60. */
  61. switch (chan->type) {
  62. case IIO_VOLTAGE:
  63. switch (type) {
  64. case IIO_EV_TYPE_THRESH:
  65. if (dir == IIO_EV_DIR_RISING)
  66. st->event_en = state;
  67. else
  68. return -EINVAL;
  69. break;
  70. default:
  71. return -EINVAL;
  72. }
  73. break;
  74. case IIO_ACTIVITY:
  75. switch (type) {
  76. case IIO_EV_TYPE_THRESH:
  77. st->event_en = state;
  78. break;
  79. default:
  80. return -EINVAL;
  81. }
  82. break;
  83. case IIO_STEPS:
  84. switch (type) {
  85. case IIO_EV_TYPE_CHANGE:
  86. st->event_en = state;
  87. break;
  88. default:
  89. return -EINVAL;
  90. }
  91. break;
  92. default:
  93. return -EINVAL;
  94. }
  95. return 0;
  96. }
  97. /**
  98. * iio_simple_dummy_read_event_value() - get value associated with event
  99. * @indio_dev: device instance specific data
  100. * @chan: channel for the event whose value is being read
  101. * @type: type of the event whose value is being read
  102. * @dir: direction of the vent whose value is being read
  103. * @info: info type of the event whose value is being read
  104. * @val: value for the event code.
  105. *
  106. * Many devices provide a large set of events of which only a subset may
  107. * be enabled at a time, with value registers whose meaning changes depending
  108. * on the event enabled. This often means that the driver must cache the values
  109. * associated with each possible events so that the right value is in place when
  110. * the enabled event is changed.
  111. */
  112. int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
  113. const struct iio_chan_spec *chan,
  114. enum iio_event_type type,
  115. enum iio_event_direction dir,
  116. enum iio_event_info info,
  117. int *val, int *val2)
  118. {
  119. struct iio_dummy_state *st = iio_priv(indio_dev);
  120. *val = st->event_val;
  121. return IIO_VAL_INT;
  122. }
  123. /**
  124. * iio_simple_dummy_write_event_value() - set value associate with event
  125. * @indio_dev: device instance specific data
  126. * @chan: channel for the event whose value is being set
  127. * @type: type of the event whose value is being set
  128. * @dir: direction of the vent whose value is being set
  129. * @info: info type of the event whose value is being set
  130. * @val: the value to be set.
  131. */
  132. int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
  133. const struct iio_chan_spec *chan,
  134. enum iio_event_type type,
  135. enum iio_event_direction dir,
  136. enum iio_event_info info,
  137. int val, int val2)
  138. {
  139. struct iio_dummy_state *st = iio_priv(indio_dev);
  140. st->event_val = val;
  141. return 0;
  142. }
  143. static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)
  144. {
  145. struct iio_dev *indio_dev = private;
  146. struct iio_dummy_state *st = iio_priv(indio_dev);
  147. st->event_timestamp = iio_get_time_ns(indio_dev);
  148. return IRQ_WAKE_THREAD;
  149. }
  150. /**
  151. * iio_simple_dummy_event_handler() - identify and pass on event
  152. * @irq: irq of event line
  153. * @private: pointer to device instance state.
  154. *
  155. * This handler is responsible for querying the device to find out what
  156. * event occurred and for then pushing that event towards userspace.
  157. * Here only one event occurs so we push that directly on with locally
  158. * grabbed timestamp.
  159. */
  160. static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
  161. {
  162. struct iio_dev *indio_dev = private;
  163. struct iio_dummy_state *st = iio_priv(indio_dev);
  164. dev_dbg(&indio_dev->dev, "id %x event %x\n",
  165. st->regs->reg_id, st->regs->reg_data);
  166. switch (st->regs->reg_data) {
  167. case 0:
  168. iio_push_event(indio_dev,
  169. IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
  170. IIO_EV_DIR_RISING,
  171. IIO_EV_TYPE_THRESH, 0, 0, 0),
  172. st->event_timestamp);
  173. break;
  174. case 1:
  175. if (st->activity_running > st->event_val)
  176. iio_push_event(indio_dev,
  177. IIO_EVENT_CODE(IIO_ACTIVITY, 0,
  178. IIO_MOD_RUNNING,
  179. IIO_EV_DIR_RISING,
  180. IIO_EV_TYPE_THRESH,
  181. 0, 0, 0),
  182. st->event_timestamp);
  183. break;
  184. case 2:
  185. if (st->activity_walking < st->event_val)
  186. iio_push_event(indio_dev,
  187. IIO_EVENT_CODE(IIO_ACTIVITY, 0,
  188. IIO_MOD_WALKING,
  189. IIO_EV_DIR_FALLING,
  190. IIO_EV_TYPE_THRESH,
  191. 0, 0, 0),
  192. st->event_timestamp);
  193. break;
  194. case 3:
  195. iio_push_event(indio_dev,
  196. IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
  197. IIO_EV_DIR_NONE,
  198. IIO_EV_TYPE_CHANGE, 0, 0, 0),
  199. st->event_timestamp);
  200. break;
  201. default:
  202. break;
  203. }
  204. return IRQ_HANDLED;
  205. }
  206. /**
  207. * iio_simple_dummy_events_register() - setup interrupt handling for events
  208. * @indio_dev: device instance data
  209. *
  210. * This function requests the threaded interrupt to handle the events.
  211. * Normally the irq is a hardware interrupt and the number comes
  212. * from board configuration files. Here we get it from a companion
  213. * module that fakes the interrupt for us. Note that module in
  214. * no way forms part of this example. Just assume that events magically
  215. * appear via the provided interrupt.
  216. */
  217. int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
  218. {
  219. struct iio_dummy_state *st = iio_priv(indio_dev);
  220. int ret;
  221. /* Fire up event source - normally not present */
  222. st->event_irq = iio_dummy_evgen_get_irq();
  223. if (st->event_irq < 0) {
  224. ret = st->event_irq;
  225. goto error_ret;
  226. }
  227. st->regs = iio_dummy_evgen_get_regs(st->event_irq);
  228. ret = request_threaded_irq(st->event_irq,
  229. &iio_simple_dummy_get_timestamp,
  230. &iio_simple_dummy_event_handler,
  231. IRQF_ONESHOT,
  232. "iio_simple_event",
  233. indio_dev);
  234. if (ret < 0)
  235. goto error_free_evgen;
  236. return 0;
  237. error_free_evgen:
  238. iio_dummy_evgen_release_irq(st->event_irq);
  239. error_ret:
  240. return ret;
  241. }
  242. /**
  243. * iio_simple_dummy_events_unregister() - tidy up interrupt handling on remove
  244. * @indio_dev: device instance data
  245. */
  246. void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
  247. {
  248. struct iio_dummy_state *st = iio_priv(indio_dev);
  249. free_irq(st->event_irq, indio_dev);
  250. /* Not part of normal driver */
  251. iio_dummy_evgen_release_irq(st->event_irq);
  252. }