^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the Diolan DLN-2 USB-ADC adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2017 Jack Andersen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mfd/dln2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/kfifo_buf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define DLN2_ADC_MOD_NAME "dln2-adc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DLN2_ADC_ID 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DLN2_ADC_GET_CHANNEL_COUNT DLN2_CMD(0x01, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DLN2_ADC_ENABLE DLN2_CMD(0x02, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DLN2_ADC_DISABLE DLN2_CMD(0x03, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DLN2_ADC_CHANNEL_ENABLE DLN2_CMD(0x05, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DLN2_ADC_CHANNEL_DISABLE DLN2_CMD(0x06, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define DLN2_ADC_SET_RESOLUTION DLN2_CMD(0x08, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DLN2_ADC_CHANNEL_GET_VAL DLN2_CMD(0x0A, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DLN2_ADC_CHANNEL_GET_ALL_VAL DLN2_CMD(0x0B, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DLN2_ADC_CHANNEL_SET_CFG DLN2_CMD(0x0C, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DLN2_ADC_CHANNEL_GET_CFG DLN2_CMD(0x0D, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DLN2_ADC_CONDITION_MET_EV DLN2_CMD(0x10, DLN2_ADC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define DLN2_ADC_EVENT_NONE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DLN2_ADC_EVENT_BELOW 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DLN2_ADC_EVENT_LEVEL_ABOVE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DLN2_ADC_EVENT_OUTSIDE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DLN2_ADC_EVENT_INSIDE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DLN2_ADC_EVENT_ALWAYS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DLN2_ADC_MAX_CHANNELS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DLN2_ADC_DATA_BITS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Plays similar role to iio_demux_table in subsystem core; except allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * in a fixed 8-element array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct dln2_adc_demux_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct dln2_adc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct iio_chan_spec iio_channels[DLN2_ADC_MAX_CHANNELS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int port, trigger_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct iio_trigger *trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Cached sample period in milliseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int sample_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Demux table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned int demux_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct dln2_adc_demux_table demux[DLN2_ADC_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Precomputed timestamp padding offset and length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned int ts_pad_offset, ts_pad_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct dln2_adc_port_chan {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct dln2_adc_get_all_vals {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) __le16 channel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __le16 values[DLN2_ADC_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static void dln2_adc_add_demux(struct dln2_adc *dln2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned int in_loc, unsigned int out_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct dln2_adc_demux_table *p = dln2->demux_count ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) &dln2->demux[dln2->demux_count - 1] : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (p && p->from + p->length == in_loc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) p->to + p->length == out_loc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) p->length += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) } else if (dln2->demux_count < DLN2_ADC_MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) p = &dln2->demux[dln2->demux_count++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) p->from = in_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) p->to = out_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) p->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void dln2_adc_update_demux(struct dln2_adc *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int in_ind = -1, out_ind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned int in_loc = 0, out_loc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Clear out any old demux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) dln2->demux_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Optimize all 8-channels case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (indio_dev->masklength &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) (*indio_dev->active_scan_mask & 0xff) == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dln2_adc_add_demux(dln2, 0, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) dln2->ts_pad_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) dln2->ts_pad_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Build demux table from fixed 8-channels to active_scan_mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for_each_set_bit(out_ind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) indio_dev->active_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) indio_dev->masklength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Handle timestamp separately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (out_ind == DLN2_ADC_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) for (++in_ind; in_ind != out_ind; ++in_ind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) in_loc += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) dln2_adc_add_demux(dln2, in_loc, out_loc, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) out_loc += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) in_loc += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (indio_dev->scan_timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) dln2->ts_pad_offset = out_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dln2->ts_pad_length = ts_offset * sizeof(int64_t) - out_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dln2->ts_pad_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dln2->ts_pad_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int dln2_adc_get_chan_count(struct dln2_adc *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u8 port = dln2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u8 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int olen = sizeof(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ret = dln2_transfer(dln2->pdev, DLN2_ADC_GET_CHANNEL_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) &port, sizeof(port), &count, &olen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (olen < sizeof(count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int dln2_adc_set_port_resolution(struct dln2_adc *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct dln2_adc_port_chan port_chan = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .port = dln2->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .chan = DLN2_ADC_DATA_BITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ret = dln2_transfer_tx(dln2->pdev, DLN2_ADC_SET_RESOLUTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) &port_chan, sizeof(port_chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int dln2_adc_set_chan_enabled(struct dln2_adc *dln2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int channel, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct dln2_adc_port_chan port_chan = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .port = dln2->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .chan = channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u16 cmd = enable ? DLN2_ADC_CHANNEL_ENABLE : DLN2_ADC_CHANNEL_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = dln2_transfer_tx(dln2->pdev, cmd, &port_chan, sizeof(port_chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int dln2_adc_set_port_enabled(struct dln2_adc *dln2, bool enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u16 *conflict_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u8 port = dln2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __le16 conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int olen = sizeof(conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u16 cmd = enable ? DLN2_ADC_ENABLE : DLN2_ADC_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (conflict_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *conflict_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = dln2_transfer(dln2->pdev, cmd, &port, sizeof(port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) &conflict, &olen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev_dbg(&dln2->pdev->dev, "Problem in %s(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __func__, (int)enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (conflict_out && enable && olen >= sizeof(conflict))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *conflict_out = le16_to_cpu(conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (enable && olen < sizeof(conflict))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static int dln2_adc_set_chan_period(struct dln2_adc *dln2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned int channel, unsigned int period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct dln2_adc_port_chan port_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) __u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) __le16 period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) __le16 low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) __le16 high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } __packed set_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .port_chan.port = dln2->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .port_chan.chan = channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .type = period ? DLN2_ADC_EVENT_ALWAYS : DLN2_ADC_EVENT_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .period = cpu_to_le16(period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret = dln2_transfer_tx(dln2->pdev, DLN2_ADC_CHANNEL_SET_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) &set_cfg, sizeof(set_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u16 conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) __le16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int olen = sizeof(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct dln2_adc_port_chan port_chan = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .port = dln2->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .chan = channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = dln2_adc_set_chan_enabled(dln2, channel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (conflict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_err(&dln2->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) "ADC pins conflict with mask %04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) (int)conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto disable_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * Call GET_VAL twice due to initial zero-return immediately after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * enabling channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) for (i = 0; i < 2; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ret = dln2_transfer(dln2->pdev, DLN2_ADC_CHANNEL_GET_VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) &port_chan, sizeof(port_chan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) &value, &olen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto disable_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (olen < sizeof(value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) goto disable_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = le16_to_cpu(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) disable_port:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dln2_adc_set_port_enabled(dln2, false, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) disable_chan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) dln2_adc_set_chan_enabled(dln2, channel, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int dln2_adc_read_all(struct dln2_adc *dln2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct dln2_adc_get_all_vals *get_all_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) __u8 port = dln2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int olen = sizeof(*get_all_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = dln2_transfer(dln2->pdev, DLN2_ADC_CHANNEL_GET_ALL_VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) &port, sizeof(port), get_all_vals, &olen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (olen < sizeof(*get_all_vals))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int dln2_adc_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int *val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned int microhertz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mutex_lock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = dln2_adc_read(dln2, chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * Voltage reference is fixed at 3.3v
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * 3.3 / (1 << 10) * 1000000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *val2 = 3222656;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return IIO_VAL_INT_PLUS_NANO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (dln2->sample_period) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) microhertz = 1000000000 / dln2->sample_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) *val = microhertz / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *val2 = microhertz % 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *val2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static int dln2_adc_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned int microhertz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) microhertz = 1000000 * val + val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) mutex_lock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dln2->sample_period =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) microhertz ? 1000000000 / microhertz : UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (dln2->sample_period > 65535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dln2->sample_period = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) dev_warn(&dln2->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) "clamping period to 65535ms\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * The first requested channel is arbitrated as a shared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * trigger source, so only one event is registered with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * DLN. The event handler will then read all enabled channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * values using DLN2_ADC_CHANNEL_GET_ALL_VAL to maintain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * synchronization between ADC readings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (dln2->trigger_chan != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ret = dln2_adc_set_chan_period(dln2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dln2->trigger_chan, dln2->sample_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int dln2_update_scan_mode(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) const unsigned long *scan_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int chan_count = indio_dev->num_channels - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int ret, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mutex_lock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) for (i = 0; i < chan_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = dln2_adc_set_chan_enabled(dln2, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) test_bit(i, scan_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) for (j = 0; j < i; ++j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dln2_adc_set_chan_enabled(dln2, j, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dev_err(&dln2->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "Unable to enable ADC channel %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dln2_adc_update_demux(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #define DLN2_ADC_CHAN(lval, idx) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) lval.type = IIO_VOLTAGE; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) lval.channel = idx; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) lval.indexed = 1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) lval.info_mask_separate = BIT(IIO_CHAN_INFO_RAW); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) lval.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) BIT(IIO_CHAN_INFO_SAMP_FREQ); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) lval.scan_index = idx; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) lval.scan_type.sign = 'u'; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) lval.scan_type.realbits = DLN2_ADC_DATA_BITS; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) lval.scan_type.storagebits = 16; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) lval.scan_type.endianness = IIO_LE; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Assignment version of IIO_CHAN_SOFT_TIMESTAMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(lval, _si) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) lval.type = IIO_TIMESTAMP; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) lval.channel = -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) lval.scan_index = _si; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) lval.scan_type.sign = 's'; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) lval.scan_type.realbits = 64; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) lval.scan_type.storagebits = 64; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static const struct iio_info dln2_adc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .read_raw = dln2_adc_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .write_raw = dln2_adc_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .update_scan_mode = dln2_update_scan_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static irqreturn_t dln2_adc_trigger_h(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) __le16 values[DLN2_ADC_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int64_t timestamp_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) } data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct dln2_adc_get_all_vals dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) const struct dln2_adc_demux_table *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) mutex_lock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = dln2_adc_read_all(dln2, &dev_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Demux operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) for (i = 0; i < dln2->demux_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) t = &dln2->demux[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) memcpy((void *)data.values + t->to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) (void *)dev_data.values + t->from, t->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Zero padding space between values and timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (dln2->ts_pad_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) memset((void *)data.values + dln2->ts_pad_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 0, dln2->ts_pad_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) iio_push_to_buffers_with_timestamp(indio_dev, &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) u16 conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) unsigned int trigger_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) mutex_lock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* Enable ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (conflict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dev_err(&dln2->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) "ADC pins conflict with mask %04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) (int)conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* Assign trigger channel based on first enabled channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) trigger_chan = find_first_bit(indio_dev->active_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) indio_dev->masklength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (trigger_chan < DLN2_ADC_MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dln2->trigger_chan = trigger_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ret = dln2_adc_set_chan_period(dln2, dln2->trigger_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dln2->sample_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) dln2->trigger_chan = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int dln2_adc_triggered_buffer_predisable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) mutex_lock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* Disable trigger channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (dln2->trigger_chan != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dln2_adc_set_chan_period(dln2, dln2->trigger_chan, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dln2->trigger_chan = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* Disable ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ret = dln2_adc_set_port_enabled(dln2, false, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mutex_unlock(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static const struct iio_buffer_setup_ops dln2_adc_buffer_setup_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .postenable = dln2_adc_triggered_buffer_postenable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .predisable = dln2_adc_triggered_buffer_predisable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static void dln2_adc_event(struct platform_device *pdev, u16 echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) const void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct iio_dev *indio_dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct dln2_adc *dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Called via URB completion handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) iio_trigger_poll(dln2->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static int dln2_adc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct dln2_adc *dln2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int i, ret, chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) indio_dev = devm_iio_device_alloc(dev, sizeof(*dln2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!indio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) dev_err(dev, "failed allocating iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) dln2 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dln2->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) dln2->port = pdata->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dln2->trigger_chan = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) mutex_init(&dln2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) platform_set_drvdata(pdev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ret = dln2_adc_set_port_resolution(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev_err(dev, "failed to set ADC resolution to 10 bits\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) chans = dln2_adc_get_chan_count(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (chans < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dev_err(dev, "failed to get channel count: %d\n", chans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (chans > DLN2_ADC_MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) chans = DLN2_ADC_MAX_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev_warn(dev, "clamping channels to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) DLN2_ADC_MAX_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) for (i = 0; i < chans; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) DLN2_ADC_CHAN(dln2->iio_channels[i], i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(dln2->iio_channels[i], i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) indio_dev->name = DLN2_ADC_MOD_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) indio_dev->info = &dln2_adc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) indio_dev->channels = dln2->iio_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) indio_dev->num_channels = chans + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) indio_dev->setup_ops = &dln2_adc_buffer_setup_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dln2->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) indio_dev->name, indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (!dln2->trig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) dev_err(dev, "failed to allocate trigger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) iio_trigger_set_drvdata(dln2->trig, dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ret = devm_iio_trigger_register(dev, dln2->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dev_err(dev, "failed to register trigger: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) iio_trigger_set_immutable(indio_dev, dln2->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) dln2_adc_trigger_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) &dln2_adc_buffer_setup_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_err(dev, "failed to allocate triggered buffer: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ret = dln2_register_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dln2_adc_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev_err(dev, "failed to setup DLN2 periodic event: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dev_err(dev, "failed to register iio device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) goto unregister_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) unregister_event:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int dln2_adc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct iio_dev *indio_dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static struct platform_driver dln2_adc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) .driver.name = DLN2_ADC_MOD_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) .probe = dln2_adc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) .remove = dln2_adc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) module_platform_driver(dln2_adc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) MODULE_AUTHOR("Jack Andersen <jackoalan@gmail.com");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) MODULE_ALIAS("platform:dln2-adc");