// SPDX-License-Identifier: GPL-2.0 /* * iio/adc/max9611.c * * Maxim max9611/max9612 high side current sense amplifier with * 12-bit ADC interface. * * Copyright (C) 2017 Jacopo Mondi */ /* * This driver supports input common-mode voltage, current-sense * amplifier with programmable gains and die temperature reading from * Maxim max9611/max9612. * * Op-amp, analog comparator, and watchdog functionalities are not * supported by this driver. */ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/module.h> #include <linux/mod_devicetable.h> #include <linux/property.h> #define DRIVER_NAME … /* max9611 register addresses */ #define MAX9611_REG_CSA_DATA … #define MAX9611_REG_RS_DATA … #define MAX9611_REG_TEMP_DATA … #define MAX9611_REG_CTRL1 … #define MAX9611_REG_CTRL2 … /* max9611 REG1 mux configuration options */ #define MAX9611_MUX_MASK … #define MAX9611_MUX_SENSE_1x … #define MAX9611_MUX_SENSE_4x … #define MAX9611_MUX_SENSE_8x … #define MAX9611_INPUT_VOLT … #define MAX9611_MUX_TEMP … /* max9611 voltage (both csa and input) helper macros */ #define MAX9611_VOLTAGE_SHIFT … #define MAX9611_VOLTAGE_RAW(_r) … /* * max9611 current sense amplifier voltage output: * LSB and offset values depends on selected gain (1x, 4x, 8x) * * GAIN LSB (nV) OFFSET (LSB steps) * 1x 107500 1 * 4x 26880 1 * 8x 13440 3 * * The complete formula to calculate current sense voltage is: * (((adc_read >> 4) - offset) / ((1 / LSB) * 10^-3) */ #define MAX9611_CSA_1X_LSB_nV … #define MAX9611_CSA_4X_LSB_nV … #define MAX9611_CSA_8X_LSB_nV … #define MAX9611_CSA_1X_OFFS_RAW … #define MAX9611_CSA_4X_OFFS_RAW … #define MAX9611_CSA_8X_OFFS_RAW … /* * max9611 common input mode (CIM): LSB is 14mV, with 14mV offset at 25 C * * The complete formula to calculate input common voltage is: * (((adc_read >> 4) * 1000) - offset) / (1 / 14 * 1000) */ #define MAX9611_CIM_LSB_mV … #define MAX9611_CIM_OFFSET_RAW … /* * max9611 temperature reading: LSB is 480 milli degrees Celsius * * The complete formula to calculate temperature is: * ((adc_read >> 7) * 1000) / (1 / 480 * 1000) */ #define MAX9611_TEMP_MAX_POS … #define MAX9611_TEMP_MAX_NEG … #define MAX9611_TEMP_MIN_NEG … #define MAX9611_TEMP_MASK … #define MAX9611_TEMP_SHIFT … #define MAX9611_TEMP_RAW(_r) … #define MAX9611_TEMP_SCALE_NUM … #define MAX9611_TEMP_SCALE_DIV … /* * Conversion time is 2 ms (typically) at Ta=25 degreeC * No maximum value is known, so play it safe. */ #define MAX9611_CONV_TIME_US_RANGE … struct max9611_dev { … }; enum max9611_conf_ids { … }; /* * max9611_mux_conf - associate ADC mux configuration with register address * where data shall be read from */ static const unsigned int max9611_mux_conf[][2] = …; enum max9611_csa_gain { … }; enum max9611_csa_gain_params { … }; /* * max9611_csa_gain_conf - associate gain multiplier with LSB and * offset values. * * Group together parameters associated with configurable gain * on current sense amplifier path to ADC interface. * Current sense read routine adjusts gain until it gets a meaningful * value; use this structure to retrieve the correct LSB and offset values. */ static const unsigned int max9611_gain_conf[][2] = …; enum max9611_chan_addrs { … }; static const struct iio_chan_spec max9611_channels[] = …; /** * max9611_read_single() - read a single value from ADC interface * * Data registers are 16 bit long, spread between two 8 bit registers * with consecutive addresses. * Configure ADC mux first, then read register at address "reg_addr". * The smbus_read_word routine asks for 16 bits and the ADC is kind enough * to return values from "reg_addr" and "reg_addr + 1" consecutively. * Data are transmitted with big-endian ordering: MSB arrives first. * * @max9611: max9611 device * @selector: index for mux and register configuration * @raw_val: the value returned from ADC */ static int max9611_read_single(struct max9611_dev *max9611, enum max9611_conf_ids selector, u16 *raw_val) { … } /** * max9611_read_csa_voltage() - read current sense amplifier output voltage * * Current sense amplifier output voltage is read through a configurable * 1x, 4x or 8x gain. * Start with plain 1x gain, and adjust gain control properly until a * meaningful value is read from ADC output. * * @max9611: max9611 device * @adc_raw: raw value read from ADC output * @csa_gain: gain configuration option selector */ static int max9611_read_csa_voltage(struct max9611_dev *max9611, u16 *adc_raw, enum max9611_csa_gain *csa_gain) { … } static int max9611_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { … } static ssize_t max9611_shunt_resistor_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static IIO_DEVICE_ATTR(in_power_shunt_resistor, 0444, max9611_shunt_resistor_show, NULL, 0); static IIO_DEVICE_ATTR(in_current_shunt_resistor, 0444, max9611_shunt_resistor_show, NULL, 0); static struct attribute *max9611_attributes[] = …; static const struct attribute_group max9611_attribute_group = …; static const struct iio_info indio_info = …; static int max9611_init(struct max9611_dev *max9611) { … } static const struct of_device_id max9611_of_table[] = …; MODULE_DEVICE_TABLE(of, max9611_of_table); static int max9611_probe(struct i2c_client *client) { … } static struct i2c_driver max9611_driver = …; module_i2c_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;