^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * iio/adc/max9611.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Maxim max9611/max9612 high side current sense amplifier with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * 12-bit ADC interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2017 Jacopo Mondi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This driver supports input common-mode voltage, current-sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * amplifier with programmable gains and die temperature reading from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Maxim max9611/max9612.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Op-amp, analog comparator, and watchdog functionalities are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * supported by this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DRIVER_NAME "max9611"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* max9611 register addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MAX9611_REG_CSA_DATA 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MAX9611_REG_RS_DATA 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MAX9611_REG_TEMP_DATA 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MAX9611_REG_CTRL1 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MAX9611_REG_CTRL2 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* max9611 REG1 mux configuration options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MAX9611_MUX_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MAX9611_MUX_SENSE_1x 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MAX9611_MUX_SENSE_4x 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MAX9611_MUX_SENSE_8x 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MAX9611_INPUT_VOLT 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MAX9611_MUX_TEMP 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* max9611 voltage (both csa and input) helper macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MAX9611_VOLTAGE_SHIFT 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MAX9611_VOLTAGE_RAW(_r) ((_r) >> MAX9611_VOLTAGE_SHIFT)
^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) * max9611 current sense amplifier voltage output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * LSB and offset values depends on selected gain (1x, 4x, 8x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * GAIN LSB (nV) OFFSET (LSB steps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * 1x 107500 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * 4x 26880 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * 8x 13440 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * The complete formula to calculate current sense voltage is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * (((adc_read >> 4) - offset) / ((1 / LSB) * 10^-3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MAX9611_CSA_1X_LSB_nV 107500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MAX9611_CSA_4X_LSB_nV 26880
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MAX9611_CSA_8X_LSB_nV 13440
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MAX9611_CSA_1X_OFFS_RAW 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MAX9611_CSA_4X_OFFS_RAW 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MAX9611_CSA_8X_OFFS_RAW 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * max9611 common input mode (CIM): LSB is 14mV, with 14mV offset at 25 C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * The complete formula to calculate input common voltage is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * (((adc_read >> 4) * 1000) - offset) / (1 / 14 * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define MAX9611_CIM_LSB_mV 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define MAX9611_CIM_OFFSET_RAW 1
^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) * max9611 temperature reading: LSB is 480 milli degrees Celsius
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * The complete formula to calculate temperature is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * ((adc_read >> 7) * 1000) / (1 / 480 * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define MAX9611_TEMP_MAX_POS 0x7f80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define MAX9611_TEMP_MAX_NEG 0xff80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define MAX9611_TEMP_MIN_NEG 0xd980
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define MAX9611_TEMP_MASK GENMASK(15, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define MAX9611_TEMP_SHIFT 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define MAX9611_TEMP_RAW(_r) ((_r) >> MAX9611_TEMP_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define MAX9611_TEMP_SCALE_NUM 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define MAX9611_TEMP_SCALE_DIV 2083
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Conversion time is 2 ms (typically) at Ta=25 degreeC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * No maximum value is known, so play it safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define MAX9611_CONV_TIME_US_RANGE 3000, 3300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct max9611_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct i2c_client *i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned int shunt_resistor_uohm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) enum max9611_conf_ids {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) CONF_SENSE_1x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) CONF_SENSE_4x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) CONF_SENSE_8x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) CONF_IN_VOLT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) CONF_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * max9611_mux_conf - associate ADC mux configuration with register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * where data shall be read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static const unsigned int max9611_mux_conf[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) [CONF_SENSE_1x] = { MAX9611_MUX_SENSE_1x, MAX9611_REG_CSA_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) [CONF_SENSE_4x] = { MAX9611_MUX_SENSE_4x, MAX9611_REG_CSA_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) [CONF_SENSE_8x] = { MAX9611_MUX_SENSE_8x, MAX9611_REG_CSA_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) [CONF_IN_VOLT] = { MAX9611_INPUT_VOLT, MAX9611_REG_RS_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) [CONF_TEMP] = { MAX9611_MUX_TEMP, MAX9611_REG_TEMP_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) enum max9611_csa_gain {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) CSA_GAIN_1x = CONF_SENSE_1x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) CSA_GAIN_4x = CONF_SENSE_4x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) CSA_GAIN_8x = CONF_SENSE_8x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) enum max9611_csa_gain_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) CSA_GAIN_LSB_nV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) CSA_GAIN_OFFS_RAW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * max9611_csa_gain_conf - associate gain multiplier with LSB and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * offset values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Group together parameters associated with configurable gain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * on current sense amplifier path to ADC interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Current sense read routine adjusts gain until it gets a meaningful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * value; use this structure to retrieve the correct LSB and offset values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static const unsigned int max9611_gain_conf[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) [CSA_GAIN_1x] = { MAX9611_CSA_1X_LSB_nV, MAX9611_CSA_1X_OFFS_RAW, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) [CSA_GAIN_4x] = { MAX9611_CSA_4X_LSB_nV, MAX9611_CSA_4X_OFFS_RAW, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) [CSA_GAIN_8x] = { MAX9611_CSA_8X_LSB_nV, MAX9611_CSA_8X_OFFS_RAW, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum max9611_chan_addrs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) MAX9611_CHAN_VOLTAGE_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) MAX9611_CHAN_VOLTAGE_SENSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) MAX9611_CHAN_TEMPERATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) MAX9611_CHAN_CURRENT_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) MAX9611_CHAN_POWER_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static const struct iio_chan_spec max9611_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .type = IIO_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .address = MAX9611_CHAN_TEMPERATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .type = IIO_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .address = MAX9611_CHAN_VOLTAGE_SENSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .indexed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .channel = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .type = IIO_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) BIT(IIO_CHAN_INFO_SCALE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) BIT(IIO_CHAN_INFO_OFFSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .address = MAX9611_CHAN_VOLTAGE_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .indexed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .channel = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .type = IIO_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .address = MAX9611_CHAN_CURRENT_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .type = IIO_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .address = MAX9611_CHAN_POWER_LOAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * max9611_read_single() - read a single value from ADC interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Data registers are 16 bit long, spread between two 8 bit registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * with consecutive addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * Configure ADC mux first, then read register at address "reg_addr".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * The smbus_read_word routine asks for 16 bits and the ADC is kind enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * to return values from "reg_addr" and "reg_addr + 1" consecutively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Data are transmitted with big-endian ordering: MSB arrives first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @max9611: max9611 device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @selector: index for mux and register configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @raw_val: the value returned from ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int max9611_read_single(struct max9611_dev *max9611,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) enum max9611_conf_ids selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u16 *raw_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u8 mux_conf = max9611_mux_conf[selector][0] & MAX9611_MUX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u8 reg_addr = max9611_mux_conf[selector][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * Keep mutex lock held during read-write to avoid mux register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * (CTRL1) re-configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) mutex_lock(&max9611->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = i2c_smbus_write_byte_data(max9611->i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) MAX9611_REG_CTRL1, mux_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dev_err(max9611->dev, "i2c write byte failed: 0x%2x - 0x%2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) MAX9611_REG_CTRL1, mux_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mutex_unlock(&max9611->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* need a delay here to make register configuration stabilize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) usleep_range(MAX9611_CONV_TIME_US_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ret = i2c_smbus_read_word_swapped(max9611->i2c_client, reg_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dev_err(max9611->dev, "i2c read word from 0x%2x failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) reg_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_unlock(&max9611->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *raw_val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mutex_unlock(&max9611->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * max9611_read_csa_voltage() - read current sense amplifier output voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * Current sense amplifier output voltage is read through a configurable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * 1x, 4x or 8x gain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Start with plain 1x gain, and adjust gain control properly until a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * meaningful value is read from ADC output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @max9611: max9611 device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @adc_raw: raw value read from ADC output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * @csa_gain: gain configuration option selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int max9611_read_csa_voltage(struct max9611_dev *max9611,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u16 *adc_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) enum max9611_csa_gain *csa_gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) enum max9611_conf_ids gain_selectors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) CONF_SENSE_1x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) CONF_SENSE_4x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) CONF_SENSE_8x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) for (i = 0; i < ARRAY_SIZE(gain_selectors); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = max9611_read_single(max9611, gain_selectors[i], adc_raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (*adc_raw > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *csa_gain = (enum max9611_csa_gain)gain_selectors[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int max9611_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct max9611_dev *dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) enum max9611_csa_gain gain_selector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const unsigned int *csa_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u16 adc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (chan->address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case MAX9611_CHAN_TEMPERATURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = max9611_read_single(dev, CONF_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) &adc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *val = MAX9611_TEMP_RAW(adc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case MAX9611_CHAN_VOLTAGE_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = max9611_read_single(dev, CONF_IN_VOLT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) &adc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) *val = MAX9611_VOLTAGE_RAW(adc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* MAX9611_CHAN_VOLTAGE_INPUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *val = MAX9611_CIM_OFFSET_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) switch (chan->address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case MAX9611_CHAN_TEMPERATURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *val = MAX9611_TEMP_SCALE_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) *val2 = MAX9611_TEMP_SCALE_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case MAX9611_CHAN_VOLTAGE_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *val = MAX9611_CIM_LSB_mV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) switch (chan->address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case MAX9611_CHAN_VOLTAGE_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * processed (mV): (raw - offset) * LSB (nV) / 10^6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * Even if max9611 can output raw csa voltage readings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * use a produced value as scale depends on gain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = max9611_read_csa_voltage(dev, &adc_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) &gain_selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) csa_gain = max9611_gain_conf[gain_selector];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) adc_data -= csa_gain[CSA_GAIN_OFFS_RAW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *val = MAX9611_VOLTAGE_RAW(adc_data) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) csa_gain[CSA_GAIN_LSB_nV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *val2 = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case MAX9611_CHAN_CURRENT_LOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* processed (mA): Vcsa (nV) / Rshunt (uOhm) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret = max9611_read_csa_voltage(dev, &adc_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) &gain_selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) csa_gain = max9611_gain_conf[gain_selector];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) adc_data -= csa_gain[CSA_GAIN_OFFS_RAW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) *val = MAX9611_VOLTAGE_RAW(adc_data) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) csa_gain[CSA_GAIN_LSB_nV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *val2 = dev->shunt_resistor_uohm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case MAX9611_CHAN_POWER_LOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * processed (mW): Vin (mV) * Vcsa (uV) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * Rshunt (uOhm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = max9611_read_single(dev, CONF_IN_VOLT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) &adc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) adc_data -= MAX9611_CIM_OFFSET_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *val = MAX9611_VOLTAGE_RAW(adc_data) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) MAX9611_CIM_LSB_mV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = max9611_read_csa_voltage(dev, &adc_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) &gain_selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) csa_gain = max9611_gain_conf[gain_selector];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* divide by 10^3 here to avoid 32bit overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) adc_data -= csa_gain[CSA_GAIN_OFFS_RAW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) *val *= MAX9611_VOLTAGE_RAW(adc_data) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) csa_gain[CSA_GAIN_LSB_nV] / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *val2 = dev->shunt_resistor_uohm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return -EINVAL;
^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 ssize_t max9611_shunt_resistor_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct max9611_dev *max9611 = iio_priv(dev_to_iio_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) unsigned int i, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) i = max9611->shunt_resistor_uohm / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) r = max9611->shunt_resistor_uohm % 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return sprintf(buf, "%u.%06u\n", i, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static IIO_DEVICE_ATTR(in_power_shunt_resistor, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) max9611_shunt_resistor_show, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static IIO_DEVICE_ATTR(in_current_shunt_resistor, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) max9611_shunt_resistor_show, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static struct attribute *max9611_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) &iio_dev_attr_in_power_shunt_resistor.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) &iio_dev_attr_in_current_shunt_resistor.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static const struct attribute_group max9611_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .attrs = max9611_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static const struct iio_info indio_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .read_raw = max9611_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .attrs = &max9611_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int max9611_init(struct max9611_dev *max9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct i2c_client *client = max9611->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) u16 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) I2C_FUNC_SMBUS_WRITE_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) I2C_FUNC_SMBUS_READ_WORD_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_err(max9611->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) "I2c adapter does not support smbus write_byte or read_word functionalities: aborting probe.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* Make sure die temperature is in range to test communications. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ret = max9611_read_single(max9611, CONF_TEMP, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) regval &= MAX9611_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if ((regval > MAX9611_TEMP_MAX_POS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) regval < MAX9611_TEMP_MIN_NEG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) regval > MAX9611_TEMP_MAX_NEG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) dev_err(max9611->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) "Invalid value received from ADC 0x%4x: aborting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Mux shall be zeroed back before applying other configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = i2c_smbus_write_byte_data(max9611->i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) MAX9611_REG_CTRL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) dev_err(max9611->dev, "i2c write byte failed: 0x%2x - 0x%2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) MAX9611_REG_CTRL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ret = i2c_smbus_write_byte_data(max9611->i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) MAX9611_REG_CTRL2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dev_err(max9611->dev, "i2c write byte failed: 0x%2x - 0x%2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) MAX9611_REG_CTRL2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) usleep_range(MAX9611_CONV_TIME_US_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static const struct of_device_id max9611_of_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {.compatible = "maxim,max9611", .data = "max9611"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {.compatible = "maxim,max9612", .data = "max9612"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) MODULE_DEVICE_TABLE(of, max9611_of_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int max9611_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) const char * const shunt_res_prop = "shunt-resistor-micro-ohms";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) const struct device_node *of_node = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) const struct of_device_id *of_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) of_match_device(max9611_of_table, &client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct max9611_dev *max9611;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned int of_shunt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*max9611));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) max9611 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) max9611->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) max9611->i2c_client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) mutex_init(&max9611->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ret = of_property_read_u32(of_node, shunt_res_prop, &of_shunt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) "Missing %s property for %pOF node\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) shunt_res_prop, of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) max9611->shunt_resistor_uohm = of_shunt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = max9611_init(max9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) indio_dev->name = of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) indio_dev->info = &indio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) indio_dev->channels = max9611_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) indio_dev->num_channels = ARRAY_SIZE(max9611_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return devm_iio_device_register(&client->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static struct i2c_driver max9611_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .name = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .of_match_table = max9611_of_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .probe = max9611_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) module_i2c_driver(max9611_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) MODULE_AUTHOR("Jacopo Mondi <jacopo+renesas@jmondi.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) MODULE_DESCRIPTION("Maxim max9611/12 current sense amplifier with 12bit ADC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) MODULE_LICENSE("GPL v2");