Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * iio/adc/max9611.c
0004  *
0005  * Maxim max9611/max9612 high side current sense amplifier with
0006  * 12-bit ADC interface.
0007  *
0008  * Copyright (C) 2017 Jacopo Mondi
0009  */
0010 
0011 /*
0012  * This driver supports input common-mode voltage, current-sense
0013  * amplifier with programmable gains and die temperature reading from
0014  * Maxim max9611/max9612.
0015  *
0016  * Op-amp, analog comparator, and watchdog functionalities are not
0017  * supported by this driver.
0018  */
0019 
0020 #include <linux/delay.h>
0021 #include <linux/i2c.h>
0022 #include <linux/iio/iio.h>
0023 #include <linux/iio/sysfs.h>
0024 #include <linux/module.h>
0025 #include <linux/mod_devicetable.h>
0026 #include <linux/property.h>
0027 
0028 #define DRIVER_NAME         "max9611"
0029 
0030 /* max9611 register addresses */
0031 #define MAX9611_REG_CSA_DATA        0x00
0032 #define MAX9611_REG_RS_DATA     0x02
0033 #define MAX9611_REG_TEMP_DATA       0x08
0034 #define MAX9611_REG_CTRL1       0x0a
0035 #define MAX9611_REG_CTRL2       0x0b
0036 
0037 /* max9611 REG1 mux configuration options */
0038 #define MAX9611_MUX_MASK        GENMASK(3, 0)
0039 #define MAX9611_MUX_SENSE_1x        0x00
0040 #define MAX9611_MUX_SENSE_4x        0x01
0041 #define MAX9611_MUX_SENSE_8x        0x02
0042 #define MAX9611_INPUT_VOLT      0x03
0043 #define MAX9611_MUX_TEMP        0x06
0044 
0045 /* max9611 voltage (both csa and input) helper macros */
0046 #define MAX9611_VOLTAGE_SHIFT       0x04
0047 #define MAX9611_VOLTAGE_RAW(_r)     ((_r) >> MAX9611_VOLTAGE_SHIFT)
0048 
0049 /*
0050  * max9611 current sense amplifier voltage output:
0051  * LSB and offset values depends on selected gain (1x, 4x, 8x)
0052  *
0053  * GAIN     LSB (nV)    OFFSET (LSB steps)
0054  * 1x       107500      1
0055  * 4x       26880       1
0056  * 8x       13440       3
0057  *
0058  * The complete formula to calculate current sense voltage is:
0059  *     (((adc_read >> 4) - offset) / ((1 / LSB) * 10^-3)
0060  */
0061 #define MAX9611_CSA_1X_LSB_nV       107500
0062 #define MAX9611_CSA_4X_LSB_nV       26880
0063 #define MAX9611_CSA_8X_LSB_nV       13440
0064 
0065 #define MAX9611_CSA_1X_OFFS_RAW     1
0066 #define MAX9611_CSA_4X_OFFS_RAW     1
0067 #define MAX9611_CSA_8X_OFFS_RAW     3
0068 
0069 /*
0070  * max9611 common input mode (CIM): LSB is 14mV, with 14mV offset at 25 C
0071  *
0072  * The complete formula to calculate input common voltage is:
0073  *     (((adc_read >> 4) * 1000) - offset) / (1 / 14 * 1000)
0074  */
0075 #define MAX9611_CIM_LSB_mV      14
0076 #define MAX9611_CIM_OFFSET_RAW      1
0077 
0078 /*
0079  * max9611 temperature reading: LSB is 480 milli degrees Celsius
0080  *
0081  * The complete formula to calculate temperature is:
0082  *     ((adc_read >> 7) * 1000) / (1 / 480 * 1000)
0083  */
0084 #define MAX9611_TEMP_MAX_POS        0x7f80
0085 #define MAX9611_TEMP_MAX_NEG        0xff80
0086 #define MAX9611_TEMP_MIN_NEG        0xd980
0087 #define MAX9611_TEMP_MASK       GENMASK(15, 7)
0088 #define MAX9611_TEMP_SHIFT      0x07
0089 #define MAX9611_TEMP_RAW(_r)        ((_r) >> MAX9611_TEMP_SHIFT)
0090 #define MAX9611_TEMP_SCALE_NUM      1000000
0091 #define MAX9611_TEMP_SCALE_DIV      2083
0092 
0093 /*
0094  * Conversion time is 2 ms (typically) at Ta=25 degreeC
0095  * No maximum value is known, so play it safe.
0096  */
0097 #define MAX9611_CONV_TIME_US_RANGE  3000, 3300
0098 
0099 struct max9611_dev {
0100     struct device *dev;
0101     struct i2c_client *i2c_client;
0102     struct mutex lock;
0103     unsigned int shunt_resistor_uohm;
0104 };
0105 
0106 enum max9611_conf_ids {
0107     CONF_SENSE_1x,
0108     CONF_SENSE_4x,
0109     CONF_SENSE_8x,
0110     CONF_IN_VOLT,
0111     CONF_TEMP,
0112 };
0113 
0114 /*
0115  * max9611_mux_conf - associate ADC mux configuration with register address
0116  *            where data shall be read from
0117  */
0118 static const unsigned int max9611_mux_conf[][2] = {
0119     [CONF_SENSE_1x] = { MAX9611_MUX_SENSE_1x, MAX9611_REG_CSA_DATA },
0120     [CONF_SENSE_4x] = { MAX9611_MUX_SENSE_4x, MAX9611_REG_CSA_DATA },
0121     [CONF_SENSE_8x] = { MAX9611_MUX_SENSE_8x, MAX9611_REG_CSA_DATA },
0122     [CONF_IN_VOLT]  = { MAX9611_INPUT_VOLT, MAX9611_REG_RS_DATA },
0123     [CONF_TEMP] = { MAX9611_MUX_TEMP, MAX9611_REG_TEMP_DATA },
0124 };
0125 
0126 enum max9611_csa_gain {
0127     CSA_GAIN_1x = CONF_SENSE_1x,
0128     CSA_GAIN_4x = CONF_SENSE_4x,
0129     CSA_GAIN_8x = CONF_SENSE_8x,
0130 };
0131 
0132 enum max9611_csa_gain_params {
0133     CSA_GAIN_LSB_nV,
0134     CSA_GAIN_OFFS_RAW,
0135 };
0136 
0137 /*
0138  * max9611_csa_gain_conf - associate gain multiplier with LSB and
0139  *             offset values.
0140  *
0141  * Group together parameters associated with configurable gain
0142  * on current sense amplifier path to ADC interface.
0143  * Current sense read routine adjusts gain until it gets a meaningful
0144  * value; use this structure to retrieve the correct LSB and offset values.
0145  */
0146 static const unsigned int max9611_gain_conf[][2] = {
0147     [CSA_GAIN_1x] = { MAX9611_CSA_1X_LSB_nV, MAX9611_CSA_1X_OFFS_RAW, },
0148     [CSA_GAIN_4x] = { MAX9611_CSA_4X_LSB_nV, MAX9611_CSA_4X_OFFS_RAW, },
0149     [CSA_GAIN_8x] = { MAX9611_CSA_8X_LSB_nV, MAX9611_CSA_8X_OFFS_RAW, },
0150 };
0151 
0152 enum max9611_chan_addrs {
0153     MAX9611_CHAN_VOLTAGE_INPUT,
0154     MAX9611_CHAN_VOLTAGE_SENSE,
0155     MAX9611_CHAN_TEMPERATURE,
0156     MAX9611_CHAN_CURRENT_LOAD,
0157     MAX9611_CHAN_POWER_LOAD,
0158 };
0159 
0160 static const struct iio_chan_spec max9611_channels[] = {
0161     {
0162       .type         = IIO_TEMP,
0163       .info_mask_separate   = BIT(IIO_CHAN_INFO_RAW) |
0164                   BIT(IIO_CHAN_INFO_SCALE),
0165       .address      = MAX9611_CHAN_TEMPERATURE,
0166     },
0167     {
0168       .type         = IIO_VOLTAGE,
0169       .info_mask_separate   = BIT(IIO_CHAN_INFO_PROCESSED),
0170       .address      = MAX9611_CHAN_VOLTAGE_SENSE,
0171       .indexed      = 1,
0172       .channel      = 0,
0173     },
0174     {
0175       .type         = IIO_VOLTAGE,
0176       .info_mask_separate   = BIT(IIO_CHAN_INFO_RAW)   |
0177                   BIT(IIO_CHAN_INFO_SCALE) |
0178                   BIT(IIO_CHAN_INFO_OFFSET),
0179       .address      = MAX9611_CHAN_VOLTAGE_INPUT,
0180       .indexed      = 1,
0181       .channel      = 1,
0182     },
0183     {
0184       .type         = IIO_CURRENT,
0185       .info_mask_separate   = BIT(IIO_CHAN_INFO_PROCESSED),
0186       .address      = MAX9611_CHAN_CURRENT_LOAD,
0187     },
0188     {
0189       .type         = IIO_POWER,
0190       .info_mask_separate   = BIT(IIO_CHAN_INFO_PROCESSED),
0191       .address      = MAX9611_CHAN_POWER_LOAD
0192     },
0193 };
0194 
0195 /**
0196  * max9611_read_single() - read a single value from ADC interface
0197  *
0198  * Data registers are 16 bit long, spread between two 8 bit registers
0199  * with consecutive addresses.
0200  * Configure ADC mux first, then read register at address "reg_addr".
0201  * The smbus_read_word routine asks for 16 bits and the ADC is kind enough
0202  * to return values from "reg_addr" and "reg_addr + 1" consecutively.
0203  * Data are transmitted with big-endian ordering: MSB arrives first.
0204  *
0205  * @max9611: max9611 device
0206  * @selector: index for mux and register configuration
0207  * @raw_val: the value returned from ADC
0208  */
0209 static int max9611_read_single(struct max9611_dev *max9611,
0210                    enum max9611_conf_ids selector,
0211                    u16 *raw_val)
0212 {
0213     int ret;
0214 
0215     u8 mux_conf = max9611_mux_conf[selector][0] & MAX9611_MUX_MASK;
0216     u8 reg_addr = max9611_mux_conf[selector][1];
0217 
0218     /*
0219      * Keep mutex lock held during read-write to avoid mux register
0220      * (CTRL1) re-configuration.
0221      */
0222     mutex_lock(&max9611->lock);
0223     ret = i2c_smbus_write_byte_data(max9611->i2c_client,
0224                     MAX9611_REG_CTRL1, mux_conf);
0225     if (ret) {
0226         dev_err(max9611->dev, "i2c write byte failed: 0x%2x - 0x%2x\n",
0227             MAX9611_REG_CTRL1, mux_conf);
0228         mutex_unlock(&max9611->lock);
0229         return ret;
0230     }
0231 
0232     /* need a delay here to make register configuration stabilize. */
0233 
0234     usleep_range(MAX9611_CONV_TIME_US_RANGE);
0235 
0236     ret = i2c_smbus_read_word_swapped(max9611->i2c_client, reg_addr);
0237     if (ret < 0) {
0238         dev_err(max9611->dev, "i2c read word from 0x%2x failed\n",
0239             reg_addr);
0240         mutex_unlock(&max9611->lock);
0241         return ret;
0242     }
0243 
0244     *raw_val = ret;
0245     mutex_unlock(&max9611->lock);
0246 
0247     return 0;
0248 }
0249 
0250 /**
0251  * max9611_read_csa_voltage() - read current sense amplifier output voltage
0252  *
0253  * Current sense amplifier output voltage is read through a configurable
0254  * 1x, 4x or 8x gain.
0255  * Start with plain 1x gain, and adjust gain control properly until a
0256  * meaningful value is read from ADC output.
0257  *
0258  * @max9611: max9611 device
0259  * @adc_raw: raw value read from ADC output
0260  * @csa_gain: gain configuration option selector
0261  */
0262 static int max9611_read_csa_voltage(struct max9611_dev *max9611,
0263                     u16 *adc_raw,
0264                     enum max9611_csa_gain *csa_gain)
0265 {
0266     enum max9611_conf_ids gain_selectors[] = {
0267         CONF_SENSE_1x,
0268         CONF_SENSE_4x,
0269         CONF_SENSE_8x
0270     };
0271     unsigned int i;
0272     int ret;
0273 
0274     for (i = 0; i < ARRAY_SIZE(gain_selectors); ++i) {
0275         ret = max9611_read_single(max9611, gain_selectors[i], adc_raw);
0276         if (ret)
0277             return ret;
0278 
0279         if (*adc_raw > 0) {
0280             *csa_gain = (enum max9611_csa_gain)gain_selectors[i];
0281             return 0;
0282         }
0283     }
0284 
0285     return -EIO;
0286 }
0287 
0288 static int max9611_read_raw(struct iio_dev *indio_dev,
0289                 struct iio_chan_spec const *chan,
0290                 int *val, int *val2, long mask)
0291 {
0292     struct max9611_dev *dev = iio_priv(indio_dev);
0293     enum max9611_csa_gain gain_selector;
0294     const unsigned int *csa_gain;
0295     u16 adc_data;
0296     int ret;
0297 
0298     switch (mask) {
0299     case IIO_CHAN_INFO_RAW:
0300 
0301         switch (chan->address) {
0302         case MAX9611_CHAN_TEMPERATURE:
0303             ret = max9611_read_single(dev, CONF_TEMP,
0304                           &adc_data);
0305             if (ret)
0306                 return -EINVAL;
0307 
0308             *val = MAX9611_TEMP_RAW(adc_data);
0309             return IIO_VAL_INT;
0310 
0311         case MAX9611_CHAN_VOLTAGE_INPUT:
0312             ret = max9611_read_single(dev, CONF_IN_VOLT,
0313                           &adc_data);
0314             if (ret)
0315                 return -EINVAL;
0316 
0317             *val = MAX9611_VOLTAGE_RAW(adc_data);
0318             return IIO_VAL_INT;
0319         }
0320 
0321         break;
0322 
0323     case IIO_CHAN_INFO_OFFSET:
0324         /* MAX9611_CHAN_VOLTAGE_INPUT */
0325         *val = MAX9611_CIM_OFFSET_RAW;
0326 
0327         return IIO_VAL_INT;
0328 
0329     case IIO_CHAN_INFO_SCALE:
0330 
0331         switch (chan->address) {
0332         case MAX9611_CHAN_TEMPERATURE:
0333             *val = MAX9611_TEMP_SCALE_NUM;
0334             *val2 = MAX9611_TEMP_SCALE_DIV;
0335 
0336             return IIO_VAL_FRACTIONAL;
0337 
0338         case MAX9611_CHAN_VOLTAGE_INPUT:
0339             *val = MAX9611_CIM_LSB_mV;
0340 
0341             return IIO_VAL_INT;
0342         }
0343 
0344         break;
0345 
0346     case IIO_CHAN_INFO_PROCESSED:
0347 
0348         switch (chan->address) {
0349         case MAX9611_CHAN_VOLTAGE_SENSE:
0350             /*
0351              * processed (mV): (raw - offset) * LSB (nV) / 10^6
0352              *
0353              * Even if max9611 can output raw csa voltage readings,
0354              * use a produced value as scale depends on gain.
0355              */
0356             ret = max9611_read_csa_voltage(dev, &adc_data,
0357                                &gain_selector);
0358             if (ret)
0359                 return -EINVAL;
0360 
0361             csa_gain = max9611_gain_conf[gain_selector];
0362 
0363             adc_data -= csa_gain[CSA_GAIN_OFFS_RAW];
0364             *val = MAX9611_VOLTAGE_RAW(adc_data) *
0365                    csa_gain[CSA_GAIN_LSB_nV];
0366             *val2 = 1000000;
0367 
0368             return IIO_VAL_FRACTIONAL;
0369 
0370         case MAX9611_CHAN_CURRENT_LOAD:
0371             /* processed (mA): Vcsa (nV) / Rshunt (uOhm)  */
0372             ret = max9611_read_csa_voltage(dev, &adc_data,
0373                                &gain_selector);
0374             if (ret)
0375                 return -EINVAL;
0376 
0377             csa_gain = max9611_gain_conf[gain_selector];
0378 
0379             adc_data -= csa_gain[CSA_GAIN_OFFS_RAW];
0380             *val = MAX9611_VOLTAGE_RAW(adc_data) *
0381                    csa_gain[CSA_GAIN_LSB_nV];
0382             *val2 = dev->shunt_resistor_uohm;
0383 
0384             return IIO_VAL_FRACTIONAL;
0385 
0386         case MAX9611_CHAN_POWER_LOAD:
0387             /*
0388              * processed (mW): Vin (mV) * Vcsa (uV) /
0389              *         Rshunt (uOhm)
0390              */
0391             ret = max9611_read_single(dev, CONF_IN_VOLT,
0392                           &adc_data);
0393             if (ret)
0394                 return -EINVAL;
0395 
0396             adc_data -= MAX9611_CIM_OFFSET_RAW;
0397             *val = MAX9611_VOLTAGE_RAW(adc_data) *
0398                    MAX9611_CIM_LSB_mV;
0399 
0400             ret = max9611_read_csa_voltage(dev, &adc_data,
0401                                &gain_selector);
0402             if (ret)
0403                 return -EINVAL;
0404 
0405             csa_gain = max9611_gain_conf[gain_selector];
0406 
0407             /* divide by 10^3 here to avoid 32bit overflow */
0408             adc_data -= csa_gain[CSA_GAIN_OFFS_RAW];
0409             *val *= MAX9611_VOLTAGE_RAW(adc_data) *
0410                 csa_gain[CSA_GAIN_LSB_nV] / 1000;
0411             *val2 = dev->shunt_resistor_uohm;
0412 
0413             return IIO_VAL_FRACTIONAL;
0414         }
0415 
0416         break;
0417     }
0418 
0419     return -EINVAL;
0420 }
0421 
0422 static ssize_t max9611_shunt_resistor_show(struct device *dev,
0423                        struct device_attribute *attr,
0424                        char *buf)
0425 {
0426     struct max9611_dev *max9611 = iio_priv(dev_to_iio_dev(dev));
0427     unsigned int i, r;
0428 
0429     i = max9611->shunt_resistor_uohm / 1000000;
0430     r = max9611->shunt_resistor_uohm % 1000000;
0431 
0432     return sysfs_emit(buf, "%u.%06u\n", i, r);
0433 }
0434 
0435 static IIO_DEVICE_ATTR(in_power_shunt_resistor, 0444,
0436                max9611_shunt_resistor_show, NULL, 0);
0437 static IIO_DEVICE_ATTR(in_current_shunt_resistor, 0444,
0438                max9611_shunt_resistor_show, NULL, 0);
0439 
0440 static struct attribute *max9611_attributes[] = {
0441     &iio_dev_attr_in_power_shunt_resistor.dev_attr.attr,
0442     &iio_dev_attr_in_current_shunt_resistor.dev_attr.attr,
0443     NULL,
0444 };
0445 
0446 static const struct attribute_group max9611_attribute_group = {
0447     .attrs = max9611_attributes,
0448 };
0449 
0450 static const struct iio_info indio_info = {
0451     .read_raw   = max9611_read_raw,
0452     .attrs      = &max9611_attribute_group,
0453 };
0454 
0455 static int max9611_init(struct max9611_dev *max9611)
0456 {
0457     struct i2c_client *client = max9611->i2c_client;
0458     u16 regval;
0459     int ret;
0460 
0461     if (!i2c_check_functionality(client->adapter,
0462                      I2C_FUNC_SMBUS_WRITE_BYTE  |
0463                      I2C_FUNC_SMBUS_READ_WORD_DATA)) {
0464         dev_err(max9611->dev,
0465             "I2c adapter does not support smbus write_byte or read_word functionalities: aborting probe.\n");
0466         return -EINVAL;
0467     }
0468 
0469     /* Make sure die temperature is in range to test communications. */
0470     ret = max9611_read_single(max9611, CONF_TEMP, &regval);
0471     if (ret)
0472         return ret;
0473 
0474     regval &= MAX9611_TEMP_MASK;
0475 
0476     if ((regval > MAX9611_TEMP_MAX_POS &&
0477          regval < MAX9611_TEMP_MIN_NEG) ||
0478          regval > MAX9611_TEMP_MAX_NEG) {
0479         dev_err(max9611->dev,
0480             "Invalid value received from ADC 0x%4x: aborting\n",
0481             regval);
0482         return -EIO;
0483     }
0484 
0485     /* Mux shall be zeroed back before applying other configurations */
0486     ret = i2c_smbus_write_byte_data(max9611->i2c_client,
0487                     MAX9611_REG_CTRL1, 0);
0488     if (ret) {
0489         dev_err(max9611->dev, "i2c write byte failed: 0x%2x - 0x%2x\n",
0490             MAX9611_REG_CTRL1, 0);
0491         return ret;
0492     }
0493 
0494     ret = i2c_smbus_write_byte_data(max9611->i2c_client,
0495                     MAX9611_REG_CTRL2, 0);
0496     if (ret) {
0497         dev_err(max9611->dev, "i2c write byte failed: 0x%2x - 0x%2x\n",
0498             MAX9611_REG_CTRL2, 0);
0499         return ret;
0500     }
0501     usleep_range(MAX9611_CONV_TIME_US_RANGE);
0502 
0503     return 0;
0504 }
0505 
0506 static const struct of_device_id max9611_of_table[] = {
0507     {.compatible = "maxim,max9611", .data = "max9611"},
0508     {.compatible = "maxim,max9612", .data = "max9612"},
0509     { },
0510 };
0511 
0512 MODULE_DEVICE_TABLE(of, max9611_of_table);
0513 static int max9611_probe(struct i2c_client *client,
0514              const struct i2c_device_id *id)
0515 {
0516     const char * const shunt_res_prop = "shunt-resistor-micro-ohms";
0517     struct max9611_dev *max9611;
0518     struct iio_dev *indio_dev;
0519     struct device *dev = &client->dev;
0520     unsigned int of_shunt;
0521     int ret;
0522 
0523     indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*max9611));
0524     if (!indio_dev)
0525         return -ENOMEM;
0526 
0527     i2c_set_clientdata(client, indio_dev);
0528 
0529     max9611         = iio_priv(indio_dev);
0530     max9611->dev        = dev;
0531     max9611->i2c_client = client;
0532     mutex_init(&max9611->lock);
0533 
0534     ret = device_property_read_u32(dev, shunt_res_prop, &of_shunt);
0535     if (ret) {
0536         dev_err(dev, "Missing %s property for %pfw node\n",
0537             shunt_res_prop, dev_fwnode(dev));
0538         return ret;
0539     }
0540     max9611->shunt_resistor_uohm = of_shunt;
0541 
0542     ret = max9611_init(max9611);
0543     if (ret)
0544         return ret;
0545 
0546     indio_dev->name     = device_get_match_data(dev);
0547     indio_dev->modes    = INDIO_DIRECT_MODE;
0548     indio_dev->info     = &indio_info;
0549     indio_dev->channels = max9611_channels;
0550     indio_dev->num_channels = ARRAY_SIZE(max9611_channels);
0551 
0552     return devm_iio_device_register(dev, indio_dev);
0553 }
0554 
0555 static struct i2c_driver max9611_driver = {
0556     .driver = {
0557            .name = DRIVER_NAME,
0558            .of_match_table = max9611_of_table,
0559     },
0560     .probe = max9611_probe,
0561 };
0562 module_i2c_driver(max9611_driver);
0563 
0564 MODULE_AUTHOR("Jacopo Mondi <jacopo+renesas@jmondi.org>");
0565 MODULE_DESCRIPTION("Maxim max9611/12 current sense amplifier with 12bit ADC");
0566 MODULE_LICENSE("GPL v2");