diff options
Diffstat (limited to 'drivers/iio/pressure/bmp280.c')
-rw-r--r-- | drivers/iio/pressure/bmp280.c | 150 |
1 files changed, 55 insertions, 95 deletions
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c index 75038dacfff1..7c623e2bd633 100644 --- a/drivers/iio/pressure/bmp280.c +++ b/drivers/iio/pressure/bmp280.c | |||
@@ -80,16 +80,12 @@ struct bmp280_data { | |||
80 | s32 t_fine; | 80 | s32 t_fine; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | /* Compensation parameters. */ | 83 | /* |
84 | struct bmp280_comp_temp { | 84 | * These enums are used for indexing into the array of compensation |
85 | u16 dig_t1; | 85 | * parameters. |
86 | s16 dig_t2, dig_t3; | 86 | */ |
87 | }; | 87 | enum { T1, T2, T3 }; |
88 | 88 | enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 }; | |
89 | struct bmp280_comp_press { | ||
90 | u16 dig_p1; | ||
91 | s16 dig_p2, dig_p3, dig_p4, dig_p5, dig_p6, dig_p7, dig_p8, dig_p9; | ||
92 | }; | ||
93 | 89 | ||
94 | static const struct iio_chan_spec bmp280_channels[] = { | 90 | static const struct iio_chan_spec bmp280_channels[] = { |
95 | { | 91 | { |
@@ -141,54 +137,6 @@ static const struct regmap_config bmp280_regmap_config = { | |||
141 | .volatile_reg = bmp280_is_volatile_reg, | 137 | .volatile_reg = bmp280_is_volatile_reg, |
142 | }; | 138 | }; |
143 | 139 | ||
144 | static int bmp280_read_compensation_temp(struct bmp280_data *data, | ||
145 | struct bmp280_comp_temp *comp) | ||
146 | { | ||
147 | int ret; | ||
148 | __le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2]; | ||
149 | |||
150 | ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START, | ||
151 | buf, BMP280_COMP_TEMP_REG_COUNT); | ||
152 | if (ret < 0) { | ||
153 | dev_err(&data->client->dev, | ||
154 | "failed to read temperature calibration parameters\n"); | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | comp->dig_t1 = (u16) le16_to_cpu(buf[0]); | ||
159 | comp->dig_t2 = (s16) le16_to_cpu(buf[1]); | ||
160 | comp->dig_t3 = (s16) le16_to_cpu(buf[2]); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int bmp280_read_compensation_press(struct bmp280_data *data, | ||
166 | struct bmp280_comp_press *comp) | ||
167 | { | ||
168 | int ret; | ||
169 | __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2]; | ||
170 | |||
171 | ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START, | ||
172 | buf, BMP280_COMP_PRESS_REG_COUNT); | ||
173 | if (ret < 0) { | ||
174 | dev_err(&data->client->dev, | ||
175 | "failed to read pressure calibration parameters\n"); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | comp->dig_p1 = (u16) le16_to_cpu(buf[0]); | ||
180 | comp->dig_p2 = (s16) le16_to_cpu(buf[1]); | ||
181 | comp->dig_p3 = (s16) le16_to_cpu(buf[2]); | ||
182 | comp->dig_p4 = (s16) le16_to_cpu(buf[3]); | ||
183 | comp->dig_p5 = (s16) le16_to_cpu(buf[4]); | ||
184 | comp->dig_p6 = (s16) le16_to_cpu(buf[5]); | ||
185 | comp->dig_p7 = (s16) le16_to_cpu(buf[6]); | ||
186 | comp->dig_p8 = (s16) le16_to_cpu(buf[7]); | ||
187 | comp->dig_p9 = (s16) le16_to_cpu(buf[8]); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | /* | 140 | /* |
193 | * Returns temperature in DegC, resolution is 0.01 DegC. Output value of | 141 | * Returns temperature in DegC, resolution is 0.01 DegC. Output value of |
194 | * "5123" equals 51.23 DegC. t_fine carries fine temperature as global | 142 | * "5123" equals 51.23 DegC. t_fine carries fine temperature as global |
@@ -197,21 +145,35 @@ static int bmp280_read_compensation_press(struct bmp280_data *data, | |||
197 | * Taken from datasheet, Section 3.11.3, "Compensation formula". | 145 | * Taken from datasheet, Section 3.11.3, "Compensation formula". |
198 | */ | 146 | */ |
199 | static s32 bmp280_compensate_temp(struct bmp280_data *data, | 147 | static s32 bmp280_compensate_temp(struct bmp280_data *data, |
200 | struct bmp280_comp_temp *comp, | ||
201 | s32 adc_temp) | 148 | s32 adc_temp) |
202 | { | 149 | { |
203 | s32 var1, var2, t; | 150 | int ret; |
151 | s32 var1, var2; | ||
152 | __le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2]; | ||
204 | 153 | ||
205 | var1 = (((adc_temp >> 3) - ((s32) comp->dig_t1 << 1)) * | 154 | ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START, |
206 | ((s32) comp->dig_t2)) >> 11; | 155 | buf, BMP280_COMP_TEMP_REG_COUNT); |
207 | var2 = (((((adc_temp >> 4) - ((s32) comp->dig_t1)) * | 156 | if (ret < 0) { |
208 | ((adc_temp >> 4) - ((s32) comp->dig_t1))) >> 12) * | 157 | dev_err(&data->client->dev, |
209 | ((s32) comp->dig_t3)) >> 14; | 158 | "failed to read temperature calibration parameters\n"); |
159 | return ret; | ||
160 | } | ||
210 | 161 | ||
211 | data->t_fine = var1 + var2; | 162 | /* |
212 | t = (data->t_fine * 5 + 128) >> 8; | 163 | * The double casts are necessary because le16_to_cpu returns an |
164 | * unsigned 16-bit value. Casting that value directly to a | ||
165 | * signed 32-bit will not do proper sign extension. | ||
166 | * | ||
167 | * Conversely, T1 and P1 are unsigned values, so they can be | ||
168 | * cast straight to the larger type. | ||
169 | */ | ||
170 | var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) * | ||
171 | ((s32)(s16)le16_to_cpu(buf[T2]))) >> 11; | ||
172 | var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) * | ||
173 | ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) * | ||
174 | ((s32)(s16)le16_to_cpu(buf[T3]))) >> 14; | ||
213 | 175 | ||
214 | return t; | 176 | return (data->t_fine * 5 + 128) >> 8; |
215 | } | 177 | } |
216 | 178 | ||
217 | /* | 179 | /* |
@@ -222,29 +184,38 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data, | |||
222 | * Taken from datasheet, Section 3.11.3, "Compensation formula". | 184 | * Taken from datasheet, Section 3.11.3, "Compensation formula". |
223 | */ | 185 | */ |
224 | static u32 bmp280_compensate_press(struct bmp280_data *data, | 186 | static u32 bmp280_compensate_press(struct bmp280_data *data, |
225 | struct bmp280_comp_press *comp, | ||
226 | s32 adc_press) | 187 | s32 adc_press) |
227 | { | 188 | { |
189 | int ret; | ||
228 | s64 var1, var2, p; | 190 | s64 var1, var2, p; |
191 | __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2]; | ||
192 | |||
193 | ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START, | ||
194 | buf, BMP280_COMP_PRESS_REG_COUNT); | ||
195 | if (ret < 0) { | ||
196 | dev_err(&data->client->dev, | ||
197 | "failed to read pressure calibration parameters\n"); | ||
198 | return ret; | ||
199 | } | ||
229 | 200 | ||
230 | var1 = ((s64) data->t_fine) - 128000; | 201 | var1 = ((s64)data->t_fine) - 128000; |
231 | var2 = var1 * var1 * (s64) comp->dig_p6; | 202 | var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]); |
232 | var2 = var2 + ((var1 * (s64) comp->dig_p5) << 17); | 203 | var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17; |
233 | var2 = var2 + (((s64) comp->dig_p4) << 35); | 204 | var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35; |
234 | var1 = ((var1 * var1 * (s64) comp->dig_p3) >> 8) + | 205 | var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) + |
235 | ((var1 * (s64) comp->dig_p2) << 12); | 206 | ((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12); |
236 | var1 = (((((s64) 1) << 47) + var1)) * ((s64) comp->dig_p1) >> 33; | 207 | var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33; |
237 | 208 | ||
238 | if (var1 == 0) | 209 | if (var1 == 0) |
239 | return 0; | 210 | return 0; |
240 | 211 | ||
241 | p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125; | 212 | p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125; |
242 | p = div64_s64(p, var1); | 213 | p = div64_s64(p, var1); |
243 | var1 = (((s64) comp->dig_p9) * (p >> 13) * (p >> 13)) >> 25; | 214 | var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25; |
244 | var2 = (((s64) comp->dig_p8) * p) >> 19; | 215 | var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19; |
245 | p = ((p + var1 + var2) >> 8) + (((s64) comp->dig_p7) << 4); | 216 | p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4); |
246 | 217 | ||
247 | return (u32) p; | 218 | return (u32)p; |
248 | } | 219 | } |
249 | 220 | ||
250 | static int bmp280_read_temp(struct bmp280_data *data, | 221 | static int bmp280_read_temp(struct bmp280_data *data, |
@@ -253,11 +224,6 @@ static int bmp280_read_temp(struct bmp280_data *data, | |||
253 | int ret; | 224 | int ret; |
254 | __be32 tmp = 0; | 225 | __be32 tmp = 0; |
255 | s32 adc_temp, comp_temp; | 226 | s32 adc_temp, comp_temp; |
256 | struct bmp280_comp_temp comp; | ||
257 | |||
258 | ret = bmp280_read_compensation_temp(data, &comp); | ||
259 | if (ret < 0) | ||
260 | return ret; | ||
261 | 227 | ||
262 | ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, | 228 | ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, |
263 | (u8 *) &tmp, 3); | 229 | (u8 *) &tmp, 3); |
@@ -267,7 +233,7 @@ static int bmp280_read_temp(struct bmp280_data *data, | |||
267 | } | 233 | } |
268 | 234 | ||
269 | adc_temp = be32_to_cpu(tmp) >> 12; | 235 | adc_temp = be32_to_cpu(tmp) >> 12; |
270 | comp_temp = bmp280_compensate_temp(data, &comp, adc_temp); | 236 | comp_temp = bmp280_compensate_temp(data, adc_temp); |
271 | 237 | ||
272 | /* | 238 | /* |
273 | * val might be NULL if we're called by the read_press routine, | 239 | * val might be NULL if we're called by the read_press routine, |
@@ -288,11 +254,6 @@ static int bmp280_read_press(struct bmp280_data *data, | |||
288 | __be32 tmp = 0; | 254 | __be32 tmp = 0; |
289 | s32 adc_press; | 255 | s32 adc_press; |
290 | u32 comp_press; | 256 | u32 comp_press; |
291 | struct bmp280_comp_press comp; | ||
292 | |||
293 | ret = bmp280_read_compensation_press(data, &comp); | ||
294 | if (ret < 0) | ||
295 | return ret; | ||
296 | 257 | ||
297 | /* Read and compensate temperature so we get a reading of t_fine. */ | 258 | /* Read and compensate temperature so we get a reading of t_fine. */ |
298 | ret = bmp280_read_temp(data, NULL); | 259 | ret = bmp280_read_temp(data, NULL); |
@@ -307,7 +268,7 @@ static int bmp280_read_press(struct bmp280_data *data, | |||
307 | } | 268 | } |
308 | 269 | ||
309 | adc_press = be32_to_cpu(tmp) >> 12; | 270 | adc_press = be32_to_cpu(tmp) >> 12; |
310 | comp_press = bmp280_compensate_press(data, &comp, adc_press); | 271 | comp_press = bmp280_compensate_press(data, adc_press); |
311 | 272 | ||
312 | *val = comp_press; | 273 | *val = comp_press; |
313 | *val2 = 256000; | 274 | *val2 = 256000; |
@@ -366,7 +327,7 @@ static int bmp280_chip_init(struct bmp280_data *data) | |||
366 | BMP280_MODE_NORMAL); | 327 | BMP280_MODE_NORMAL); |
367 | if (ret < 0) { | 328 | if (ret < 0) { |
368 | dev_err(&data->client->dev, | 329 | dev_err(&data->client->dev, |
369 | "failed to write config register\n"); | 330 | "failed to write ctrl_meas register\n"); |
370 | return ret; | 331 | return ret; |
371 | } | 332 | } |
372 | 333 | ||
@@ -394,7 +355,6 @@ static int bmp280_probe(struct i2c_client *client, | |||
394 | if (!indio_dev) | 355 | if (!indio_dev) |
395 | return -ENOMEM; | 356 | return -ENOMEM; |
396 | 357 | ||
397 | i2c_set_clientdata(client, indio_dev); | ||
398 | data = iio_priv(indio_dev); | 358 | data = iio_priv(indio_dev); |
399 | mutex_init(&data->lock); | 359 | mutex_init(&data->lock); |
400 | data->client = client; | 360 | data->client = client; |