Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: accel: bmc150: Use more consistent and accurate scale values

It is quite strange that BMA222 and BMA222E have very close, yet
subtly different values in their scale tables. Comparing the datasheets
this is simply because the "Resolution" for the different measurement
ranges are documented with different precision.

For example, for +-2g the BMA222 datasheet [1] suggests a resolution
of 15.6 mg/LSB, while the BMA222E datasheet [2] suggests 15.63 mg/LSB.

Actually, there is no need to rely on the resolution given by the Bosch
datasheets. The resolution and scale can be calculated more consistently
and accurately using the range (e.g. +-2g) and the channel size (e.g. 8 bits).

Distributing 4g (-2g to 2g) over 8 bits results in an exact resolution
of (4g / 2^8) = 15.625 mg/LSB which is the same value as in both datasheets,
just slightly more accurate. Multiplying g = 9.80665 m/s^2 we get a more
accurate value for the IIO scale table.

Generalizing this we can calculate the scale tables more accurately using
(range / 2^bits) * g * 10^6 (because of IIO_VAL_INT_PLUS_MICRO).

Document this and make the scale tables more consistent and accurate
for all the variants using that formula. Now the scale tables for
BMA222 and BMA222E are consistent and probably slightly more accurate.

[1]: https://media.digikey.com/pdf/Data%20Sheets/Bosch/BMA222.pdf
[2]: https://www.mouser.com/datasheet/2/783/BST-BMA222E-DS004-06-1021076.pdf

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gnail.com>
Link: https://lore.kernel.org/r/20210611182442.1971-1-stephan@gerhold.net
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Stephan Gerhold and committed by
Jonathan Cameron
e2a73c4e fb226ae7

+24 -22
+24 -22
drivers/iio/accel/bmc150-accel-core.c
··· 1088 1088 static const struct iio_chan_spec bma280_accel_channels[] = 1089 1089 BMC150_ACCEL_CHANNELS(14); 1090 1090 1091 + /* 1092 + * The range for the Bosch sensors is typically +-2g/4g/8g/16g, distributed 1093 + * over the amount of bits (see above). The scale table can be calculated using 1094 + * (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2 1095 + * e.g. for +-2g and 12 bits: (4 / 2^12) * 9.80665 m/s^2 = 0.0095768... m/s^2 1096 + * Multiply 10^6 and round to get the values listed below. 1097 + */ 1091 1098 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { 1092 1099 { 1093 1100 .name = "BMA222", 1094 1101 .chip_id = 0x03, 1095 1102 .channels = bma222e_accel_channels, 1096 1103 .num_channels = ARRAY_SIZE(bma222e_accel_channels), 1097 - /* 1098 - * The datasheet page 17 says: 1099 - * 15.6, 31.3, 62.5 and 125 mg per LSB. 1100 - * IIO unit is m/s^2 so multiply by g = 9.80665 m/s^2. 1101 - */ 1102 - .scale_table = { {152984, BMC150_ACCEL_DEF_RANGE_2G}, 1103 - {306948, BMC150_ACCEL_DEF_RANGE_4G}, 1104 + .scale_table = { {153229, BMC150_ACCEL_DEF_RANGE_2G}, 1105 + {306458, BMC150_ACCEL_DEF_RANGE_4G}, 1104 1106 {612916, BMC150_ACCEL_DEF_RANGE_8G}, 1105 1107 {1225831, BMC150_ACCEL_DEF_RANGE_16G} }, 1106 1108 }, ··· 1111 1109 .chip_id = 0xF8, 1112 1110 .channels = bma222e_accel_channels, 1113 1111 .num_channels = ARRAY_SIZE(bma222e_accel_channels), 1114 - .scale_table = { {153277, BMC150_ACCEL_DEF_RANGE_2G}, 1115 - {306457, BMC150_ACCEL_DEF_RANGE_4G}, 1116 - {612915, BMC150_ACCEL_DEF_RANGE_8G}, 1112 + .scale_table = { {153229, BMC150_ACCEL_DEF_RANGE_2G}, 1113 + {306458, BMC150_ACCEL_DEF_RANGE_4G}, 1114 + {612916, BMC150_ACCEL_DEF_RANGE_8G}, 1117 1115 {1225831, BMC150_ACCEL_DEF_RANGE_16G} }, 1118 1116 }, 1119 1117 { ··· 1121 1119 .chip_id = 0xF9, 1122 1120 .channels = bma250e_accel_channels, 1123 1121 .num_channels = ARRAY_SIZE(bma250e_accel_channels), 1124 - .scale_table = { {38344, BMC150_ACCEL_DEF_RANGE_2G}, 1125 - {76590, BMC150_ACCEL_DEF_RANGE_4G}, 1126 - {153277, BMC150_ACCEL_DEF_RANGE_8G}, 1127 - {306457, BMC150_ACCEL_DEF_RANGE_16G} }, 1122 + .scale_table = { {38307, BMC150_ACCEL_DEF_RANGE_2G}, 1123 + {76614, BMC150_ACCEL_DEF_RANGE_4G}, 1124 + {153229, BMC150_ACCEL_DEF_RANGE_8G}, 1125 + {306458, BMC150_ACCEL_DEF_RANGE_16G} }, 1128 1126 }, 1129 1127 { 1130 1128 .name = "BMA253/BMA254/BMA255/BMC150/BMI055", 1131 1129 .chip_id = 0xFA, 1132 1130 .channels = bmc150_accel_channels, 1133 1131 .num_channels = ARRAY_SIZE(bmc150_accel_channels), 1134 - .scale_table = { {9610, BMC150_ACCEL_DEF_RANGE_2G}, 1135 - {19122, BMC150_ACCEL_DEF_RANGE_4G}, 1136 - {38344, BMC150_ACCEL_DEF_RANGE_8G}, 1137 - {76590, BMC150_ACCEL_DEF_RANGE_16G} }, 1132 + .scale_table = { {9577, BMC150_ACCEL_DEF_RANGE_2G}, 1133 + {19154, BMC150_ACCEL_DEF_RANGE_4G}, 1134 + {38307, BMC150_ACCEL_DEF_RANGE_8G}, 1135 + {76614, BMC150_ACCEL_DEF_RANGE_16G} }, 1138 1136 }, 1139 1137 { 1140 1138 .name = "BMA280", 1141 1139 .chip_id = 0xFB, 1142 1140 .channels = bma280_accel_channels, 1143 1141 .num_channels = ARRAY_SIZE(bma280_accel_channels), 1144 - .scale_table = { {2392, BMC150_ACCEL_DEF_RANGE_2G}, 1145 - {4785, BMC150_ACCEL_DEF_RANGE_4G}, 1146 - {9581, BMC150_ACCEL_DEF_RANGE_8G}, 1147 - {19152, BMC150_ACCEL_DEF_RANGE_16G} }, 1142 + .scale_table = { {2394, BMC150_ACCEL_DEF_RANGE_2G}, 1143 + {4788, BMC150_ACCEL_DEF_RANGE_4G}, 1144 + {9577, BMC150_ACCEL_DEF_RANGE_8G}, 1145 + {19154, BMC150_ACCEL_DEF_RANGE_16G} }, 1148 1146 }, 1149 1147 }; 1150 1148