diff mbox series

[v2,10/10] iio: adc: mcp3911: add support to set PGA

Message ID 20220625103853.2470346-10-marcus.folkesson@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series [v2,01/10] iio: adc: mcp3911: correct "microchip,device-addr" property | expand

Commit Message

Marcus Folkesson June 25, 2022, 10:38 a.m. UTC
Add support for setting the Programmable Gain Amplifiers by adjust the
scale value.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---

Notes:
    v2:
        - add missing comma
        - Address comments from Andy Shevchenko

 drivers/iio/adc/mcp3911.c | 134 +++++++++++++++++++++++++++++++-------
 1 file changed, 110 insertions(+), 24 deletions(-)

Comments

kernel test robot June 25, 2022, 12:08 p.m. UTC | #1
Hi Marcus,

I love your patch! Perhaps something to improve:

[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on linus/master v5.19-rc3 next-20220624]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Marcus-Folkesson/iio-adc-mcp3911-correct-microchip-device-addr-property/20220625-184118
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
config: i386-randconfig-a001
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/def017eb4efc80ab515495d6eb7d59d142c0276d
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Marcus-Folkesson/iio-adc-mcp3911-correct-microchip-device-addr-property/20220625-184118
        git checkout def017eb4efc80ab515495d6eb7d59d142c0276d
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/iio/adc/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/iio/adc/mcp3911.c: In function 'mcp3911_calc_scale_table':
>> drivers/iio/adc/mcp3911.c:305:13: warning: variable 'tmp0' set but not used [-Wunused-but-set-variable]
     305 |         int tmp0, tmp1;
         |             ^~~~
   drivers/iio/adc/mcp3911.c: At top level:
   drivers/iio/adc/mcp3911.c:366:22: warning: initialized field overwritten [-Woverride-init]
     366 |         MCP3911_CHAN(0),
         |                      ^
   drivers/iio/adc/mcp3911.c:347:31: note: in definition of macro 'MCP3911_CHAN'
     347 |                 .scan_index = idx,                              \
         |                               ^~~
   drivers/iio/adc/mcp3911.c:366:22: note: (near initialization for 'mcp3911_channels[0].scan_index')
     366 |         MCP3911_CHAN(0),
         |                      ^
   drivers/iio/adc/mcp3911.c:347:31: note: in definition of macro 'MCP3911_CHAN'
     347 |                 .scan_index = idx,                              \
         |                               ^~~
   drivers/iio/adc/mcp3911.c:367:22: warning: initialized field overwritten [-Woverride-init]
     367 |         MCP3911_CHAN(1),
         |                      ^
   drivers/iio/adc/mcp3911.c:347:31: note: in definition of macro 'MCP3911_CHAN'
     347 |                 .scan_index = idx,                              \
         |                               ^~~
   drivers/iio/adc/mcp3911.c:367:22: note: (near initialization for 'mcp3911_channels[1].scan_index')
     367 |         MCP3911_CHAN(1),
         |                      ^
   drivers/iio/adc/mcp3911.c:347:31: note: in definition of macro 'MCP3911_CHAN'
     347 |                 .scan_index = idx,                              \
         |                               ^~~


vim +/tmp0 +305 drivers/iio/adc/mcp3911.c

   299	
   300	static int mcp3911_calc_scale_table(struct mcp3911 *adc)
   301	{
   302		u32 ref = MCP3911_INT_VREF_MV;
   303		u32 div;
   304		int ret;
 > 305		int tmp0, tmp1;
   306		s64 tmp2;
   307	
   308		if (adc->vref) {
   309			ret = regulator_get_voltage(adc->vref);
   310			if (ret < 0) {
   311				dev_err(&adc->spi->dev,
   312					"failed to get vref voltage: %d\n",
   313				       ret);
   314				return ret;
   315			}
   316	
   317			ref = ret / 1000;
   318		}
   319	
   320		/*
   321		 * For 24bit Conversion
   322		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
   323		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
   324		 */
   325	
   326		/* ref = Reference voltage
   327		 * div = (2^23 * 1.5 * gain) = 12582912 * gain
   328		 */
   329		for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
   330			div = 12582912 * BIT(i);
   331			tmp2 = div_s64((s64)ref * 1000000000LL, div);
   332			tmp1 = div;
   333			tmp0 = (int)div_s64_rem(tmp2, 1000000000, &tmp1);
   334	
   335			mcp3911_scale_table[i][0] = 0;
   336			mcp3911_scale_table[i][1] = tmp1;
   337		}
   338	
   339		return 0;
   340	}
   341
