Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &regval);
^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");