On Fri, Apr 17, 2020 at 01:40:20PM +0200, Linus Walleij wrote: > The manual for the HSCDTD008A gives us a scaling for the > three axis as +/- 2.4mT (24 Gauss) per axis. > > The manual for the AMI305 and AMI306 gives us a scaling > for the three axis as +/- 12 Gauss per axis. > > Tests with the HSCDTD008A sensor, cat the raw values: > $ cat in_magn_*_raw > raw > 45 > 189 > -19 > > The scaling factor in in_magn_*_scale is 0.001464843, > which gives: > 0.065 Gauss > 0.277 Gauss > -0.027 Gauss > > The earths magnetic field is in the range of 0.25 to 0.65 > Gauss on the surface according to Wikipedia, so these > seem like reasonable values. > > Again we are guessing that the AK8974 has a 12 bit ADC, > based on the similarity with AMI305 and AMI306. > > Cc: Nick Reitemeyer <nick.reitemeyer@xxxxxx> > Cc: Stephan Gerhold <stephan@xxxxxxxxxxx> > Cc: Michał Mirosław <mirq-linux@xxxxxxxxxxxx> > Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> > --- > ChangeLog v2->v3: > - Scale the 2.4mT/24Gauss to 15 bits for the HSCDTD008A. > - Scale the 12 Gauss to 12 bits for the AMI305/AMI306 > - Use 12 bits for the other variants. > - Return directly in the raw read function. > ChangeLog v1->v2: > - Split out the measurement refactoring. > --- > drivers/iio/magnetometer/ak8974.c | 45 ++++++++++++++++++++++++++++++- > 1 file changed, 44 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c > index b8dbea119a67..f8410ac34316 100644 > --- a/drivers/iio/magnetometer/ak8974.c > +++ b/drivers/iio/magnetometer/ak8974.c > @@ -608,6 +608,48 @@ static int ak8974_read_raw(struct iio_dev *indio_dev, > if (ret) > return ret; > return IIO_VAL_INT; > + case IIO_CHAN_INFO_SCALE: > + switch (ak8974->variant) { > + case AK8974_WHOAMI_VALUE_AMI306: > + case AK8974_WHOAMI_VALUE_AMI305: > + /* > + * The datasheet for AMI305 and AMI306, page 6 > + * specifies the range of the sensor to be > + * +/- 12 Gauss. > + */ > + *val = 12 * 2; > + /* > + * 12 bits are used > + * [ -2048 .. 2047 ] (manual page 20) > + * [ 0xf800 .. 0x07ff ] > + */ > + *val2 = 4096; > + return IIO_VAL_FRACTIONAL; You can leave '* 2' out from both values. And actually, since *val2 is 2^n, you can return IIO_VAL_FRACTIONAL_LOG2 (with *val2 = 11) and save a division in the caller. Best Regards, Michał Mirosław