aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/pressure/bmp280.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/pressure/bmp280.c')
-rw-r--r--drivers/iio/pressure/bmp280.c150
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/*
84struct 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}; 87enum { T1, T2, T3 };
88 88enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
89struct 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
94static const struct iio_chan_spec bmp280_channels[] = { 90static 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
144static 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
165static 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 */
199static s32 bmp280_compensate_temp(struct bmp280_data *data, 147static 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 */
224static u32 bmp280_compensate_press(struct bmp280_data *data, 186static 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
250static int bmp280_read_temp(struct bmp280_data *data, 221static 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;