Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Ibrahim Tilki | 4802 | 99.32% | 2 | 33.33% |
Nuno Sá | 28 | 0.58% | 1 | 16.67% |
Andy Shevchenko | 3 | 0.06% | 1 | 16.67% |
Jonathan Cameron | 1 | 0.02% | 1 | 16.67% |
Mehdi Djait | 1 | 0.02% | 1 | 16.67% |
Total | 4835 | 6 |
// SPDX-License-Identifier: GPL-2.0-only /* * MAX11410 SPI ADC driver * * Copyright 2022 Analog Devices Inc. */ #include <linux/bitfield.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/err.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> #include <asm/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> #define MAX11410_REG_CONV_START 0x01 #define MAX11410_CONV_TYPE_SINGLE 0x00 #define MAX11410_CONV_TYPE_CONTINUOUS 0x01 #define MAX11410_REG_CAL_START 0x03 #define MAX11410_CAL_START_SELF 0x00 #define MAX11410_CAL_START_PGA 0x01 #define MAX11410_REG_GPIO_CTRL(ch) ((ch) ? 0x05 : 0x04) #define MAX11410_GPIO_INTRB 0xC1 #define MAX11410_REG_FILTER 0x08 #define MAX11410_FILTER_RATE_MASK GENMASK(3, 0) #define MAX11410_FILTER_RATE_MAX 0x0F #define MAX11410_FILTER_LINEF_MASK GENMASK(5, 4) #define MAX11410_FILTER_50HZ BIT(5) #define MAX11410_FILTER_60HZ BIT(4) #define MAX11410_REG_CTRL 0x09 #define MAX11410_CTRL_REFSEL_MASK GENMASK(2, 0) #define MAX11410_CTRL_VREFN_BUF_BIT BIT(3) #define MAX11410_CTRL_VREFP_BUF_BIT BIT(4) #define MAX11410_CTRL_FORMAT_BIT BIT(5) #define MAX11410_CTRL_UNIPOLAR_BIT BIT(6) #define MAX11410_REG_MUX_CTRL0 0x0B #define MAX11410_REG_PGA 0x0E #define MAX11410_PGA_GAIN_MASK GENMASK(2, 0) #define MAX11410_PGA_SIG_PATH_MASK GENMASK(5, 4) #define MAX11410_PGA_SIG_PATH_BUFFERED 0x00 #define MAX11410_PGA_SIG_PATH_BYPASS 0x01 #define MAX11410_PGA_SIG_PATH_PGA 0x02 #define MAX11410_REG_DATA0 0x30 #define MAX11410_REG_STATUS 0x38 #define MAX11410_STATUS_CONV_READY_BIT BIT(0) #define MAX11410_STATUS_CAL_READY_BIT BIT(2) #define MAX11410_REFSEL_AVDD_AGND 0x03 #define MAX11410_REFSEL_MAX 0x06 #define MAX11410_SIG_PATH_MAX 0x02 #define MAX11410_CHANNEL_INDEX_MAX 0x0A #define MAX11410_AINP_AVDD 0x0A #define MAX11410_AINN_GND 0x0A #define MAX11410_CONVERSION_TIMEOUT_MS 2000 #define MAX11410_CALIB_TIMEOUT_MS 2000 #define MAX11410_SCALE_AVAIL_SIZE 8 enum max11410_filter { MAX11410_FILTER_FIR5060, MAX11410_FILTER_FIR50, MAX11410_FILTER_FIR60, MAX11410_FILTER_SINC4, }; static const u8 max11410_sampling_len[] = { [MAX11410_FILTER_FIR5060] = 5, [MAX11410_FILTER_FIR50] = 6, [MAX11410_FILTER_FIR60] = 6, [MAX11410_FILTER_SINC4] = 10, }; static const int max11410_sampling_rates[4][10][2] = { [MAX11410_FILTER_FIR5060] = { { 1, 100000 }, { 2, 100000 }, { 4, 200000 }, { 8, 400000 }, { 16, 800000 } }, [MAX11410_FILTER_FIR50] = { { 1, 300000 }, { 2, 700000 }, { 5, 300000 }, { 10, 700000 }, { 21, 300000 }, { 40 } }, [MAX11410_FILTER_FIR60] = { { 1, 300000 }, { 2, 700000 }, { 5, 300000 }, { 10, 700000 }, { 21, 300000 }, { 40 } }, [MAX11410_FILTER_SINC4] = { { 4 }, { 10 }, { 20 }, { 40 }, { 60 }, { 120 }, { 240 }, { 480 }, { 960 }, { 1920 } } }; struct max11410_channel_config { u32 settling_time_us; u32 *scale_avail; u8 refsel; u8 sig_path; u8 gain; bool bipolar; bool buffered_vrefp; bool buffered_vrefn; }; struct max11410_state { struct spi_device *spi_dev; struct iio_trigger *trig; struct completion completion; struct mutex lock; /* Prevent changing channel config during sampling */ struct regmap *regmap; struct regulator *avdd; struct regulator *vrefp[3]; struct regulator *vrefn[3]; struct max11410_channel_config *channels; int irq; struct { u32 data __aligned(IIO_DMA_MINALIGN); s64 ts __aligned(8); } scan; }; static const struct iio_chan_spec chanspec_template = { .type = IIO_VOLTAGE, .indexed = 1, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_type = { .sign = 's', .realbits = 24, .storagebits = 32, .endianness = IIO_LE, }, }; static unsigned int max11410_reg_size(unsigned int reg) { /* Registers from 0x00 to 0x10 are 1 byte, the rest are 3 bytes long. */ return reg <= 0x10 ? 1 : 3; } static int max11410_write_reg(struct max11410_state *st, unsigned int reg, unsigned int val) { /* This driver only needs to write 8-bit registers */ if (max11410_reg_size(reg) != 1) return -EINVAL; return regmap_write(st->regmap, reg, val); } static int max11410_read_reg(struct max11410_state *st, unsigned int reg, int *val) { int ret; if (max11410_reg_size(reg) == 3) { ret = regmap_bulk_read(st->regmap, reg, &st->scan.data, 3); if (ret) return ret; *val = get_unaligned_be24(&st->scan.data); return 0; } return regmap_read(st->regmap, reg, val); } static struct regulator *max11410_get_vrefp(struct max11410_state *st, u8 refsel) { refsel = refsel % 4; if (refsel == 3) return st->avdd; return st->vrefp[refsel]; } static struct regulator *max11410_get_vrefn(struct max11410_state *st, u8 refsel) { if (refsel > 2) return NULL; return st->vrefn[refsel]; } static const struct regmap_config regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = 0x39, }; static ssize_t max11410_notch_en_show(struct device *dev, struct device_attribute *devattr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct max11410_state *state = iio_priv(indio_dev); struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); unsigned int val; int ret; ret = max11410_read_reg(state, MAX11410_REG_FILTER, &val); if (ret) return ret; switch (iio_attr->address) { case 0: val = !FIELD_GET(MAX11410_FILTER_50HZ, val); break; case 1: val = !FIELD_GET(MAX11410_FILTER_60HZ, val); break; case 2: val = FIELD_GET(MAX11410_FILTER_LINEF_MASK, val) == 3; break; default: return -EINVAL; } return sysfs_emit(buf, "%d\n", val); } static ssize_t max11410_notch_en_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); struct iio_dev *indio_dev = dev_get_drvdata(dev); struct max11410_state *state = iio_priv(indio_dev); unsigned int filter_bits; bool enable; int ret; ret = kstrtobool(buf, &enable); if (ret) return ret; switch (iio_attr->address) { case 0: filter_bits = MAX11410_FILTER_50HZ; break; case 1: filter_bits = MAX11410_FILTER_60HZ; break; case 2: default: filter_bits = MAX11410_FILTER_50HZ | MAX11410_FILTER_60HZ; enable = !enable; break; } if (enable) ret = regmap_clear_bits(state->regmap, MAX11410_REG_FILTER, filter_bits); else ret = regmap_set_bits(state->regmap, MAX11410_REG_FILTER, filter_bits); if (ret) return ret; return count; } static ssize_t in_voltage_filter2_notch_center_show(struct device *dev, struct device_attribute *devattr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct max11410_state *state = iio_priv(indio_dev); int ret, reg, rate, filter; ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®); if (ret) return ret; rate = FIELD_GET(MAX11410_FILTER_RATE_MASK, reg); rate = clamp_val(rate, 0, max11410_sampling_len[MAX11410_FILTER_SINC4] - 1); filter = max11410_sampling_rates[MAX11410_FILTER_SINC4][rate][0]; return sysfs_emit(buf, "%d\n", filter); } static IIO_CONST_ATTR(in_voltage_filter0_notch_center, "50"); static IIO_CONST_ATTR(in_voltage_filter1_notch_center, "60"); static IIO_DEVICE_ATTR_RO(in_voltage_filter2_notch_center, 2); static IIO_DEVICE_ATTR(in_voltage_filter0_notch_en, 0644, max11410_notch_en_show, max11410_notch_en_store, 0); static IIO_DEVICE_ATTR(in_voltage_filter1_notch_en, 0644, max11410_notch_en_show, max11410_notch_en_store, 1); static IIO_DEVICE_ATTR(in_voltage_filter2_notch_en, 0644, max11410_notch_en_show, max11410_notch_en_store, 2); static struct attribute *max11410_attributes[] = { &iio_const_attr_in_voltage_filter0_notch_center.dev_attr.attr, &iio_const_attr_in_voltage_filter1_notch_center.dev_attr.attr, &iio_dev_attr_in_voltage_filter2_notch_center.dev_attr.attr, &iio_dev_attr_in_voltage_filter0_notch_en.dev_attr.attr, &iio_dev_attr_in_voltage_filter1_notch_en.dev_attr.attr, &iio_dev_attr_in_voltage_filter2_notch_en.dev_attr.attr, NULL }; static const struct attribute_group max11410_attribute_group = { .attrs = max11410_attributes, }; static int max11410_set_input_mux(struct max11410_state *st, u8 ainp, u8 ainn) { if (ainp > MAX11410_CHANNEL_INDEX_MAX || ainn > MAX11410_CHANNEL_INDEX_MAX) return -EINVAL; return max11410_write_reg(st, MAX11410_REG_MUX_CTRL0, (ainp << 4) | ainn); } static int max11410_configure_channel(struct max11410_state *st, struct iio_chan_spec const *chan) { struct max11410_channel_config cfg = st->channels[chan->address]; unsigned int regval; int ret; if (chan->differential) ret = max11410_set_input_mux(st, chan->channel, chan->channel2); else ret = max11410_set_input_mux(st, chan->channel, MAX11410_AINN_GND); if (ret) return ret; regval = FIELD_PREP(MAX11410_CTRL_VREFP_BUF_BIT, cfg.buffered_vrefp) | FIELD_PREP(MAX11410_CTRL_VREFN_BUF_BIT, cfg.buffered_vrefn) | FIELD_PREP(MAX11410_CTRL_REFSEL_MASK, cfg.refsel) | FIELD_PREP(MAX11410_CTRL_UNIPOLAR_BIT, cfg.bipolar ? 0 : 1); ret = regmap_update_bits(st->regmap, MAX11410_REG_CTRL, MAX11410_CTRL_REFSEL_MASK | MAX11410_CTRL_VREFP_BUF_BIT | MAX11410_CTRL_VREFN_BUF_BIT | MAX11410_CTRL_UNIPOLAR_BIT, regval); if (ret) return ret; regval = FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, cfg.sig_path) | FIELD_PREP(MAX11410_PGA_GAIN_MASK, cfg.gain); ret = regmap_write(st->regmap, MAX11410_REG_PGA, regval); if (ret) return ret; if (cfg.settling_time_us) fsleep(cfg.settling_time_us); return 0; } static int max11410_sample(struct max11410_state *st, int *sample_raw, struct iio_chan_spec const *chan) { int val, ret; ret = max11410_configure_channel(st, chan); if (ret) return ret; if (st->irq > 0) reinit_completion(&st->completion); /* Start Conversion */ ret = max11410_write_reg(st, MAX11410_REG_CONV_START, MAX11410_CONV_TYPE_SINGLE); if (ret) return ret; if (st->irq > 0) { /* Wait for an interrupt. */ ret = wait_for_completion_timeout(&st->completion, msecs_to_jiffies(MAX11410_CONVERSION_TIMEOUT_MS)); if (!ret) return -ETIMEDOUT; } else { int ret2; /* Wait for status register Conversion Ready flag */ ret = read_poll_timeout(max11410_read_reg, ret2, ret2 || (val & MAX11410_STATUS_CONV_READY_BIT), 5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000, true, st, MAX11410_REG_STATUS, &val); if (ret) return ret; if (ret2) return ret2; } /* Read ADC Data */ return max11410_read_reg(st, MAX11410_REG_DATA0, sample_raw); } static int max11410_get_scale(struct max11410_state *state, struct max11410_channel_config cfg) { struct regulator *vrefp, *vrefn; int scale; vrefp = max11410_get_vrefp(state, cfg.refsel); scale = regulator_get_voltage(vrefp) / 1000; vrefn = max11410_get_vrefn(state, cfg.refsel); if (vrefn) scale -= regulator_get_voltage(vrefn) / 1000; if (cfg.bipolar) scale *= 2; return scale >> cfg.gain; } static int max11410_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long info) { struct max11410_state *state = iio_priv(indio_dev); struct max11410_channel_config cfg = state->channels[chan->address]; int ret, reg_val, filter, rate; switch (info) { case IIO_CHAN_INFO_SCALE: *val = max11410_get_scale(state, cfg); *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_OFFSET: if (cfg.bipolar) *val = -BIT(chan->scan_type.realbits - 1); else *val = 0; return IIO_VAL_INT; case IIO_CHAN_INFO_RAW: ret = iio_device_claim_direct_mode(indio_dev); if (ret) return ret; mutex_lock(&state->lock); ret = max11410_sample(state, ®_val, chan); mutex_unlock(&state->lock); iio_device_release_direct_mode(indio_dev); if (ret) return ret; *val = reg_val; return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®_val); if (ret) return ret; filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); rate = reg_val & MAX11410_FILTER_RATE_MASK; if (rate >= max11410_sampling_len[filter]) rate = max11410_sampling_len[filter] - 1; *val = max11410_sampling_rates[filter][rate][0]; *val2 = max11410_sampling_rates[filter][rate][1]; return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; } static int max11410_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { struct max11410_state *st = iio_priv(indio_dev); int i, ret, reg_val, filter, gain; u32 *scale_avail; switch (mask) { case IIO_CHAN_INFO_SCALE: scale_avail = st->channels[chan->address].scale_avail; if (!scale_avail) return -EOPNOTSUPP; /* Accept values in range 0.000001 <= scale < 1.000000 */ if (val != 0 || val2 == 0) return -EINVAL; ret = iio_device_claim_direct_mode(indio_dev); if (ret) return ret; /* Convert from INT_PLUS_MICRO to FRACTIONAL_LOG2 */ val2 = val2 * DIV_ROUND_CLOSEST(BIT(24), 1000000); val2 = DIV_ROUND_CLOSEST(scale_avail[0], val2); gain = order_base_2(val2); st->channels[chan->address].gain = clamp_val(gain, 0, 7); iio_device_release_direct_mode(indio_dev); return 0; case IIO_CHAN_INFO_SAMP_FREQ: ret = iio_device_claim_direct_mode(indio_dev); if (ret) return ret; mutex_lock(&st->lock); ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); if (ret) goto out; filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); for (i = 0; i < max11410_sampling_len[filter]; ++i) { if (val == max11410_sampling_rates[filter][i][0] && val2 == max11410_sampling_rates[filter][i][1]) break; } if (i == max11410_sampling_len[filter]) { ret = -EINVAL; goto out; } ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, MAX11410_FILTER_RATE_MASK, i); out: mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); return ret; default: return -EINVAL; } } static int max11410_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length, long info) { struct max11410_state *st = iio_priv(indio_dev); struct max11410_channel_config cfg; int ret, reg_val, filter; switch (info) { case IIO_CHAN_INFO_SAMP_FREQ: ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); if (ret) return ret; filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); *vals = (const int *)max11410_sampling_rates[filter]; *length = max11410_sampling_len[filter] * 2; *type = IIO_VAL_INT_PLUS_MICRO; return IIO_AVAIL_LIST; case IIO_CHAN_INFO_SCALE: cfg = st->channels[chan->address]; if (!cfg.scale_avail) return -EINVAL; *vals = cfg.scale_avail; *length = MAX11410_SCALE_AVAIL_SIZE * 2; *type = IIO_VAL_FRACTIONAL_LOG2; return IIO_AVAIL_LIST; } return -EINVAL; } static const struct iio_info max11410_info = { .read_raw = max11410_read_raw, .write_raw = max11410_write_raw, .read_avail = max11410_read_avail, .attrs = &max11410_attribute_group, }; static irqreturn_t max11410_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct max11410_state *st = iio_priv(indio_dev); int ret; ret = max11410_read_reg(st, MAX11410_REG_DATA0, &st->scan.data); if (ret) { dev_err(&indio_dev->dev, "cannot read data\n"); goto out; } iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, iio_get_time_ns(indio_dev)); out: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; } static int max11410_buffer_postenable(struct iio_dev *indio_dev) { struct max11410_state *st = iio_priv(indio_dev); int scan_ch, ret; scan_ch = ffs(*indio_dev->active_scan_mask) - 1; ret = max11410_configure_channel(st, &indio_dev->channels[scan_ch]); if (ret) return ret; /* Start continuous conversion. */ return max11410_write_reg(st, MAX11410_REG_CONV_START, MAX11410_CONV_TYPE_CONTINUOUS); } static int max11410_buffer_predisable(struct iio_dev *indio_dev) { struct max11410_state *st = iio_priv(indio_dev); /* Stop continuous conversion. */ return max11410_write_reg(st, MAX11410_REG_CONV_START, MAX11410_CONV_TYPE_SINGLE); } static const struct iio_buffer_setup_ops max11410_buffer_ops = { .postenable = &max11410_buffer_postenable, .predisable = &max11410_buffer_predisable, .validate_scan_mask = &iio_validate_scan_mask_onehot, }; static const struct iio_trigger_ops max11410_trigger_ops = { .validate_device = iio_trigger_validate_own_device, }; static irqreturn_t max11410_interrupt(int irq, void *dev_id) { struct iio_dev *indio_dev = dev_id; struct max11410_state *st = iio_priv(indio_dev); if (iio_buffer_enabled(indio_dev)) iio_trigger_poll_nested(st->trig); else complete(&st->completion); return IRQ_HANDLED; }; static int max11410_parse_channels(struct max11410_state *st, struct iio_dev *indio_dev) { struct iio_chan_spec chanspec = chanspec_template; struct device *dev = &st->spi_dev->dev; struct max11410_channel_config *cfg; struct iio_chan_spec *channels; u32 reference, sig_path; const char *node_name; u32 inputs[2], scale; unsigned int num_ch; int chan_idx = 0; int ret, i; num_ch = device_get_child_node_count(dev); if (num_ch == 0) return dev_err_probe(&indio_dev->dev, -ENODEV, "FW has no channels defined\n"); /* Reserve space for soft timestamp channel */ num_ch++; channels = devm_kcalloc(dev, num_ch, sizeof(*channels), GFP_KERNEL); if (!channels) return -ENOMEM; st->channels = devm_kcalloc(dev, num_ch, sizeof(*st->channels), GFP_KERNEL); if (!st->channels) return -ENOMEM; device_for_each_child_node_scoped(dev, child) { node_name = fwnode_get_name(child); if (fwnode_property_present(child, "diff-channels")) { ret = fwnode_property_read_u32_array(child, "diff-channels", inputs, ARRAY_SIZE(inputs)); chanspec.differential = 1; } else { ret = fwnode_property_read_u32(child, "reg", &inputs[0]); inputs[1] = 0; chanspec.differential = 0; } if (ret) return ret; if (inputs[0] > MAX11410_CHANNEL_INDEX_MAX || inputs[1] > MAX11410_CHANNEL_INDEX_MAX) return dev_err_probe(&indio_dev->dev, -EINVAL, "Invalid channel index for %s, should be less than %d\n", node_name, MAX11410_CHANNEL_INDEX_MAX + 1); cfg = &st->channels[chan_idx]; reference = MAX11410_REFSEL_AVDD_AGND; fwnode_property_read_u32(child, "adi,reference", &reference); if (reference > MAX11410_REFSEL_MAX) return dev_err_probe(&indio_dev->dev, -EINVAL, "Invalid adi,reference value for %s, should be less than %d.\n", node_name, MAX11410_REFSEL_MAX + 1); if (!max11410_get_vrefp(st, reference) || (!max11410_get_vrefn(st, reference) && reference <= 2)) return dev_err_probe(&indio_dev->dev, -EINVAL, "Invalid VREF configuration for %s, either specify corresponding VREF regulators or change adi,reference property.\n", node_name); sig_path = MAX11410_PGA_SIG_PATH_BUFFERED; fwnode_property_read_u32(child, "adi,input-mode", &sig_path); if (sig_path > MAX11410_SIG_PATH_MAX) return dev_err_probe(&indio_dev->dev, -EINVAL, "Invalid adi,input-mode value for %s, should be less than %d.\n", node_name, MAX11410_SIG_PATH_MAX + 1); fwnode_property_read_u32(child, "settling-time-us", &cfg->settling_time_us); cfg->bipolar = fwnode_property_read_bool(child, "bipolar"); cfg->buffered_vrefp = fwnode_property_read_bool(child, "adi,buffered-vrefp"); cfg->buffered_vrefn = fwnode_property_read_bool(child, "adi,buffered-vrefn"); cfg->refsel = reference; cfg->sig_path = sig_path; cfg->gain = 0; /* Enable scale_available property if input mode is PGA */ if (sig_path == MAX11410_PGA_SIG_PATH_PGA) { __set_bit(IIO_CHAN_INFO_SCALE, &chanspec.info_mask_separate_available); cfg->scale_avail = devm_kcalloc(dev, MAX11410_SCALE_AVAIL_SIZE * 2, sizeof(*cfg->scale_avail), GFP_KERNEL); if (!cfg->scale_avail) return -ENOMEM; scale = max11410_get_scale(st, *cfg); for (i = 0; i < MAX11410_SCALE_AVAIL_SIZE; i++) { cfg->scale_avail[2 * i] = scale >> i; cfg->scale_avail[2 * i + 1] = chanspec.scan_type.realbits; } } else { __clear_bit(IIO_CHAN_INFO_SCALE, &chanspec.info_mask_separate_available); } chanspec.address = chan_idx; chanspec.scan_index = chan_idx; chanspec.channel = inputs[0]; chanspec.channel2 = inputs[1]; channels[chan_idx] = chanspec; chan_idx++; } channels[chan_idx] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(chan_idx); indio_dev->num_channels = chan_idx + 1; indio_dev->channels = channels; return 0; } static void max11410_disable_reg(void *reg) { regulator_disable(reg); } static int max11410_init_vref(struct device *dev, struct regulator **vref, const char *id) { struct regulator *reg; int ret; reg = devm_regulator_get_optional(dev, id); if (PTR_ERR(reg) == -ENODEV) { *vref = NULL; return 0; } else if (IS_ERR(reg)) { return PTR_ERR(reg); } ret = regulator_enable(reg); if (ret) return dev_err_probe(dev, ret, "Failed to enable regulator %s\n", id); *vref = reg; return devm_add_action_or_reset(dev, max11410_disable_reg, reg); } static int max11410_calibrate(struct max11410_state *st, u32 cal_type) { int ret, ret2, val; ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type); if (ret) return ret; /* Wait for status register Calibration Ready flag */ ret = read_poll_timeout(max11410_read_reg, ret2, ret2 || (val & MAX11410_STATUS_CAL_READY_BIT), 50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true, st, MAX11410_REG_STATUS, &val); if (ret) return ret; return ret2; } static int max11410_self_calibrate(struct max11410_state *st) { int ret, i; ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, MAX11410_FILTER_RATE_MASK, FIELD_PREP(MAX11410_FILTER_RATE_MASK, MAX11410_FILTER_RATE_MAX)); if (ret) return ret; ret = max11410_calibrate(st, MAX11410_CAL_START_SELF); if (ret) return ret; ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, MAX11410_PGA_SIG_PATH_MASK, FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, MAX11410_PGA_SIG_PATH_PGA)); if (ret) return ret; /* PGA calibrations */ for (i = 1; i < 8; ++i) { ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, MAX11410_PGA_GAIN_MASK, i); if (ret) return ret; ret = max11410_calibrate(st, MAX11410_CAL_START_PGA); if (ret) return ret; } /* Cleanup */ ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, MAX11410_PGA_GAIN_MASK, 0); if (ret) return ret; ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, MAX11410_FILTER_RATE_MASK, 0); if (ret) return ret; return regmap_write_bits(st->regmap, MAX11410_REG_PGA, MAX11410_PGA_SIG_PATH_MASK, FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, MAX11410_PGA_SIG_PATH_BUFFERED)); } static int max11410_probe(struct spi_device *spi) { const char *vrefp_regs[] = { "vref0p", "vref1p", "vref2p" }; const char *vrefn_regs[] = { "vref0n", "vref1n", "vref2n" }; struct device *dev = &spi->dev; struct max11410_state *st; struct iio_dev *indio_dev; int ret, irqs[2]; int i; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); st->spi_dev = spi; init_completion(&st->completion); mutex_init(&st->lock); indio_dev->name = "max11410"; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &max11410_info; st->regmap = devm_regmap_init_spi(spi, ®map_config); if (IS_ERR(st->regmap)) return dev_err_probe(dev, PTR_ERR(st->regmap), "regmap initialization failed\n"); ret = max11410_init_vref(dev, &st->avdd, "avdd"); if (ret) return ret; for (i = 0; i < ARRAY_SIZE(vrefp_regs); i++) { ret = max11410_init_vref(dev, &st->vrefp[i], vrefp_regs[i]); if (ret) return ret; ret = max11410_init_vref(dev, &st->vrefn[i], vrefn_regs[i]); if (ret) return ret; } /* * Regulators must be configured before parsing channels for * validating "adi,reference" property of each channel. */ ret = max11410_parse_channels(st, indio_dev); if (ret) return ret; irqs[0] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio0"); irqs[1] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio1"); if (irqs[0] > 0) { st->irq = irqs[0]; ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(0), MAX11410_GPIO_INTRB); } else if (irqs[1] > 0) { st->irq = irqs[1]; ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(1), MAX11410_GPIO_INTRB); } else if (spi->irq > 0) { return dev_err_probe(dev, -ENODEV, "no interrupt name specified"); } if (ret) return ret; ret = regmap_set_bits(st->regmap, MAX11410_REG_CTRL, MAX11410_CTRL_FORMAT_BIT); if (ret) return ret; ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, &max11410_trigger_handler, &max11410_buffer_ops); if (ret) return ret; if (st->irq > 0) { st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); if (!st->trig) return -ENOMEM; st->trig->ops = &max11410_trigger_ops; ret = devm_iio_trigger_register(dev, st->trig); if (ret) return ret; ret = devm_request_threaded_irq(dev, st->irq, NULL, &max11410_interrupt, IRQF_ONESHOT, "max11410", indio_dev); if (ret) return ret; } ret = max11410_self_calibrate(st); if (ret) return dev_err_probe(dev, ret, "cannot perform device self calibration\n"); return devm_iio_device_register(dev, indio_dev); } static const struct of_device_id max11410_spi_of_id[] = { { .compatible = "adi,max11410" }, { } }; MODULE_DEVICE_TABLE(of, max11410_spi_of_id); static const struct spi_device_id max11410_id[] = { { "max11410" }, { } }; MODULE_DEVICE_TABLE(spi, max11410_id); static struct spi_driver max11410_driver = { .driver = { .name = "max11410", .of_match_table = max11410_spi_of_id, }, .probe = max11410_probe, .id_table = max11410_id, }; module_spi_driver(max11410_driver); MODULE_AUTHOR("David Jung <David.Jung@analog.com>"); MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>"); MODULE_DESCRIPTION("Analog Devices MAX11410 ADC"); MODULE_LICENSE("GPL");
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1