xilinx-xadc-events.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Xilinx XADC driver
  3. *
  4. * Copyright 2013 Analog Devices Inc.
  5. * Author: Lars-Peter Clauen <lars@metafoo.de>
  6. *
  7. * Licensed under the GPL-2.
  8. */
  9. #include <linux/iio/events.h>
  10. #include <linux/iio/iio.h>
  11. #include <linux/kernel.h>
  12. #include "xilinx-xadc.h"
  13. static const struct iio_chan_spec *xadc_event_to_channel(
  14. struct iio_dev *indio_dev, unsigned int event)
  15. {
  16. switch (event) {
  17. case XADC_THRESHOLD_OT_MAX:
  18. case XADC_THRESHOLD_TEMP_MAX:
  19. return &indio_dev->channels[0];
  20. case XADC_THRESHOLD_VCCINT_MAX:
  21. case XADC_THRESHOLD_VCCAUX_MAX:
  22. return &indio_dev->channels[event];
  23. default:
  24. return &indio_dev->channels[event-1];
  25. }
  26. }
  27. static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event)
  28. {
  29. const struct iio_chan_spec *chan;
  30. /* Temperature threshold error, we don't handle this yet */
  31. if (event == 0)
  32. return;
  33. chan = xadc_event_to_channel(indio_dev, event);
  34. if (chan->type == IIO_TEMP) {
  35. /*
  36. * The temperature channel only supports over-temperature
  37. * events.
  38. */
  39. iio_push_event(indio_dev,
  40. IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
  41. IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
  42. iio_get_time_ns(indio_dev));
  43. } else {
  44. /*
  45. * For other channels we don't know whether it is a upper or
  46. * lower threshold event. Userspace will have to check the
  47. * channel value if it wants to know.
  48. */
  49. iio_push_event(indio_dev,
  50. IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
  51. IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER),
  52. iio_get_time_ns(indio_dev));
  53. }
  54. }
  55. void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events)
  56. {
  57. unsigned int i;
  58. for_each_set_bit(i, &events, 8)
  59. xadc_handle_event(indio_dev, i);
  60. }
  61. static unsigned int xadc_get_threshold_offset(const struct iio_chan_spec *chan,
  62. enum iio_event_direction dir)
  63. {
  64. unsigned int offset;
  65. if (chan->type == IIO_TEMP) {
  66. offset = XADC_THRESHOLD_OT_MAX;
  67. } else {
  68. if (chan->channel < 2)
  69. offset = chan->channel + 1;
  70. else
  71. offset = chan->channel + 6;
  72. }
  73. if (dir == IIO_EV_DIR_FALLING)
  74. offset += 4;
  75. return offset;
  76. }
  77. static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan)
  78. {
  79. if (chan->type == IIO_TEMP)
  80. return XADC_ALARM_OT_MASK;
  81. switch (chan->channel) {
  82. case 0:
  83. return XADC_ALARM_VCCINT_MASK;
  84. case 1:
  85. return XADC_ALARM_VCCAUX_MASK;
  86. case 2:
  87. return XADC_ALARM_VCCBRAM_MASK;
  88. case 3:
  89. return XADC_ALARM_VCCPINT_MASK;
  90. case 4:
  91. return XADC_ALARM_VCCPAUX_MASK;
  92. case 5:
  93. return XADC_ALARM_VCCODDR_MASK;
  94. default:
  95. /* We will never get here */
  96. return 0;
  97. }
  98. }
  99. int xadc_read_event_config(struct iio_dev *indio_dev,
  100. const struct iio_chan_spec *chan, enum iio_event_type type,
  101. enum iio_event_direction dir)
  102. {
  103. struct xadc *xadc = iio_priv(indio_dev);
  104. return (bool)(xadc->alarm_mask & xadc_get_alarm_mask(chan));
  105. }
  106. int xadc_write_event_config(struct iio_dev *indio_dev,
  107. const struct iio_chan_spec *chan, enum iio_event_type type,
  108. enum iio_event_direction dir, int state)
  109. {
  110. unsigned int alarm = xadc_get_alarm_mask(chan);
  111. struct xadc *xadc = iio_priv(indio_dev);
  112. uint16_t cfg, old_cfg;
  113. int ret;
  114. mutex_lock(&xadc->mutex);
  115. if (state)
  116. xadc->alarm_mask |= alarm;
  117. else
  118. xadc->alarm_mask &= ~alarm;
  119. xadc->ops->update_alarm(xadc, xadc->alarm_mask);
  120. ret = _xadc_read_adc_reg(xadc, XADC_REG_CONF1, &cfg);
  121. if (ret)
  122. goto err_out;
  123. old_cfg = cfg;
  124. cfg |= XADC_CONF1_ALARM_MASK;
  125. cfg &= ~((xadc->alarm_mask & 0xf0) << 4); /* bram, pint, paux, ddr */
  126. cfg &= ~((xadc->alarm_mask & 0x08) >> 3); /* ot */
  127. cfg &= ~((xadc->alarm_mask & 0x07) << 1); /* temp, vccint, vccaux */
  128. if (old_cfg != cfg)
  129. ret = _xadc_write_adc_reg(xadc, XADC_REG_CONF1, cfg);
  130. err_out:
  131. mutex_unlock(&xadc->mutex);
  132. return ret;
  133. }
  134. /* Register value is msb aligned, the lower 4 bits are ignored */
  135. #define XADC_THRESHOLD_VALUE_SHIFT 4
  136. int xadc_read_event_value(struct iio_dev *indio_dev,
  137. const struct iio_chan_spec *chan, enum iio_event_type type,
  138. enum iio_event_direction dir, enum iio_event_info info,
  139. int *val, int *val2)
  140. {
  141. unsigned int offset = xadc_get_threshold_offset(chan, dir);
  142. struct xadc *xadc = iio_priv(indio_dev);
  143. switch (info) {
  144. case IIO_EV_INFO_VALUE:
  145. *val = xadc->threshold[offset];
  146. break;
  147. case IIO_EV_INFO_HYSTERESIS:
  148. *val = xadc->temp_hysteresis;
  149. break;
  150. default:
  151. return -EINVAL;
  152. }
  153. *val >>= XADC_THRESHOLD_VALUE_SHIFT;
  154. return IIO_VAL_INT;
  155. }
  156. int xadc_write_event_value(struct iio_dev *indio_dev,
  157. const struct iio_chan_spec *chan, enum iio_event_type type,
  158. enum iio_event_direction dir, enum iio_event_info info,
  159. int val, int val2)
  160. {
  161. unsigned int offset = xadc_get_threshold_offset(chan, dir);
  162. struct xadc *xadc = iio_priv(indio_dev);
  163. int ret = 0;
  164. val <<= XADC_THRESHOLD_VALUE_SHIFT;
  165. if (val < 0 || val > 0xffff)
  166. return -EINVAL;
  167. mutex_lock(&xadc->mutex);
  168. switch (info) {
  169. case IIO_EV_INFO_VALUE:
  170. xadc->threshold[offset] = val;
  171. break;
  172. case IIO_EV_INFO_HYSTERESIS:
  173. xadc->temp_hysteresis = val;
  174. break;
  175. default:
  176. mutex_unlock(&xadc->mutex);
  177. return -EINVAL;
  178. }
  179. if (chan->type == IIO_TEMP) {
  180. /*
  181. * According to the datasheet we need to set the lower 4 bits to
  182. * 0x3, otherwise 125 degree celsius will be used as the
  183. * threshold.
  184. */
  185. val |= 0x3;
  186. /*
  187. * Since we store the hysteresis as relative (to the threshold)
  188. * value, but the hardware expects an absolute value we need to
  189. * recalcualte this value whenever the hysteresis or the
  190. * threshold changes.
  191. */
  192. if (xadc->threshold[offset] < xadc->temp_hysteresis)
  193. xadc->threshold[offset + 4] = 0;
  194. else
  195. xadc->threshold[offset + 4] = xadc->threshold[offset] -
  196. xadc->temp_hysteresis;
  197. ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset + 4),
  198. xadc->threshold[offset + 4]);
  199. if (ret)
  200. goto out_unlock;
  201. }
  202. if (info == IIO_EV_INFO_VALUE)
  203. ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset), val);
  204. out_unlock:
  205. mutex_unlock(&xadc->mutex);
  206. return ret;
  207. }