cregit-Linux how code gets into the kernel

Release 4.7 drivers/iio/adc/xilinx-xadc-events.c

Directory: drivers/iio/adc
/*
 * Xilinx XADC driver
 *
 * Copyright 2013 Analog Devices Inc.
 *  Author: Lars-Peter Clauen <lars@metafoo.de>
 *
 * Licensed under the GPL-2.
 */

#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/kernel.h>

#include "xilinx-xadc.h"


static const struct iio_chan_spec *xadc_event_to_channel( struct iio_dev *indio_dev, unsigned int event) { switch (event) { case XADC_THRESHOLD_OT_MAX: case XADC_THRESHOLD_TEMP_MAX: return &indio_dev->channels[0]; case XADC_THRESHOLD_VCCINT_MAX: case XADC_THRESHOLD_VCCAUX_MAX: return &indio_dev->channels[event]; default: return &indio_dev->channels[event-1]; } }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen66100.00%1100.00%
Total66100.00%1100.00%


static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event) { const struct iio_chan_spec *chan; /* Temperature threshold error, we don't handle this yet */ if (event == 0) return; chan = xadc_event_to_channel(indio_dev, event); if (chan->type == IIO_TEMP) { /* * The temperature channel only supports over-temperature * events. */ iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), iio_get_time_ns()); } else { /* * For other channels we don't know whether it is a upper or * lower threshold event. Userspace will have to check the * channel value if it wants to know. */ iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), iio_get_time_ns()); } }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen99100.00%1100.00%
Total99100.00%1100.00%


void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events) { unsigned int i; for_each_set_bit(i, &events, 8) xadc_handle_event(indio_dev, i); }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen33100.00%1100.00%
Total33100.00%1100.00%


static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan, enum iio_event_direction dir) { unsigned int offset; if (chan->type == IIO_TEMP) { offset = XADC_THRESHOLD_OT_MAX; } else { if (chan->channel < 2) offset = chan->channel + 1; else offset = chan->channel + 6; } if (dir == IIO_EV_DIR_FALLING) offset += 4; return offset; }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen75100.00%1100.00%
Total75100.00%1100.00%


static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan) { if (chan->type == IIO_TEMP) { return XADC_ALARM_OT_MASK; } else { switch (chan->channel) { case 0: return XADC_ALARM_VCCINT_MASK; case 1: return XADC_ALARM_VCCAUX_MASK; case 2: return XADC_ALARM_VCCBRAM_MASK; case 3: return XADC_ALARM_VCCPINT_MASK; case 4: return XADC_ALARM_VCCPAUX_MASK; case 5: return XADC_ALARM_VCCODDR_MASK; default: /* We will never get here */ return 0; } } }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen78100.00%1100.00%
Total78100.00%1100.00%


int xadc_read_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir) { struct xadc *xadc = iio_priv(indio_dev); return (bool)(xadc->alarm_mask & xadc_get_alarm_mask(chan)); }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen49100.00%1100.00%
Total49100.00%1100.00%


int xadc_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, int state) { unsigned int alarm = xadc_get_alarm_mask(chan); struct xadc *xadc = iio_priv(indio_dev); uint16_t cfg, old_cfg; int ret; mutex_lock(&xadc->mutex); if (state) xadc->alarm_mask |= alarm; else xadc->alarm_mask &= ~alarm; xadc->ops->update_alarm(xadc, xadc->alarm_mask); ret = _xadc_read_adc_reg(xadc, XADC_REG_CONF1, &cfg); if (ret) goto err_out; old_cfg = cfg; cfg |= XADC_CONF1_ALARM_MASK; cfg &= ~((xadc->alarm_mask & 0xf0) << 4); /* bram, pint, paux, ddr */ cfg &= ~((xadc->alarm_mask & 0x08) >> 3); /* ot */ cfg &= ~((xadc->alarm_mask & 0x07) << 1); /* temp, vccint, vccaux */ if (old_cfg != cfg) ret = _xadc_write_adc_reg(xadc, XADC_REG_CONF1, cfg); err_out: mutex_unlock(&xadc->mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen198100.00%1100.00%
Total198100.00%1100.00%

/* Register value is msb aligned, the lower 4 bits are ignored */ #define XADC_THRESHOLD_VALUE_SHIFT 4
int xadc_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, enum iio_event_info info, int *val, int *val2) { unsigned int offset = xadc_get_threshold_offset(chan, dir); struct xadc *xadc = iio_priv(indio_dev); switch (info) { case IIO_EV_INFO_VALUE: *val = xadc->threshold[offset]; break; case IIO_EV_INFO_HYSTERESIS: *val = xadc->temp_hysteresis; break; default: return -EINVAL; } *val >>= XADC_THRESHOLD_VALUE_SHIFT; return IIO_VAL_INT; }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen101100.00%1100.00%
Total101100.00%1100.00%


int xadc_write_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, enum iio_event_info info, int val, int val2) { unsigned int offset = xadc_get_threshold_offset(chan, dir); struct xadc *xadc = iio_priv(indio_dev); int ret = 0; val <<= XADC_THRESHOLD_VALUE_SHIFT; if (val < 0 || val > 0xffff) return -EINVAL; mutex_lock(&xadc->mutex); switch (info) { case IIO_EV_INFO_VALUE: xadc->threshold[offset] = val; break; case IIO_EV_INFO_HYSTERESIS: xadc->temp_hysteresis = val; break; default: mutex_unlock(&xadc->mutex); return -EINVAL; } if (chan->type == IIO_TEMP) { /* * According to the datasheet we need to set the lower 4 bits to * 0x3, otherwise 125 degree celsius will be used as the * threshold. */ val |= 0x3; /* * Since we store the hysteresis as relative (to the threshold) * value, but the hardware expects an absolute value we need to * recalcualte this value whenever the hysteresis or the * threshold changes. */ if (xadc->threshold[offset] < xadc->temp_hysteresis) xadc->threshold[offset + 4] = 0; else xadc->threshold[offset + 4] = xadc->threshold[offset] - xadc->temp_hysteresis; ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset + 4), xadc->threshold[offset + 4]); if (ret) goto out_unlock; } if (info == IIO_EV_INFO_VALUE) ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset), val); out_unlock: mutex_unlock(&xadc->mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen252100.00%1100.00%
Total252100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen969100.00%1100.00%
Total969100.00%1100.00%
Directory: drivers/iio/adc
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}