1caa8ce7fSGwendal Grignou // SPDX-License-Identifier: GPL-2.0 2caa8ce7fSGwendal Grignou /* 3caa8ce7fSGwendal Grignou * Copyright 2021 Google LLC. 4caa8ce7fSGwendal Grignou * 5caa8ce7fSGwendal Grignou * Common part of most Semtech SAR sensor. 6caa8ce7fSGwendal Grignou */ 7caa8ce7fSGwendal Grignou 8caa8ce7fSGwendal Grignou #include <linux/acpi.h> 9caa8ce7fSGwendal Grignou #include <linux/bitops.h> 10caa8ce7fSGwendal Grignou #include <linux/byteorder/generic.h> 11caa8ce7fSGwendal Grignou #include <linux/delay.h> 12caa8ce7fSGwendal Grignou #include <linux/device.h> 13caa8ce7fSGwendal Grignou #include <linux/err.h> 14caa8ce7fSGwendal Grignou #include <linux/export.h> 15caa8ce7fSGwendal Grignou #include <linux/interrupt.h> 16caa8ce7fSGwendal Grignou #include <linux/irqreturn.h> 17caa8ce7fSGwendal Grignou #include <linux/i2c.h> 18caa8ce7fSGwendal Grignou #include <linux/kernel.h> 19caa8ce7fSGwendal Grignou #include <linux/module.h> 20caa8ce7fSGwendal Grignou #include <linux/regmap.h> 21caa8ce7fSGwendal Grignou #include <linux/regulator/consumer.h> 22caa8ce7fSGwendal Grignou #include <vdso/bits.h> 23caa8ce7fSGwendal Grignou 24caa8ce7fSGwendal Grignou #include <linux/iio/buffer.h> 25caa8ce7fSGwendal Grignou #include <linux/iio/events.h> 26caa8ce7fSGwendal Grignou #include <linux/iio/iio.h> 27caa8ce7fSGwendal Grignou #include <linux/iio/trigger.h> 28caa8ce7fSGwendal Grignou #include <linux/iio/triggered_buffer.h> 29caa8ce7fSGwendal Grignou #include <linux/iio/trigger_consumer.h> 30caa8ce7fSGwendal Grignou 31caa8ce7fSGwendal Grignou #include "sx_common.h" 32caa8ce7fSGwendal Grignou 33caa8ce7fSGwendal Grignou /* All Semtech SAR sensors have IRQ bit in the same order. */ 34caa8ce7fSGwendal Grignou #define SX_COMMON_CONVDONE_IRQ BIT(0) 35caa8ce7fSGwendal Grignou #define SX_COMMON_FAR_IRQ BIT(2) 36caa8ce7fSGwendal Grignou #define SX_COMMON_CLOSE_IRQ BIT(3) 37caa8ce7fSGwendal Grignou 38caa8ce7fSGwendal Grignou const struct iio_event_spec sx_common_events[3] = { 39caa8ce7fSGwendal Grignou { 40caa8ce7fSGwendal Grignou .type = IIO_EV_TYPE_THRESH, 41caa8ce7fSGwendal Grignou .dir = IIO_EV_DIR_RISING, 42caa8ce7fSGwendal Grignou .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD), 43caa8ce7fSGwendal Grignou }, 44caa8ce7fSGwendal Grignou { 45caa8ce7fSGwendal Grignou .type = IIO_EV_TYPE_THRESH, 46caa8ce7fSGwendal Grignou .dir = IIO_EV_DIR_FALLING, 47caa8ce7fSGwendal Grignou .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD), 48caa8ce7fSGwendal Grignou }, 49caa8ce7fSGwendal Grignou { 50caa8ce7fSGwendal Grignou .type = IIO_EV_TYPE_THRESH, 51caa8ce7fSGwendal Grignou .dir = IIO_EV_DIR_EITHER, 52caa8ce7fSGwendal Grignou .mask_separate = BIT(IIO_EV_INFO_ENABLE) | 53caa8ce7fSGwendal Grignou BIT(IIO_EV_INFO_HYSTERESIS) | 54caa8ce7fSGwendal Grignou BIT(IIO_EV_INFO_VALUE), 55caa8ce7fSGwendal Grignou }, 56caa8ce7fSGwendal Grignou }; 57caa8ce7fSGwendal Grignou EXPORT_SYMBOL_NS_GPL(sx_common_events, SEMTECH_PROX); 58caa8ce7fSGwendal Grignou 59caa8ce7fSGwendal Grignou static irqreturn_t sx_common_irq_handler(int irq, void *private) 60caa8ce7fSGwendal Grignou { 61caa8ce7fSGwendal Grignou struct iio_dev *indio_dev = private; 62caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 63caa8ce7fSGwendal Grignou 64caa8ce7fSGwendal Grignou if (data->trigger_enabled) 65caa8ce7fSGwendal Grignou iio_trigger_poll(data->trig); 66caa8ce7fSGwendal Grignou 67caa8ce7fSGwendal Grignou /* 68caa8ce7fSGwendal Grignou * Even if no event is enabled, we need to wake the thread to clear the 69caa8ce7fSGwendal Grignou * interrupt state by reading SX_COMMON_REG_IRQ_SRC. 70caa8ce7fSGwendal Grignou * It is not possible to do that here because regmap_read takes a mutex. 71caa8ce7fSGwendal Grignou */ 72caa8ce7fSGwendal Grignou return IRQ_WAKE_THREAD; 73caa8ce7fSGwendal Grignou } 74caa8ce7fSGwendal Grignou 75caa8ce7fSGwendal Grignou static void sx_common_push_events(struct iio_dev *indio_dev) 76caa8ce7fSGwendal Grignou { 77caa8ce7fSGwendal Grignou int ret; 78caa8ce7fSGwendal Grignou unsigned int val, chan; 79caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 80caa8ce7fSGwendal Grignou s64 timestamp = iio_get_time_ns(indio_dev); 81caa8ce7fSGwendal Grignou unsigned long prox_changed; 82caa8ce7fSGwendal Grignou 83caa8ce7fSGwendal Grignou /* Read proximity state on all channels */ 84caa8ce7fSGwendal Grignou ret = regmap_read(data->regmap, data->chip_info->reg_stat, &val); 85caa8ce7fSGwendal Grignou if (ret) { 86caa8ce7fSGwendal Grignou dev_err(&data->client->dev, "i2c transfer error in irq\n"); 87caa8ce7fSGwendal Grignou return; 88caa8ce7fSGwendal Grignou } 89caa8ce7fSGwendal Grignou 9019d32860SJongpil Jung val >>= data->chip_info->stat_offset; 91caa8ce7fSGwendal Grignou 92caa8ce7fSGwendal Grignou /* 93caa8ce7fSGwendal Grignou * Only iterate over channels with changes on proximity status that have 94caa8ce7fSGwendal Grignou * events enabled. 95caa8ce7fSGwendal Grignou */ 96caa8ce7fSGwendal Grignou prox_changed = (data->chan_prox_stat ^ val) & data->chan_event; 97caa8ce7fSGwendal Grignou 98caa8ce7fSGwendal Grignou for_each_set_bit(chan, &prox_changed, data->chip_info->num_channels) { 99caa8ce7fSGwendal Grignou int dir; 100caa8ce7fSGwendal Grignou u64 ev; 101caa8ce7fSGwendal Grignou 102caa8ce7fSGwendal Grignou dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; 103caa8ce7fSGwendal Grignou ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan, 104caa8ce7fSGwendal Grignou IIO_EV_TYPE_THRESH, dir); 105caa8ce7fSGwendal Grignou 106caa8ce7fSGwendal Grignou iio_push_event(indio_dev, ev, timestamp); 107caa8ce7fSGwendal Grignou } 108caa8ce7fSGwendal Grignou data->chan_prox_stat = val; 109caa8ce7fSGwendal Grignou } 110caa8ce7fSGwendal Grignou 111caa8ce7fSGwendal Grignou static int sx_common_enable_irq(struct sx_common_data *data, unsigned int irq) 112caa8ce7fSGwendal Grignou { 113caa8ce7fSGwendal Grignou if (!data->client->irq) 114caa8ce7fSGwendal Grignou return 0; 115caa8ce7fSGwendal Grignou return regmap_update_bits(data->regmap, data->chip_info->reg_irq_msk, 116caa8ce7fSGwendal Grignou irq << data->chip_info->irq_msk_offset, 117caa8ce7fSGwendal Grignou irq << data->chip_info->irq_msk_offset); 118caa8ce7fSGwendal Grignou } 119caa8ce7fSGwendal Grignou 120caa8ce7fSGwendal Grignou static int sx_common_disable_irq(struct sx_common_data *data, unsigned int irq) 121caa8ce7fSGwendal Grignou { 122caa8ce7fSGwendal Grignou if (!data->client->irq) 123caa8ce7fSGwendal Grignou return 0; 124caa8ce7fSGwendal Grignou return regmap_update_bits(data->regmap, data->chip_info->reg_irq_msk, 125caa8ce7fSGwendal Grignou irq << data->chip_info->irq_msk_offset, 0); 126caa8ce7fSGwendal Grignou } 127caa8ce7fSGwendal Grignou 128caa8ce7fSGwendal Grignou static int sx_common_update_chan_en(struct sx_common_data *data, 129caa8ce7fSGwendal Grignou unsigned long chan_read, 130caa8ce7fSGwendal Grignou unsigned long chan_event) 131caa8ce7fSGwendal Grignou { 132caa8ce7fSGwendal Grignou int ret; 133caa8ce7fSGwendal Grignou unsigned long channels = chan_read | chan_event; 134caa8ce7fSGwendal Grignou 135caa8ce7fSGwendal Grignou if ((data->chan_read | data->chan_event) != channels) { 136caa8ce7fSGwendal Grignou ret = regmap_update_bits(data->regmap, 137caa8ce7fSGwendal Grignou data->chip_info->reg_enable_chan, 138caa8ce7fSGwendal Grignou data->chip_info->mask_enable_chan, 139caa8ce7fSGwendal Grignou channels); 140caa8ce7fSGwendal Grignou if (ret) 141caa8ce7fSGwendal Grignou return ret; 142caa8ce7fSGwendal Grignou } 143caa8ce7fSGwendal Grignou data->chan_read = chan_read; 144caa8ce7fSGwendal Grignou data->chan_event = chan_event; 145caa8ce7fSGwendal Grignou return 0; 146caa8ce7fSGwendal Grignou } 147caa8ce7fSGwendal Grignou 148caa8ce7fSGwendal Grignou static int sx_common_get_read_channel(struct sx_common_data *data, int channel) 149caa8ce7fSGwendal Grignou { 150caa8ce7fSGwendal Grignou return sx_common_update_chan_en(data, data->chan_read | BIT(channel), 151caa8ce7fSGwendal Grignou data->chan_event); 152caa8ce7fSGwendal Grignou } 153caa8ce7fSGwendal Grignou 154caa8ce7fSGwendal Grignou static int sx_common_put_read_channel(struct sx_common_data *data, int channel) 155caa8ce7fSGwendal Grignou { 156caa8ce7fSGwendal Grignou return sx_common_update_chan_en(data, data->chan_read & ~BIT(channel), 157caa8ce7fSGwendal Grignou data->chan_event); 158caa8ce7fSGwendal Grignou } 159caa8ce7fSGwendal Grignou 160caa8ce7fSGwendal Grignou static int sx_common_get_event_channel(struct sx_common_data *data, int channel) 161caa8ce7fSGwendal Grignou { 162caa8ce7fSGwendal Grignou return sx_common_update_chan_en(data, data->chan_read, 163caa8ce7fSGwendal Grignou data->chan_event | BIT(channel)); 164caa8ce7fSGwendal Grignou } 165caa8ce7fSGwendal Grignou 166caa8ce7fSGwendal Grignou static int sx_common_put_event_channel(struct sx_common_data *data, int channel) 167caa8ce7fSGwendal Grignou { 168caa8ce7fSGwendal Grignou return sx_common_update_chan_en(data, data->chan_read, 169caa8ce7fSGwendal Grignou data->chan_event & ~BIT(channel)); 170caa8ce7fSGwendal Grignou } 171caa8ce7fSGwendal Grignou 172caa8ce7fSGwendal Grignou /** 173caa8ce7fSGwendal Grignou * sx_common_read_proximity() - Read raw proximity value. 174caa8ce7fSGwendal Grignou * @data: Internal data 175caa8ce7fSGwendal Grignou * @chan: Channel to read 176caa8ce7fSGwendal Grignou * @val: pointer to return read value. 177caa8ce7fSGwendal Grignou * 178caa8ce7fSGwendal Grignou * Request a conversion, wait for the sensor to be ready and 179caa8ce7fSGwendal Grignou * return the raw proximity value. 180caa8ce7fSGwendal Grignou */ 181caa8ce7fSGwendal Grignou int sx_common_read_proximity(struct sx_common_data *data, 182caa8ce7fSGwendal Grignou const struct iio_chan_spec *chan, int *val) 183caa8ce7fSGwendal Grignou { 184caa8ce7fSGwendal Grignou int ret; 185caa8ce7fSGwendal Grignou __be16 rawval; 186caa8ce7fSGwendal Grignou 187caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 188caa8ce7fSGwendal Grignou 189caa8ce7fSGwendal Grignou ret = sx_common_get_read_channel(data, chan->channel); 190caa8ce7fSGwendal Grignou if (ret) 191caa8ce7fSGwendal Grignou goto out; 192caa8ce7fSGwendal Grignou 193caa8ce7fSGwendal Grignou ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ); 194caa8ce7fSGwendal Grignou if (ret) 195caa8ce7fSGwendal Grignou goto out_put_channel; 196caa8ce7fSGwendal Grignou 197caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 198caa8ce7fSGwendal Grignou 199caa8ce7fSGwendal Grignou if (data->client->irq) { 200caa8ce7fSGwendal Grignou ret = wait_for_completion_interruptible(&data->completion); 201caa8ce7fSGwendal Grignou reinit_completion(&data->completion); 202caa8ce7fSGwendal Grignou } else { 203caa8ce7fSGwendal Grignou ret = data->chip_info->ops.wait_for_sample(data); 204caa8ce7fSGwendal Grignou } 205caa8ce7fSGwendal Grignou 206caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 207caa8ce7fSGwendal Grignou 208caa8ce7fSGwendal Grignou if (ret) 209caa8ce7fSGwendal Grignou goto out_disable_irq; 210caa8ce7fSGwendal Grignou 211caa8ce7fSGwendal Grignou ret = data->chip_info->ops.read_prox_data(data, chan, &rawval); 212caa8ce7fSGwendal Grignou if (ret) 213caa8ce7fSGwendal Grignou goto out_disable_irq; 214caa8ce7fSGwendal Grignou 215caa8ce7fSGwendal Grignou *val = sign_extend32(be16_to_cpu(rawval), chan->scan_type.realbits - 1); 216caa8ce7fSGwendal Grignou 217caa8ce7fSGwendal Grignou ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); 218caa8ce7fSGwendal Grignou if (ret) 219caa8ce7fSGwendal Grignou goto out_put_channel; 220caa8ce7fSGwendal Grignou 221caa8ce7fSGwendal Grignou ret = sx_common_put_read_channel(data, chan->channel); 222caa8ce7fSGwendal Grignou if (ret) 223caa8ce7fSGwendal Grignou goto out; 224caa8ce7fSGwendal Grignou 225caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 226caa8ce7fSGwendal Grignou 227caa8ce7fSGwendal Grignou return IIO_VAL_INT; 228caa8ce7fSGwendal Grignou 229caa8ce7fSGwendal Grignou out_disable_irq: 230caa8ce7fSGwendal Grignou sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); 231caa8ce7fSGwendal Grignou out_put_channel: 232caa8ce7fSGwendal Grignou sx_common_put_read_channel(data, chan->channel); 233caa8ce7fSGwendal Grignou out: 234caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 235caa8ce7fSGwendal Grignou 236caa8ce7fSGwendal Grignou return ret; 237caa8ce7fSGwendal Grignou } 238caa8ce7fSGwendal Grignou EXPORT_SYMBOL_NS_GPL(sx_common_read_proximity, SEMTECH_PROX); 239caa8ce7fSGwendal Grignou 240caa8ce7fSGwendal Grignou /** 241caa8ce7fSGwendal Grignou * sx_common_read_event_config() - Configure event setting. 242caa8ce7fSGwendal Grignou * @indio_dev: iio device object 243caa8ce7fSGwendal Grignou * @chan: Channel to read 244caa8ce7fSGwendal Grignou * @type: Type of event (unused) 245caa8ce7fSGwendal Grignou * @dir: Direction of event (unused) 246caa8ce7fSGwendal Grignou * 247caa8ce7fSGwendal Grignou * return if the given channel is used for event gathering. 248caa8ce7fSGwendal Grignou */ 249caa8ce7fSGwendal Grignou int sx_common_read_event_config(struct iio_dev *indio_dev, 250caa8ce7fSGwendal Grignou const struct iio_chan_spec *chan, 251caa8ce7fSGwendal Grignou enum iio_event_type type, 252caa8ce7fSGwendal Grignou enum iio_event_direction dir) 253caa8ce7fSGwendal Grignou { 254caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 255caa8ce7fSGwendal Grignou 256caa8ce7fSGwendal Grignou return !!(data->chan_event & BIT(chan->channel)); 257caa8ce7fSGwendal Grignou } 258caa8ce7fSGwendal Grignou EXPORT_SYMBOL_NS_GPL(sx_common_read_event_config, SEMTECH_PROX); 259caa8ce7fSGwendal Grignou 260caa8ce7fSGwendal Grignou /** 261caa8ce7fSGwendal Grignou * sx_common_write_event_config() - Configure event setting. 262caa8ce7fSGwendal Grignou * @indio_dev: iio device object 263caa8ce7fSGwendal Grignou * @chan: Channel to enable 264caa8ce7fSGwendal Grignou * @type: Type of event (unused) 265caa8ce7fSGwendal Grignou * @dir: Direction of event (unused) 266caa8ce7fSGwendal Grignou * @state: State of the event. 267caa8ce7fSGwendal Grignou * 268caa8ce7fSGwendal Grignou * Enable/Disable event on a given channel. 269caa8ce7fSGwendal Grignou */ 270caa8ce7fSGwendal Grignou int sx_common_write_event_config(struct iio_dev *indio_dev, 271caa8ce7fSGwendal Grignou const struct iio_chan_spec *chan, 272caa8ce7fSGwendal Grignou enum iio_event_type type, 273caa8ce7fSGwendal Grignou enum iio_event_direction dir, int state) 274caa8ce7fSGwendal Grignou { 275caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 276caa8ce7fSGwendal Grignou unsigned int eventirq = SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ; 277caa8ce7fSGwendal Grignou int ret; 278caa8ce7fSGwendal Grignou 279caa8ce7fSGwendal Grignou /* If the state hasn't changed, there's nothing to do. */ 280caa8ce7fSGwendal Grignou if (!!(data->chan_event & BIT(chan->channel)) == state) 281caa8ce7fSGwendal Grignou return 0; 282caa8ce7fSGwendal Grignou 283caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 284caa8ce7fSGwendal Grignou if (state) { 285caa8ce7fSGwendal Grignou ret = sx_common_get_event_channel(data, chan->channel); 286caa8ce7fSGwendal Grignou if (ret) 287caa8ce7fSGwendal Grignou goto out_unlock; 288caa8ce7fSGwendal Grignou if (!(data->chan_event & ~BIT(chan->channel))) { 289caa8ce7fSGwendal Grignou ret = sx_common_enable_irq(data, eventirq); 290caa8ce7fSGwendal Grignou if (ret) 291caa8ce7fSGwendal Grignou sx_common_put_event_channel(data, chan->channel); 292caa8ce7fSGwendal Grignou } 293caa8ce7fSGwendal Grignou } else { 294caa8ce7fSGwendal Grignou ret = sx_common_put_event_channel(data, chan->channel); 295caa8ce7fSGwendal Grignou if (ret) 296caa8ce7fSGwendal Grignou goto out_unlock; 297caa8ce7fSGwendal Grignou if (!data->chan_event) { 298caa8ce7fSGwendal Grignou ret = sx_common_disable_irq(data, eventirq); 299caa8ce7fSGwendal Grignou if (ret) 300caa8ce7fSGwendal Grignou sx_common_get_event_channel(data, chan->channel); 301caa8ce7fSGwendal Grignou } 302caa8ce7fSGwendal Grignou } 303caa8ce7fSGwendal Grignou 304caa8ce7fSGwendal Grignou out_unlock: 305caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 306caa8ce7fSGwendal Grignou return ret; 307caa8ce7fSGwendal Grignou } 308caa8ce7fSGwendal Grignou EXPORT_SYMBOL_NS_GPL(sx_common_write_event_config, SEMTECH_PROX); 309caa8ce7fSGwendal Grignou 310caa8ce7fSGwendal Grignou static int sx_common_set_trigger_state(struct iio_trigger *trig, bool state) 311caa8ce7fSGwendal Grignou { 312caa8ce7fSGwendal Grignou struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 313caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 314caa8ce7fSGwendal Grignou int ret = 0; 315caa8ce7fSGwendal Grignou 316caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 317caa8ce7fSGwendal Grignou 318caa8ce7fSGwendal Grignou if (state) 319caa8ce7fSGwendal Grignou ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ); 320caa8ce7fSGwendal Grignou else if (!data->chan_read) 321caa8ce7fSGwendal Grignou ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); 322caa8ce7fSGwendal Grignou if (ret) 323caa8ce7fSGwendal Grignou goto out; 324caa8ce7fSGwendal Grignou 325caa8ce7fSGwendal Grignou data->trigger_enabled = state; 326caa8ce7fSGwendal Grignou 327caa8ce7fSGwendal Grignou out: 328caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 329caa8ce7fSGwendal Grignou 330caa8ce7fSGwendal Grignou return ret; 331caa8ce7fSGwendal Grignou } 332caa8ce7fSGwendal Grignou 333caa8ce7fSGwendal Grignou static const struct iio_trigger_ops sx_common_trigger_ops = { 334caa8ce7fSGwendal Grignou .set_trigger_state = sx_common_set_trigger_state, 335caa8ce7fSGwendal Grignou }; 336caa8ce7fSGwendal Grignou 337caa8ce7fSGwendal Grignou static irqreturn_t sx_common_irq_thread_handler(int irq, void *private) 338caa8ce7fSGwendal Grignou { 339caa8ce7fSGwendal Grignou struct iio_dev *indio_dev = private; 340caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 341caa8ce7fSGwendal Grignou int ret; 342caa8ce7fSGwendal Grignou unsigned int val; 343caa8ce7fSGwendal Grignou 344caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 345caa8ce7fSGwendal Grignou 346caa8ce7fSGwendal Grignou ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val); 347caa8ce7fSGwendal Grignou if (ret) { 348caa8ce7fSGwendal Grignou dev_err(&data->client->dev, "i2c transfer error in irq\n"); 349caa8ce7fSGwendal Grignou goto out; 350caa8ce7fSGwendal Grignou } 351caa8ce7fSGwendal Grignou 352caa8ce7fSGwendal Grignou if (val & ((SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ) << data->chip_info->irq_msk_offset)) 353caa8ce7fSGwendal Grignou sx_common_push_events(indio_dev); 354caa8ce7fSGwendal Grignou 355caa8ce7fSGwendal Grignou if (val & (SX_COMMON_CONVDONE_IRQ << data->chip_info->irq_msk_offset)) 356caa8ce7fSGwendal Grignou complete(&data->completion); 357caa8ce7fSGwendal Grignou 358caa8ce7fSGwendal Grignou out: 359caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 360caa8ce7fSGwendal Grignou 361caa8ce7fSGwendal Grignou return IRQ_HANDLED; 362caa8ce7fSGwendal Grignou } 363caa8ce7fSGwendal Grignou 364caa8ce7fSGwendal Grignou static irqreturn_t sx_common_trigger_handler(int irq, void *private) 365caa8ce7fSGwendal Grignou { 366caa8ce7fSGwendal Grignou struct iio_poll_func *pf = private; 367caa8ce7fSGwendal Grignou struct iio_dev *indio_dev = pf->indio_dev; 368caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 369caa8ce7fSGwendal Grignou __be16 val; 370caa8ce7fSGwendal Grignou int bit, ret, i = 0; 371caa8ce7fSGwendal Grignou 372caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 373caa8ce7fSGwendal Grignou 374caa8ce7fSGwendal Grignou for_each_set_bit(bit, indio_dev->active_scan_mask, 375caa8ce7fSGwendal Grignou indio_dev->masklength) { 376caa8ce7fSGwendal Grignou ret = data->chip_info->ops.read_prox_data(data, 377caa8ce7fSGwendal Grignou &indio_dev->channels[bit], 378caa8ce7fSGwendal Grignou &val); 379caa8ce7fSGwendal Grignou if (ret) 380caa8ce7fSGwendal Grignou goto out; 381caa8ce7fSGwendal Grignou 382caa8ce7fSGwendal Grignou data->buffer.channels[i++] = val; 383caa8ce7fSGwendal Grignou } 384caa8ce7fSGwendal Grignou 385caa8ce7fSGwendal Grignou iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, 386caa8ce7fSGwendal Grignou pf->timestamp); 387caa8ce7fSGwendal Grignou 388caa8ce7fSGwendal Grignou out: 389caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 390caa8ce7fSGwendal Grignou 391caa8ce7fSGwendal Grignou iio_trigger_notify_done(indio_dev->trig); 392caa8ce7fSGwendal Grignou 393caa8ce7fSGwendal Grignou return IRQ_HANDLED; 394caa8ce7fSGwendal Grignou } 395caa8ce7fSGwendal Grignou 396caa8ce7fSGwendal Grignou static int sx_common_buffer_preenable(struct iio_dev *indio_dev) 397caa8ce7fSGwendal Grignou { 398caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 399caa8ce7fSGwendal Grignou unsigned long channels = 0; 400caa8ce7fSGwendal Grignou int bit, ret; 401caa8ce7fSGwendal Grignou 402caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 403caa8ce7fSGwendal Grignou for_each_set_bit(bit, indio_dev->active_scan_mask, 404caa8ce7fSGwendal Grignou indio_dev->masklength) 405caa8ce7fSGwendal Grignou __set_bit(indio_dev->channels[bit].channel, &channels); 406caa8ce7fSGwendal Grignou 407caa8ce7fSGwendal Grignou ret = sx_common_update_chan_en(data, channels, data->chan_event); 408caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 409caa8ce7fSGwendal Grignou return ret; 410caa8ce7fSGwendal Grignou } 411caa8ce7fSGwendal Grignou 412caa8ce7fSGwendal Grignou static int sx_common_buffer_postdisable(struct iio_dev *indio_dev) 413caa8ce7fSGwendal Grignou { 414caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 415caa8ce7fSGwendal Grignou int ret; 416caa8ce7fSGwendal Grignou 417caa8ce7fSGwendal Grignou mutex_lock(&data->mutex); 418caa8ce7fSGwendal Grignou ret = sx_common_update_chan_en(data, 0, data->chan_event); 419caa8ce7fSGwendal Grignou mutex_unlock(&data->mutex); 420caa8ce7fSGwendal Grignou return ret; 421caa8ce7fSGwendal Grignou } 422caa8ce7fSGwendal Grignou 423caa8ce7fSGwendal Grignou static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = { 424caa8ce7fSGwendal Grignou .preenable = sx_common_buffer_preenable, 425caa8ce7fSGwendal Grignou .postdisable = sx_common_buffer_postdisable, 426caa8ce7fSGwendal Grignou }; 427caa8ce7fSGwendal Grignou 428caa8ce7fSGwendal Grignou static void sx_common_regulator_disable(void *_data) 429caa8ce7fSGwendal Grignou { 430caa8ce7fSGwendal Grignou struct sx_common_data *data = _data; 431caa8ce7fSGwendal Grignou 432caa8ce7fSGwendal Grignou regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); 433caa8ce7fSGwendal Grignou } 434caa8ce7fSGwendal Grignou 435caa8ce7fSGwendal Grignou #define SX_COMMON_SOFT_RESET 0xde 436caa8ce7fSGwendal Grignou 437*7008f35cSAndy Shevchenko static int sx_common_init_device(struct device *dev, struct iio_dev *indio_dev) 438caa8ce7fSGwendal Grignou { 439caa8ce7fSGwendal Grignou struct sx_common_data *data = iio_priv(indio_dev); 440caa8ce7fSGwendal Grignou struct sx_common_reg_default tmp; 441caa8ce7fSGwendal Grignou const struct sx_common_reg_default *initval; 442caa8ce7fSGwendal Grignou int ret; 443caa8ce7fSGwendal Grignou unsigned int i, val; 444caa8ce7fSGwendal Grignou 445caa8ce7fSGwendal Grignou ret = regmap_write(data->regmap, data->chip_info->reg_reset, 446caa8ce7fSGwendal Grignou SX_COMMON_SOFT_RESET); 447caa8ce7fSGwendal Grignou if (ret) 448caa8ce7fSGwendal Grignou return ret; 449caa8ce7fSGwendal Grignou 450caa8ce7fSGwendal Grignou usleep_range(1000, 2000); /* power-up time is ~1ms. */ 451caa8ce7fSGwendal Grignou 452caa8ce7fSGwendal Grignou /* Clear reset interrupt state by reading SX_COMMON_REG_IRQ_SRC. */ 453caa8ce7fSGwendal Grignou ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val); 454caa8ce7fSGwendal Grignou if (ret) 455caa8ce7fSGwendal Grignou return ret; 456caa8ce7fSGwendal Grignou 457caa8ce7fSGwendal Grignou /* Program defaults from constant or BIOS. */ 458caa8ce7fSGwendal Grignou for (i = 0; i < data->chip_info->num_default_regs; i++) { 459*7008f35cSAndy Shevchenko initval = data->chip_info->ops.get_default_reg(dev, i, &tmp); 460caa8ce7fSGwendal Grignou ret = regmap_write(data->regmap, initval->reg, initval->def); 461caa8ce7fSGwendal Grignou if (ret) 462caa8ce7fSGwendal Grignou return ret; 463caa8ce7fSGwendal Grignou } 464caa8ce7fSGwendal Grignou 465caa8ce7fSGwendal Grignou return data->chip_info->ops.init_compensation(indio_dev); 466caa8ce7fSGwendal Grignou } 467caa8ce7fSGwendal Grignou 468caa8ce7fSGwendal Grignou /** 469caa8ce7fSGwendal Grignou * sx_common_probe() - Common setup for Semtech SAR sensor 470caa8ce7fSGwendal Grignou * @client: I2C client object 471caa8ce7fSGwendal Grignou * @chip_info: Semtech sensor chip information. 472caa8ce7fSGwendal Grignou * @regmap_config: Sensor registers map configuration. 473caa8ce7fSGwendal Grignou */ 474caa8ce7fSGwendal Grignou int sx_common_probe(struct i2c_client *client, 475caa8ce7fSGwendal Grignou const struct sx_common_chip_info *chip_info, 476caa8ce7fSGwendal Grignou const struct regmap_config *regmap_config) 477caa8ce7fSGwendal Grignou { 478caa8ce7fSGwendal Grignou struct device *dev = &client->dev; 479caa8ce7fSGwendal Grignou struct iio_dev *indio_dev; 480caa8ce7fSGwendal Grignou struct sx_common_data *data; 481caa8ce7fSGwendal Grignou int ret; 482caa8ce7fSGwendal Grignou 483caa8ce7fSGwendal Grignou indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 484caa8ce7fSGwendal Grignou if (!indio_dev) 485caa8ce7fSGwendal Grignou return -ENOMEM; 486caa8ce7fSGwendal Grignou 487caa8ce7fSGwendal Grignou data = iio_priv(indio_dev); 488caa8ce7fSGwendal Grignou 489caa8ce7fSGwendal Grignou data->chip_info = chip_info; 490caa8ce7fSGwendal Grignou data->client = client; 491caa8ce7fSGwendal Grignou data->supplies[0].supply = "vdd"; 492caa8ce7fSGwendal Grignou data->supplies[1].supply = "svdd"; 493caa8ce7fSGwendal Grignou mutex_init(&data->mutex); 494caa8ce7fSGwendal Grignou init_completion(&data->completion); 495caa8ce7fSGwendal Grignou 496caa8ce7fSGwendal Grignou data->regmap = devm_regmap_init_i2c(client, regmap_config); 497caa8ce7fSGwendal Grignou if (IS_ERR(data->regmap)) 498caa8ce7fSGwendal Grignou return dev_err_probe(dev, PTR_ERR(data->regmap), 499caa8ce7fSGwendal Grignou "Could init register map\n"); 500caa8ce7fSGwendal Grignou 501caa8ce7fSGwendal Grignou ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), 502caa8ce7fSGwendal Grignou data->supplies); 503caa8ce7fSGwendal Grignou if (ret) 504caa8ce7fSGwendal Grignou return dev_err_probe(dev, ret, "Unable to get regulators\n"); 505caa8ce7fSGwendal Grignou 506caa8ce7fSGwendal Grignou ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies); 507caa8ce7fSGwendal Grignou if (ret) 508caa8ce7fSGwendal Grignou return dev_err_probe(dev, ret, "Unable to enable regulators\n"); 509caa8ce7fSGwendal Grignou 510caa8ce7fSGwendal Grignou /* Must wait for Tpor time after initial power up */ 511caa8ce7fSGwendal Grignou usleep_range(1000, 1100); 512caa8ce7fSGwendal Grignou 513caa8ce7fSGwendal Grignou ret = devm_add_action_or_reset(dev, sx_common_regulator_disable, data); 514caa8ce7fSGwendal Grignou if (ret) 515caa8ce7fSGwendal Grignou return dev_err_probe(dev, ret, 516caa8ce7fSGwendal Grignou "Unable to register regulators deleter\n"); 517caa8ce7fSGwendal Grignou 518caa8ce7fSGwendal Grignou ret = data->chip_info->ops.check_whoami(dev, indio_dev); 519caa8ce7fSGwendal Grignou if (ret) 520caa8ce7fSGwendal Grignou return dev_err_probe(dev, ret, "error reading WHOAMI\n"); 521caa8ce7fSGwendal Grignou 522caa8ce7fSGwendal Grignou ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev)); 52374a53a95SStephen Boyd indio_dev->dev.of_node = client->dev.of_node; 524caa8ce7fSGwendal Grignou indio_dev->modes = INDIO_DIRECT_MODE; 525caa8ce7fSGwendal Grignou 526caa8ce7fSGwendal Grignou indio_dev->channels = data->chip_info->iio_channels; 527caa8ce7fSGwendal Grignou indio_dev->num_channels = data->chip_info->num_iio_channels; 528caa8ce7fSGwendal Grignou indio_dev->info = &data->chip_info->iio_info; 529caa8ce7fSGwendal Grignou 530caa8ce7fSGwendal Grignou i2c_set_clientdata(client, indio_dev); 531caa8ce7fSGwendal Grignou 532*7008f35cSAndy Shevchenko ret = sx_common_init_device(dev, indio_dev); 533caa8ce7fSGwendal Grignou if (ret) 534caa8ce7fSGwendal Grignou return dev_err_probe(dev, ret, "Unable to initialize sensor\n"); 535caa8ce7fSGwendal Grignou 536caa8ce7fSGwendal Grignou if (client->irq) { 537caa8ce7fSGwendal Grignou ret = devm_request_threaded_irq(dev, client->irq, 538caa8ce7fSGwendal Grignou sx_common_irq_handler, 539caa8ce7fSGwendal Grignou sx_common_irq_thread_handler, 540caa8ce7fSGwendal Grignou IRQF_ONESHOT, 541caa8ce7fSGwendal Grignou "sx_event", indio_dev); 542caa8ce7fSGwendal Grignou if (ret) 543caa8ce7fSGwendal Grignou return dev_err_probe(dev, ret, "No IRQ\n"); 544caa8ce7fSGwendal Grignou 545caa8ce7fSGwendal Grignou data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", 546caa8ce7fSGwendal Grignou indio_dev->name, 547caa8ce7fSGwendal Grignou iio_device_id(indio_dev)); 548caa8ce7fSGwendal Grignou if (!data->trig) 549caa8ce7fSGwendal Grignou return -ENOMEM; 550caa8ce7fSGwendal Grignou 551caa8ce7fSGwendal Grignou data->trig->ops = &sx_common_trigger_ops; 552caa8ce7fSGwendal Grignou iio_trigger_set_drvdata(data->trig, indio_dev); 553caa8ce7fSGwendal Grignou 554caa8ce7fSGwendal Grignou ret = devm_iio_trigger_register(dev, data->trig); 555caa8ce7fSGwendal Grignou if (ret) 556caa8ce7fSGwendal Grignou return ret; 557caa8ce7fSGwendal Grignou } 558caa8ce7fSGwendal Grignou 559caa8ce7fSGwendal Grignou ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 560caa8ce7fSGwendal Grignou iio_pollfunc_store_time, 561caa8ce7fSGwendal Grignou sx_common_trigger_handler, 562caa8ce7fSGwendal Grignou &sx_common_buffer_setup_ops); 563caa8ce7fSGwendal Grignou if (ret) 564caa8ce7fSGwendal Grignou return ret; 565caa8ce7fSGwendal Grignou 566caa8ce7fSGwendal Grignou return devm_iio_device_register(dev, indio_dev); 567caa8ce7fSGwendal Grignou } 568caa8ce7fSGwendal Grignou EXPORT_SYMBOL_NS_GPL(sx_common_probe, SEMTECH_PROX); 569caa8ce7fSGwendal Grignou 570caa8ce7fSGwendal Grignou MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>"); 571caa8ce7fSGwendal Grignou MODULE_DESCRIPTION("Common functions and structures for Semtech sensor"); 572caa8ce7fSGwendal Grignou MODULE_LICENSE("GPL v2"); 573