Jonathan Cameron June 25, 2022, 12:54 p.m. UTC | #2
On Sat, 25 Jun 2022 12:38:53 +0200
Marcus Folkesson <marcus.folkesson@gmail.com> wrote:

> Add support for setting the Programmable Gain Amplifiers by adjust the
> scale value.
> 
> Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
A few minor things inline.

Thanks,

Jonathan

> ---
> 
> Notes:
>     v2:
>         - add missing comma
>         - Address comments from Andy Shevchenko
> 
>  drivers/iio/adc/mcp3911.c | 134 +++++++++++++++++++++++++++++++-------
>  1 file changed, 110 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> index a019264e73e3..f0179385485f 100644
> --- a/drivers/iio/adc/mcp3911.c
> +++ b/drivers/iio/adc/mcp3911.c
> @@ -26,6 +26,8 @@
>  #define MCP3911_REG_MOD			0x06
>  #define MCP3911_REG_PHASE		0x07
>  #define MCP3911_REG_GAIN		0x09
> +#define MCP3911_GAIN_MASK(ch)          (0x7 << 3*ch)
> +#define MCP3911_GAIN_VAL(ch, val)      ((val << 3*ch) & MCP3911_GAIN_MASK(ch))
>  
>  #define MCP3911_REG_STATUSCOM		0x0a
>  #define MCP3911_STATUSCOM_DRHIZ         BIT(12)
> @@ -55,8 +57,10 @@
>  #define MCP3911_REG_WRITE(reg, id)	((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
>  
>  #define MCP3911_NUM_CHANNELS		2
> +#define MCP3911_NUM_SCALES		6
>  
>  static const int mcp3911_osr_table[] = {32, 64, 128, 256, 512, 1024, 2048, 4096};
> +static u32 mcp3911_scale_table[MCP3911_NUM_SCALES][2];
>  
>  struct mcp3911 {
>  	struct spi_device *spi;
> @@ -65,6 +69,7 @@ struct mcp3911 {
>  	struct clk *clki;
>  	u32 dev_addr;
>  	struct iio_trigger *trig;
> +	u32 gain[MCP3911_NUM_CHANNELS];
>  	struct {
>  		u32 channels[2];
>  		s64 ts __aligned(8);
> @@ -113,6 +118,37 @@ static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask,
>  	return mcp3911_write(adc, reg, val, len);
>  }
>  
> +static int mcp3911_get_gain(struct mcp3911 *adc, u8 channel, u32 *val)
> +{
> +	int ret;
> +
> +	ret = mcp3911_read(adc, MCP3911_REG_GAIN, val, 1);
> +	if (ret)
> +		return ret;
> +
> +	*val >>= channel * 3;
> +	*val &= GENMASK(2, 0);
> +	*val = BIT(*val);
> +
> +	return 0;
> +}
> +
> +static int mcp3911_write_raw_get_fmt(struct iio_dev *indio_dev,
> +					struct iio_chan_spec const *chan,
> +					long mask)
> +{
> +	switch (mask) {
> +	case IIO_CHAN_INFO_SCALE:
> +		return IIO_VAL_INT_PLUS_NANO;
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_PHASE:
> +		return IIO_VAL_INT;

Ah. here is what I asked for earlier. Please move it back to the
patches that introduced the other features.

> +	default:
> +		return IIO_VAL_INT_PLUS_NANO;
> +	}
> +}
> +
>  static int mcp3911_read_avail(struct iio_dev *indio_dev,
>  			     struct iio_chan_spec const *chan,
>  			     const int **vals, int *type, int *length,
> @@ -124,6 +160,11 @@ static int mcp3911_read_avail(struct iio_dev *indio_dev,
>  		*vals = mcp3911_osr_table;
>  		*length = ARRAY_SIZE(mcp3911_osr_table);
>  		return IIO_AVAIL_LIST;
> +	case IIO_CHAN_INFO_SCALE:
> +		*type = IIO_VAL_INT_PLUS_NANO;
> +		*vals = (int *)mcp3911_scale_table;
> +		*length = ARRAY_SIZE(mcp3911_scale_table) * 2;
> +		return IIO_AVAIL_LIST;
>  	default:
>  		return -EINVAL;
>  	}
> @@ -180,29 +221,9 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
>  		break;
>  
>  	case IIO_CHAN_INFO_SCALE:
> -		if (adc->vref) {
> -			ret = regulator_get_voltage(adc->vref);
> -			if (ret < 0) {
> -				dev_err(indio_dev->dev.parent,
> -					"failed to get vref voltage: %d\n",
> -				       ret);
> -				goto out;
> -			}
> -
> -			*val = ret / 1000;
> -		} else {
> -			*val = MCP3911_INT_VREF_MV;
> -		}
> -
> -		/*
> -		 * For 24bit Conversion
> -		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
> -		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
> -		 */
> -
> -		/* val2 = (2^23 * 1.5) */
> -		*val2 = 12582912;
> -		ret = IIO_VAL_FRACTIONAL;
> +		*val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0];
> +		*val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1];
> +		ret = IIO_VAL_INT_PLUS_NANO;
>  		break;
>  	}
>  
> @@ -220,6 +241,18 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
>  
>  	mutex_lock(&adc->lock);
>  	switch (mask) {
> +	case IIO_CHAN_INFO_SCALE:
> +		for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
> +			if (val == mcp3911_scale_table[i][0] &&
> +				val2 == mcp3911_scale_table[i][1]) {
> +
> +				adc->gain[channel->channel] = BIT(i);
> +				ret = mcp3911_update(adc, MCP3911_REG_GAIN,
> +						MCP3911_GAIN_MASK(channel->channel),
> +						MCP3911_GAIN_VAL(channel->channel, i), 1);
> +			}
> +		}
> +		break;
>  	case IIO_CHAN_INFO_OFFSET:
>  		if (val2 != 0) {
>  			ret = -EINVAL;
> @@ -264,6 +297,48 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
>  	return ret;
>  }
>  
> +static int mcp3911_calc_scale_table(struct mcp3911 *adc)
> +{
> +	u32 ref = MCP3911_INT_VREF_MV;
> +	u32 div;
> +	int ret;
> +	int tmp0, tmp1;
> +	s64 tmp2;
> +
> +	if (adc->vref) {
> +		ret = regulator_get_voltage(adc->vref);
> +		if (ret < 0) {
> +			dev_err(&adc->spi->dev,
> +				"failed to get vref voltage: %d\n",
> +			       ret);
> +			return ret;
> +		}
> +
> +		ref = ret / 1000;
> +	}
> +
> +	/*
> +	 * For 24bit Conversion
> +	 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
> +	 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
> +	 */
> +
> +	/* ref = Reference voltage

comment syntax is wrong.  Also a bit odd to have two comment
blocks next to each other. Please combine them.

> +	 * div = (2^23 * 1.5 * gain) = 12582912 * gain
> +	 */
> +	for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
> +		div = 12582912 * BIT(i);
> +		tmp2 = div_s64((s64)ref * 1000000000LL, div);
> +		tmp1 = div;
> +		tmp0 = (int)div_s64_rem(tmp2, 1000000000, &tmp1);
> +
> +		mcp3911_scale_table[i][0] = 0;
> +		mcp3911_scale_table[i][1] = tmp1;
> +	}
> +
> +	return 0;
> +}
> +
>  #define MCP3911_CHAN(idx) {					\
>  		.type = IIO_VOLTAGE,				\
>  		.indexed = 1,					\
> @@ -276,8 +351,10 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
>  		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
>  			BIT(IIO_CHAN_INFO_OFFSET) |		\
>  			BIT(IIO_CHAN_INFO_SCALE),		\
> -		.info_mask_shared_by_type_available =		\
> +		.info_mask_shared_by_type_available =           \
>  			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
> +		.info_mask_separate_available =			\
> +			BIT(IIO_CHAN_INFO_SCALE),		\
>  		.scan_type = {					\
>  			.sign = 's',				\
>  			.realbits = 24,				\
> @@ -330,6 +407,7 @@ static const struct iio_info mcp3911_info = {
>  	.read_raw = mcp3911_read_raw,
>  	.write_raw = mcp3911_write_raw,
>  	.read_avail = mcp3911_read_avail,
> +	.write_raw_get_fmt = mcp3911_write_raw_get_fmt,
>  };
>  
>  static irqreturn_t mcp3911_interrupt(int irq, void *dev_id)
> @@ -460,6 +538,14 @@ static int mcp3911_probe(struct spi_device *spi)
>  	if (ret)
>  		goto clk_disable;
>  
> +	ret = mcp3911_calc_scale_table(adc);
> +	if (ret)
> +		goto clk_disable;
> +
> +       /* Store gain values to better calculate scale values */

Run checkpatch.pl You have spaces here which should be a tab.

> +	mcp3911_get_gain(adc, 0, &adc->gain[0]);
> +	mcp3911_get_gain(adc, 1, &adc->gain[1]);

We'd normally set something like this to default value rather than
rely on sane state from a previous startup.  Either that or rely on reset
(which device has, but I don't think driver supports yet).



> +
>  	if (device_property_read_bool(&adc->spi->dev, "microchip,data-ready-hiz"))
>  		ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, MCP3911_STATUSCOM_DRHIZ,
>  				0, 2);
diff mbox series

Patch

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index a019264e73e3..f0179385485f 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -26,6 +26,8 @@ 
 #define MCP3911_REG_MOD			0x06
 #define MCP3911_REG_PHASE		0x07
 #define MCP3911_REG_GAIN		0x09
+#define MCP3911_GAIN_MASK(ch)          (0x7 << 3*ch)
+#define MCP3911_GAIN_VAL(ch, val)      ((val << 3*ch) & MCP3911_GAIN_MASK(ch))
 
 #define MCP3911_REG_STATUSCOM		0x0a
 #define MCP3911_STATUSCOM_DRHIZ         BIT(12)
@@ -55,8 +57,10 @@ 
 #define MCP3911_REG_WRITE(reg, id)	((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
 
 #define MCP3911_NUM_CHANNELS		2
+#define MCP3911_NUM_SCALES		6
 
 static const int mcp3911_osr_table[] = {32, 64, 128, 256, 512, 1024, 2048, 4096};
+static u32 mcp3911_scale_table[MCP3911_NUM_SCALES][2];
 
 struct mcp3911 {
 	struct spi_device *spi;
@@ -65,6 +69,7 @@  struct mcp3911 {
 	struct clk *clki;
 	u32 dev_addr;
 	struct iio_trigger *trig;
+	u32 gain[MCP3911_NUM_CHANNELS];
 	struct {
 		u32 channels[2];
 		s64 ts __aligned(8);
@@ -113,6 +118,37 @@  static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask,
 	return mcp3911_write(adc, reg, val, len);
 }
 
+static int mcp3911_get_gain(struct mcp3911 *adc, u8 channel, u32 *val)
+{
+	int ret;
+
+	ret = mcp3911_read(adc, MCP3911_REG_GAIN, val, 1);
+	if (ret)
+		return ret;
+
+	*val >>= channel * 3;
+	*val &= GENMASK(2, 0);
+	*val = BIT(*val);
+
+	return 0;
+}
+
+static int mcp3911_write_raw_get_fmt(struct iio_dev *indio_dev,
+					struct iio_chan_spec const *chan,
+					long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		return IIO_VAL_INT_PLUS_NANO;
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_PHASE:
+		return IIO_VAL_INT;
+	default:
+		return IIO_VAL_INT_PLUS_NANO;
+	}
+}
+
 static int mcp3911_read_avail(struct iio_dev *indio_dev,
 			     struct iio_chan_spec const *chan,
 			     const int **vals, int *type, int *length,
@@ -124,6 +160,11 @@  static int mcp3911_read_avail(struct iio_dev *indio_dev,
 		*vals = mcp3911_osr_table;
 		*length = ARRAY_SIZE(mcp3911_osr_table);
 		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_SCALE:
+		*type = IIO_VAL_INT_PLUS_NANO;
+		*vals = (int *)mcp3911_scale_table;
+		*length = ARRAY_SIZE(mcp3911_scale_table) * 2;
+		return IIO_AVAIL_LIST;
 	default:
 		return -EINVAL;
 	}
@@ -180,29 +221,9 @@  static int mcp3911_read_raw(struct iio_dev *indio_dev,
 		break;
 
 	case IIO_CHAN_INFO_SCALE:
-		if (adc->vref) {
-			ret = regulator_get_voltage(adc->vref);
-			if (ret < 0) {
-				dev_err(indio_dev->dev.parent,
-					"failed to get vref voltage: %d\n",
-				       ret);
-				goto out;
-			}
-
-			*val = ret / 1000;
-		} else {
-			*val = MCP3911_INT_VREF_MV;
-		}
-
-		/*
-		 * For 24bit Conversion
-		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
-		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
-		 */
-
-		/* val2 = (2^23 * 1.5) */
-		*val2 = 12582912;
-		ret = IIO_VAL_FRACTIONAL;
+		*val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0];
+		*val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1];
+		ret = IIO_VAL_INT_PLUS_NANO;
 		break;
 	}
 
@@ -220,6 +241,18 @@  static int mcp3911_write_raw(struct iio_dev *indio_dev,
 
 	mutex_lock(&adc->lock);
 	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
+			if (val == mcp3911_scale_table[i][0] &&
+				val2 == mcp3911_scale_table[i][1]) {
+
+				adc->gain[channel->channel] = BIT(i);
+				ret = mcp3911_update(adc, MCP3911_REG_GAIN,
+						MCP3911_GAIN_MASK(channel->channel),
+						MCP3911_GAIN_VAL(channel->channel, i), 1);
+			}
+		}
+		break;
 	case IIO_CHAN_INFO_OFFSET:
 		if (val2 != 0) {
 			ret = -EINVAL;
@@ -264,6 +297,48 @@  static int mcp3911_write_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int mcp3911_calc_scale_table(struct mcp3911 *adc)
+{
+	u32 ref = MCP3911_INT_VREF_MV;
+	u32 div;
+	int ret;
+	int tmp0, tmp1;
+	s64 tmp2;
+
+	if (adc->vref) {
+		ret = regulator_get_voltage(adc->vref);
+		if (ret < 0) {
+			dev_err(&adc->spi->dev,
+				"failed to get vref voltage: %d\n",
+			       ret);
+			return ret;
+		}
+
+		ref = ret / 1000;
+	}
+
+	/*
+	 * For 24bit Conversion
+	 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
+	 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
+	 */
+
+	/* ref = Reference voltage
+	 * div = (2^23 * 1.5 * gain) = 12582912 * gain
+	 */
+	for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
+		div = 12582912 * BIT(i);
+		tmp2 = div_s64((s64)ref * 1000000000LL, div);
+		tmp1 = div;
+		tmp0 = (int)div_s64_rem(tmp2, 1000000000, &tmp1);
+
+		mcp3911_scale_table[i][0] = 0;
+		mcp3911_scale_table[i][1] = tmp1;
+	}
+
+	return 0;
+}
+
 #define MCP3911_CHAN(idx) {					\
 		.type = IIO_VOLTAGE,				\
 		.indexed = 1,					\
@@ -276,8 +351,10 @@  static int mcp3911_write_raw(struct iio_dev *indio_dev,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
 			BIT(IIO_CHAN_INFO_OFFSET) |		\
 			BIT(IIO_CHAN_INFO_SCALE),		\
-		.info_mask_shared_by_type_available =		\
+		.info_mask_shared_by_type_available =           \
 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		.info_mask_separate_available =			\
+			BIT(IIO_CHAN_INFO_SCALE),		\
 		.scan_type = {					\
 			.sign = 's',				\
 			.realbits = 24,				\
@@ -330,6 +407,7 @@  static const struct iio_info mcp3911_info = {
 	.read_raw = mcp3911_read_raw,
 	.write_raw = mcp3911_write_raw,
 	.read_avail = mcp3911_read_avail,
+	.write_raw_get_fmt = mcp3911_write_raw_get_fmt,
 };
 
 static irqreturn_t mcp3911_interrupt(int irq, void *dev_id)
@@ -460,6 +538,14 @@  static int mcp3911_probe(struct spi_device *spi)
 	if (ret)
 		goto clk_disable;
 
+	ret = mcp3911_calc_scale_table(adc);
+	if (ret)
+		goto clk_disable;
+
+       /* Store gain values to better calculate scale values */
+	mcp3911_get_gain(adc, 0, &adc->gain[0]);
+	mcp3911_get_gain(adc, 1, &adc->gain[1]);
+
 	if (device_property_read_bool(&adc->spi->dev, "microchip,data-ready-hiz"))
 		ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, MCP3911_STATUSCOM_DRHIZ,
 				0, 2);