iio: ak8975: Fix calculation formula for convert micro tesla to gauss unit
PATCH RESEND 1/2 iio: ak8975: Fix calculation formula for convert micro tesla to gauss unit
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.
--- drivers/iio/magnetometer/ak8975.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/iio/magnetometer/ak8975.c +9 -7
@@ -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 ; }
Signature · 5 lines
1.7.9.5 -- Best Regards,
Quoted 7 lines · Beomho Seo
One micro tesla equal 0.01 gauss. So I have fixed calculation formula And add
RAW_TO_GAUSSmacro. ASA is in the range of 0 to 255. If multiply 0.003, calculationresult(in_magn_[*]_scale)is always 0. So multiply 3000 and return andIIO_VAL_INT_PLUS_MICRO.
As a result,read_rawcall back function return accurate scale value.Signed-off-by Beomho Seo <[email protected]>
Applied to the fixes-togreg branch of iio.git
Thanks,
Quoted 50 lines
--- drivers/iio/magnetometer/ak8975.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)drivers/iio/magnetometer/ak8975.c +9
-7@@ -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 ; }
Jonathan Cameron
maintainerQuoted 11 lines · Jonathan Cameron
Quoted 7 lines · Beomho Seo
One micro tesla equal 0.01 gauss. So I have fixed calculation formula And add
RAW_TO_GAUSSmacro. ASA is in the range of 0 to 255. If multiply 0.003, calculationresult(in_magn_[*]_scale)is always 0. So multiply 3000 and return andIIO_VAL_INT_PLUS_MICRO.
As a result,read_rawcall back function return accurate scale value.Signed-off-by Beomho Seo <[email protected]>Applied to the fixes-togreg branch of iio.git
Thanks,
I forgot to mention that I added a line to the description on what the effect of the bug was and also marked this for stable.
Thanks,
Jonathan
Quoted 55 lines
Quoted 40 lines
--- drivers/iio/magnetometer/ak8975.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)drivers/iio/magnetometer/ak8975.c +6
-5@@ -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 :drivers/iio/magnetometer/ak8975.c static int ak8975_read_raw(struct iio_dev *indio_dev, · line 437
Quoted 10 lines
drivers/iio/magnetometer/ak8975.c +3
-2return 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 ; }--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html