iio: ak8975: Fix calculation formula for convert micro tesla to gauss unit

This effects the reported scale of the raw values, and thus userspace
applications that use this value.

One micro tesla equal 0.01 gauss. So I have fixed calculation formula And add RAW_TO_GAUSS macro.
ASA is in the range of 0 to 255. If multiply 0.003, calculation result(in_magn_[*]_scale) is
always 0. So multiply 3000 and return and IIO_VAL_INT_PLUS_MICRO.
As a result, read_raw call back function return accurate scale value.

Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
This commit is contained in:
Beomho Seo 2014-04-02 09:15:00 +01:00 committed by Jonathan Cameron
parent d180371d41
commit bef44abccb
1 changed files with 9 additions and 7 deletions

View File

@ -85,6 +85,7 @@
#define AK8975_MAX_CONVERSION_TIMEOUT 500
#define AK8975_CONVERSION_DONE_POLL_TIME 10
#define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000)
#define RAW_TO_GAUSS(asa) ((((asa) + 128) * 3000) / 256)
/*
* Per-instance context data for the device.
@ -265,15 +266,15 @@ static int ak8975_setup(struct i2c_client *client)
*
* Since 1uT = 0.01 gauss, our final scale factor becomes:
*
* Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
* Hadj = H * ((ASA + 128) * 30 / 256
* Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
* Hadj = H * ((ASA + 128) * 0.003) / 256
*
* Since ASA doesn't change, we cache the resultant scale factor into the
* device context in ak8975_setup().
*/
data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
data->raw_to_gauss[0] = RAW_TO_GAUSS(data->asa[0]);
data->raw_to_gauss[1] = RAW_TO_GAUSS(data->asa[1]);
data->raw_to_gauss[2] = RAW_TO_GAUSS(data->asa[2]);
return 0;
}
@ -428,8 +429,9 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_RAW:
return ak8975_read_axis(indio_dev, chan->address, val);
case IIO_CHAN_INFO_SCALE:
*val = data->raw_to_gauss[chan->address];
return IIO_VAL_INT;
*val = 0;
*val2 = data->raw_to_gauss[chan->address];
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}