/* All Semtech SAR sensors have IRQ bit in the same order. */ #define SX_COMMON_CONVDONE_IRQ BIT(0) #define SX_COMMON_FAR_IRQ BIT(2) #define SX_COMMON_CLOSE_IRQ BIT(3)
if (data->trigger_enabled)
iio_trigger_poll(data->trig);
/* * Even if no event is enabled, we need to wake the thread to clear the * interrupt state by reading SX_COMMON_REG_IRQ_SRC. * It is not possible to do that here because regmap_read takes a mutex.
*/ return IRQ_WAKE_THREAD;
}
/* Read proximity state on all channels */
ret = regmap_read(data->regmap, data->chip_info->reg_stat, &val); if (ret) {
dev_err(&data->client->dev, "i2c transfer error in irq\n"); return;
}
val >>= data->chip_info->stat_offset;
/* * Only iterate over channels with changes on proximity status that have * events enabled.
*/
prox_changed = (data->chan_prox_stat ^ val) & data->chan_event;
for_each_set_bit(chan, &prox_changed, data->chip_info->num_channels) { int dir;
u64 ev;
dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING;
ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan,
IIO_EV_TYPE_THRESH, dir);
/** * sx_common_read_proximity() - Read raw proximity value. * @data: Internal data * @chan: Channel to read * @val: pointer to return read value. * * Request a conversion, wait for the sensor to be ready and * return the raw proximity value.
*/ int sx_common_read_proximity(struct sx_common_data *data, conststruct iio_chan_spec *chan, int *val)
{ int ret;
__be16 rawval;
mutex_lock(&data->mutex);
ret = sx_common_get_read_channel(data, chan->channel); if (ret) goto out;
ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ); if (ret) goto out_put_channel;
mutex_unlock(&data->mutex);
if (data->client->irq) {
ret = wait_for_completion_interruptible(&data->completion);
reinit_completion(&data->completion);
} else {
ret = data->chip_info->ops.wait_for_sample(data);
}
mutex_lock(&data->mutex);
if (ret) goto out_disable_irq;
ret = data->chip_info->ops.read_prox_data(data, chan, &rawval); if (ret) goto out_disable_irq;
/** * sx_common_write_event_config() - Configure event setting. * @indio_dev: iio device object * @chan: Channel to enable * @type: Type of event (unused) * @dir: Direction of event (unused) * @state: State of the event. * * Enable/Disable event on a given channel.
*/ int sx_common_write_event_config(struct iio_dev *indio_dev, conststruct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, bool state)
{ struct sx_common_data *data = iio_priv(indio_dev); unsignedint eventirq = SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ; int ret;
/* If the state hasn't changed, there's nothing to do. */ if (!!(data->chan_event & BIT(chan->channel)) == state) return 0;
mutex_lock(&data->mutex); if (state) {
ret = sx_common_get_event_channel(data, chan->channel); if (ret) goto out_unlock; if (!(data->chan_event & ~BIT(chan->channel))) {
ret = sx_common_enable_irq(data, eventirq); if (ret)
sx_common_put_event_channel(data, chan->channel);
}
} else {
ret = sx_common_put_event_channel(data, chan->channel); if (ret) goto out_unlock; if (!data->chan_event) {
ret = sx_common_disable_irq(data, eventirq); if (ret)
sx_common_get_event_channel(data, chan->channel);
}
}
if (state)
ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ); elseif (!data->chan_read)
ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); if (ret) goto out;
ret = regmap_write(data->regmap, data->chip_info->reg_reset,
SX_COMMON_SOFT_RESET); if (ret) return ret;
usleep_range(1000, 2000); /* power-up time is ~1ms. */
/* Clear reset interrupt state by reading SX_COMMON_REG_IRQ_SRC. */
ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val); if (ret) return ret;
/* Program defaults from constant or BIOS. */ for (i = 0; i < data->chip_info->num_default_regs; i++) {
initval = data->chip_info->ops.get_default_reg(dev, i, &tmp);
ret = regmap_write(data->regmap, initval->reg, initval->def); if (ret) return ret;
}
ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
regulator_names); if (ret) return dev_err_probe(dev, ret, "Unable to get regulators\n");
/* Must wait for Tpor time after initial power up */
usleep_range(1000, 1100);
ret = data->chip_info->ops.check_whoami(dev, indio_dev); if (ret) return dev_err_probe(dev, ret, "error reading WHOAMI\n");
ret = sx_common_init_device(dev, indio_dev); if (ret) return dev_err_probe(dev, ret, "Unable to initialize sensor\n");
if (client->irq) {
ret = devm_request_threaded_irq(dev, client->irq,
sx_common_irq_handler,
sx_common_irq_thread_handler,
IRQF_ONESHOT, "sx_event", indio_dev); if (ret) return dev_err_probe(dev, ret, "No IRQ\n");
data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
indio_dev->name,
iio_device_id(indio_dev)); if (!data->trig) return -ENOMEM;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.