1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * Bosch BME680 - Temperature, Pressure, Humidity & Gas Sensor |
4 | * |
5 | * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH |
6 | * Copyright (C) 2018 Himanshu Jha <himanshujha199640@gmail.com> |
7 | * |
8 | * Datasheet: |
9 | * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf |
10 | */ |
11 | #include <linux/bitfield.h> |
12 | #include <linux/cleanup.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/device.h> |
15 | #include <linux/log2.h> |
16 | #include <linux/module.h> |
17 | #include <linux/pm.h> |
18 | #include <linux/pm_runtime.h> |
19 | #include <linux/regmap.h> |
20 | #include <linux/regulator/consumer.h> |
21 | |
22 | #include <linux/iio/buffer.h> |
23 | #include <linux/iio/iio.h> |
24 | #include <linux/iio/sysfs.h> |
25 | #include <linux/iio/trigger_consumer.h> |
26 | #include <linux/iio/triggered_buffer.h> |
27 | |
28 | #include <linux/unaligned.h> |
29 | |
30 | #include "bme680.h" |
31 | |
32 | /* 1st set of calibration data */ |
33 | enum { |
34 | /* Temperature calib indexes */ |
35 | T2_LSB = 0, |
36 | T3 = 2, |
37 | /* Pressure calib indexes */ |
38 | P1_LSB = 4, |
39 | P2_LSB = 6, |
40 | P3 = 8, |
41 | P4_LSB = 10, |
42 | P5_LSB = 12, |
43 | P7 = 14, |
44 | P6 = 15, |
45 | P8_LSB = 18, |
46 | P9_LSB = 20, |
47 | P10 = 22, |
48 | }; |
49 | |
50 | /* 2nd set of calibration data */ |
51 | enum { |
52 | /* Humidity calib indexes */ |
53 | H2_MSB = 0, |
54 | H1_LSB = 1, |
55 | H3 = 3, |
56 | H4 = 4, |
57 | H5 = 5, |
58 | H6 = 6, |
59 | H7 = 7, |
60 | /* Stray T1 calib index */ |
61 | T1_LSB = 8, |
62 | /* Gas heater calib indexes */ |
63 | GH2_LSB = 10, |
64 | GH1 = 12, |
65 | GH3 = 13, |
66 | }; |
67 | |
68 | /* 3rd set of calibration data */ |
69 | enum { |
70 | RES_HEAT_VAL = 0, |
71 | RES_HEAT_RANGE = 2, |
72 | RANGE_SW_ERR = 4, |
73 | }; |
74 | |
75 | struct bme680_calib { |
76 | u16 par_t1; |
77 | s16 par_t2; |
78 | s8 par_t3; |
79 | u16 par_p1; |
80 | s16 par_p2; |
81 | s8 par_p3; |
82 | s16 par_p4; |
83 | s16 par_p5; |
84 | s8 par_p6; |
85 | s8 par_p7; |
86 | s16 par_p8; |
87 | s16 par_p9; |
88 | u8 par_p10; |
89 | u16 par_h1; |
90 | u16 par_h2; |
91 | s8 par_h3; |
92 | s8 par_h4; |
93 | s8 par_h5; |
94 | u8 par_h6; |
95 | s8 par_h7; |
96 | s8 par_gh1; |
97 | s16 par_gh2; |
98 | s8 par_gh3; |
99 | u8 res_heat_range; |
100 | s8 res_heat_val; |
101 | s8 range_sw_err; |
102 | }; |
103 | |
104 | /* values of CTRL_MEAS register */ |
105 | enum bme680_op_mode { |
106 | BME680_MODE_SLEEP = 0, |
107 | BME680_MODE_FORCED = 1, |
108 | }; |
109 | |
110 | enum bme680_scan { |
111 | BME680_TEMP, |
112 | BME680_PRESS, |
113 | BME680_HUMID, |
114 | BME680_GAS, |
115 | }; |
116 | |
117 | static const char *const bme680_supply_names[] = { "vdd", "vddio"}; |
118 | |
119 | struct bme680_data { |
120 | struct regmap *regmap; |
121 | struct bme680_calib bme680; |
122 | struct mutex lock; /* Protect multiple serial R/W ops to device. */ |
123 | u8 oversampling_temp; |
124 | u8 oversampling_press; |
125 | u8 oversampling_humid; |
126 | u8 preheat_curr_mA; |
127 | u16 heater_dur; |
128 | u16 heater_temp; |
129 | |
130 | struct { |
131 | s32 chan[4]; |
132 | aligned_s64 ts; |
133 | } scan; |
134 | |
135 | union { |
136 | u8 buf[BME680_NUM_BULK_READ_REGS]; |
137 | unsigned int check; |
138 | __be16 be16; |
139 | u8 bme680_cal_buf_1[BME680_CALIB_RANGE_1_LEN]; |
140 | u8 bme680_cal_buf_2[BME680_CALIB_RANGE_2_LEN]; |
141 | u8 bme680_cal_buf_3[BME680_CALIB_RANGE_3_LEN]; |
142 | }; |
143 | }; |
144 | |
145 | static const struct regmap_range bme680_volatile_ranges[] = { |
146 | regmap_reg_range(BME680_REG_MEAS_STAT_0, BME680_REG_GAS_R_LSB), |
147 | regmap_reg_range(BME680_REG_STATUS, BME680_REG_STATUS), |
148 | regmap_reg_range(BME680_T2_LSB_REG, BME680_GH3_REG), |
149 | }; |
150 | |
151 | static const struct regmap_access_table bme680_volatile_table = { |
152 | .yes_ranges = bme680_volatile_ranges, |
153 | .n_yes_ranges = ARRAY_SIZE(bme680_volatile_ranges), |
154 | }; |
155 | |
156 | const struct regmap_config bme680_regmap_config = { |
157 | .reg_bits = 8, |
158 | .val_bits = 8, |
159 | .max_register = 0xef, |
160 | .volatile_table = &bme680_volatile_table, |
161 | .cache_type = REGCACHE_RBTREE, |
162 | }; |
163 | EXPORT_SYMBOL_NS(bme680_regmap_config, "IIO_BME680"); |
164 | |
165 | static const struct iio_chan_spec bme680_channels[] = { |
166 | { |
167 | .type = IIO_TEMP, |
168 | /* PROCESSED maintained for ABI backwards compatibility */ |
169 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | |
170 | BIT(IIO_CHAN_INFO_RAW) | |
171 | BIT(IIO_CHAN_INFO_SCALE) | |
172 | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), |
173 | .scan_index = 0, |
174 | .scan_type = { |
175 | .sign = 's', |
176 | .realbits = 16, |
177 | .storagebits = 16, |
178 | .endianness = IIO_CPU, |
179 | }, |
180 | }, |
181 | { |
182 | .type = IIO_PRESSURE, |
183 | /* PROCESSED maintained for ABI backwards compatibility */ |
184 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | |
185 | BIT(IIO_CHAN_INFO_RAW) | |
186 | BIT(IIO_CHAN_INFO_SCALE) | |
187 | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), |
188 | .scan_index = 1, |
189 | .scan_type = { |
190 | .sign = 'u', |
191 | .realbits = 32, |
192 | .storagebits = 32, |
193 | .endianness = IIO_CPU, |
194 | }, |
195 | }, |
196 | { |
197 | .type = IIO_HUMIDITYRELATIVE, |
198 | /* PROCESSED maintained for ABI backwards compatibility */ |
199 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | |
200 | BIT(IIO_CHAN_INFO_RAW) | |
201 | BIT(IIO_CHAN_INFO_SCALE) | |
202 | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), |
203 | .scan_index = 2, |
204 | .scan_type = { |
205 | .sign = 'u', |
206 | .realbits = 32, |
207 | .storagebits = 32, |
208 | .endianness = IIO_CPU, |
209 | }, |
210 | }, |
211 | { |
212 | .type = IIO_RESISTANCE, |
213 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), |
214 | .scan_index = 3, |
215 | .scan_type = { |
216 | .sign = 'u', |
217 | .realbits = 32, |
218 | .storagebits = 32, |
219 | .endianness = IIO_CPU, |
220 | }, |
221 | }, |
222 | IIO_CHAN_SOFT_TIMESTAMP(4), |
223 | { |
224 | .type = IIO_CURRENT, |
225 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), |
226 | .output = 1, |
227 | .scan_index = -1, |
228 | }, |
229 | }; |
230 | |
231 | static int bme680_read_calib(struct bme680_data *data, |
232 | struct bme680_calib *calib) |
233 | { |
234 | struct device *dev = regmap_get_device(map: data->regmap); |
235 | unsigned int tmp_msb, tmp_lsb; |
236 | int ret; |
237 | |
238 | ret = regmap_bulk_read(map: data->regmap, BME680_T2_LSB_REG, |
239 | val: data->bme680_cal_buf_1, |
240 | val_count: sizeof(data->bme680_cal_buf_1)); |
241 | if (ret < 0) { |
242 | dev_err(dev, "failed to read 1st set of calib data;\n"); |
243 | return ret; |
244 | } |
245 | |
246 | calib->par_t2 = get_unaligned_le16(p: &data->bme680_cal_buf_1[T2_LSB]); |
247 | calib->par_t3 = data->bme680_cal_buf_1[T3]; |
248 | calib->par_p1 = get_unaligned_le16(p: &data->bme680_cal_buf_1[P1_LSB]); |
249 | calib->par_p2 = get_unaligned_le16(p: &data->bme680_cal_buf_1[P2_LSB]); |
250 | calib->par_p3 = data->bme680_cal_buf_1[P3]; |
251 | calib->par_p4 = get_unaligned_le16(p: &data->bme680_cal_buf_1[P4_LSB]); |
252 | calib->par_p5 = get_unaligned_le16(p: &data->bme680_cal_buf_1[P5_LSB]); |
253 | calib->par_p7 = data->bme680_cal_buf_1[P7]; |
254 | calib->par_p6 = data->bme680_cal_buf_1[P6]; |
255 | calib->par_p8 = get_unaligned_le16(p: &data->bme680_cal_buf_1[P8_LSB]); |
256 | calib->par_p9 = get_unaligned_le16(p: &data->bme680_cal_buf_1[P9_LSB]); |
257 | calib->par_p10 = data->bme680_cal_buf_1[P10]; |
258 | |
259 | ret = regmap_bulk_read(map: data->regmap, BME680_H2_MSB_REG, |
260 | val: data->bme680_cal_buf_2, |
261 | val_count: sizeof(data->bme680_cal_buf_2)); |
262 | if (ret < 0) { |
263 | dev_err(dev, "failed to read 2nd set of calib data;\n"); |
264 | return ret; |
265 | } |
266 | |
267 | tmp_lsb = data->bme680_cal_buf_2[H1_LSB]; |
268 | tmp_msb = data->bme680_cal_buf_2[H1_LSB + 1]; |
269 | calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) | |
270 | (tmp_lsb & BME680_BIT_H1_DATA_MASK); |
271 | |
272 | tmp_msb = data->bme680_cal_buf_2[H2_MSB]; |
273 | tmp_lsb = data->bme680_cal_buf_2[H2_MSB + 1]; |
274 | calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) | |
275 | (tmp_lsb >> BME680_HUM_REG_SHIFT_VAL); |
276 | |
277 | calib->par_h3 = data->bme680_cal_buf_2[H3]; |
278 | calib->par_h4 = data->bme680_cal_buf_2[H4]; |
279 | calib->par_h5 = data->bme680_cal_buf_2[H5]; |
280 | calib->par_h6 = data->bme680_cal_buf_2[H6]; |
281 | calib->par_h7 = data->bme680_cal_buf_2[H7]; |
282 | calib->par_t1 = get_unaligned_le16(p: &data->bme680_cal_buf_2[T1_LSB]); |
283 | calib->par_gh2 = get_unaligned_le16(p: &data->bme680_cal_buf_2[GH2_LSB]); |
284 | calib->par_gh1 = data->bme680_cal_buf_2[GH1]; |
285 | calib->par_gh3 = data->bme680_cal_buf_2[GH3]; |
286 | |
287 | ret = regmap_bulk_read(map: data->regmap, BME680_REG_RES_HEAT_VAL, |
288 | val: data->bme680_cal_buf_3, |
289 | val_count: sizeof(data->bme680_cal_buf_3)); |
290 | if (ret < 0) { |
291 | dev_err(dev, "failed to read 3rd set of calib data;\n"); |
292 | return ret; |
293 | } |
294 | |
295 | calib->res_heat_val = data->bme680_cal_buf_3[RES_HEAT_VAL]; |
296 | |
297 | calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK, |
298 | data->bme680_cal_buf_3[RES_HEAT_RANGE]); |
299 | |
300 | calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK, |
301 | data->bme680_cal_buf_3[RANGE_SW_ERR]); |
302 | |
303 | return 0; |
304 | } |
305 | |
306 | static int bme680_read_temp_adc(struct bme680_data *data, u32 *adc_temp) |
307 | { |
308 | struct device *dev = regmap_get_device(map: data->regmap); |
309 | u32 value_temp; |
310 | int ret; |
311 | |
312 | ret = regmap_bulk_read(map: data->regmap, BME680_REG_TEMP_MSB, |
313 | val: data->buf, BME680_TEMP_NUM_BYTES); |
314 | if (ret < 0) { |
315 | dev_err(dev, "failed to read temperature\n"); |
316 | return ret; |
317 | } |
318 | |
319 | value_temp = FIELD_GET(BME680_MEAS_TRIM_MASK, |
320 | get_unaligned_be24(data->buf)); |
321 | if (value_temp == BME680_MEAS_SKIPPED) { |
322 | /* reading was skipped */ |
323 | dev_err(dev, "reading temperature skipped\n"); |
324 | return -EINVAL; |
325 | } |
326 | *adc_temp = value_temp; |
327 | |
328 | return 0; |
329 | } |
330 | |
331 | /* |
332 | * Taken from Bosch BME680 API: |
333 | * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L876 |
334 | * |
335 | * Returns temperature measurement in DegC, resolutions is 0.01 DegC. Therefore, |
336 | * output value of "3233" represents 32.33 DegC. |
337 | */ |
338 | static s32 bme680_calc_t_fine(struct bme680_data *data, u32 adc_temp) |
339 | { |
340 | struct bme680_calib *calib = &data->bme680; |
341 | s64 var1, var2, var3; |
342 | |
343 | /* If the calibration is invalid, attempt to reload it */ |
344 | if (!calib->par_t2) |
345 | bme680_read_calib(data, calib); |
346 | |
347 | var1 = ((s32)adc_temp >> 3) - ((s32)calib->par_t1 << 1); |
348 | var2 = (var1 * calib->par_t2) >> 11; |
349 | var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; |
350 | var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14; |
351 | return var2 + var3; /* t_fine = var2 + var3 */ |
352 | } |
353 | |
354 | static int bme680_get_t_fine(struct bme680_data *data, s32 *t_fine) |
355 | { |
356 | u32 adc_temp; |
357 | int ret; |
358 | |
359 | ret = bme680_read_temp_adc(data, adc_temp: &adc_temp); |
360 | if (ret) |
361 | return ret; |
362 | |
363 | *t_fine = bme680_calc_t_fine(data, adc_temp); |
364 | |
365 | return 0; |
366 | } |
367 | |
368 | static s16 bme680_compensate_temp(struct bme680_data *data, |
369 | u32 adc_temp) |
370 | { |
371 | return (bme680_calc_t_fine(data, adc_temp) * 5 + 128) / 256; |
372 | } |
373 | |
374 | static int bme680_read_press_adc(struct bme680_data *data, u32 *adc_press) |
375 | { |
376 | struct device *dev = regmap_get_device(map: data->regmap); |
377 | u32 value_press; |
378 | int ret; |
379 | |
380 | ret = regmap_bulk_read(map: data->regmap, BME680_REG_PRESS_MSB, |
381 | val: data->buf, BME680_PRESS_NUM_BYTES); |
382 | if (ret < 0) { |
383 | dev_err(dev, "failed to read pressure\n"); |
384 | return ret; |
385 | } |
386 | |
387 | value_press = FIELD_GET(BME680_MEAS_TRIM_MASK, |
388 | get_unaligned_be24(data->buf)); |
389 | if (value_press == BME680_MEAS_SKIPPED) { |
390 | /* reading was skipped */ |
391 | dev_err(dev, "reading pressure skipped\n"); |
392 | return -EINVAL; |
393 | } |
394 | *adc_press = value_press; |
395 | |
396 | return 0; |
397 | } |
398 | |
399 | /* |
400 | * Taken from Bosch BME680 API: |
401 | * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L896 |
402 | * |
403 | * Returns pressure measurement in Pa. Output value of "97356" represents |
404 | * 97356 Pa = 973.56 hPa. |
405 | */ |
406 | static u32 bme680_compensate_press(struct bme680_data *data, |
407 | u32 adc_press, s32 t_fine) |
408 | { |
409 | struct bme680_calib *calib = &data->bme680; |
410 | s32 var1, var2, var3, press_comp; |
411 | |
412 | var1 = (t_fine >> 1) - 64000; |
413 | var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2; |
414 | var2 = var2 + (var1 * calib->par_p5 << 1); |
415 | var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16); |
416 | var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * |
417 | ((s32)calib->par_p3 << 5)) >> 3) + |
418 | ((calib->par_p2 * var1) >> 1); |
419 | var1 = var1 >> 18; |
420 | var1 = ((32768 + var1) * calib->par_p1) >> 15; |
421 | press_comp = 1048576 - adc_press; |
422 | press_comp = ((press_comp - (var2 >> 12)) * 3125); |
423 | |
424 | if (press_comp >= BME680_MAX_OVERFLOW_VAL) |
425 | press_comp = ((press_comp / (u32)var1) << 1); |
426 | else |
427 | press_comp = ((press_comp << 1) / (u32)var1); |
428 | |
429 | var1 = (calib->par_p9 * (((press_comp >> 3) * |
430 | (press_comp >> 3)) >> 13)) >> 12; |
431 | var2 = ((press_comp >> 2) * calib->par_p8) >> 13; |
432 | var3 = ((press_comp >> 8) * (press_comp >> 8) * |
433 | (press_comp >> 8) * calib->par_p10) >> 17; |
434 | |
435 | press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4; |
436 | |
437 | return press_comp; |
438 | } |
439 | |
440 | static int bme680_read_humid_adc(struct bme680_data *data, u32 *adc_humidity) |
441 | { |
442 | struct device *dev = regmap_get_device(map: data->regmap); |
443 | u32 value_humidity; |
444 | int ret; |
445 | |
446 | ret = regmap_bulk_read(map: data->regmap, BME680_REG_HUMIDITY_MSB, |
447 | val: &data->be16, BME680_HUMID_NUM_BYTES); |
448 | if (ret < 0) { |
449 | dev_err(dev, "failed to read humidity\n"); |
450 | return ret; |
451 | } |
452 | |
453 | value_humidity = be16_to_cpu(data->be16); |
454 | if (value_humidity == BME680_MEAS_SKIPPED) { |
455 | /* reading was skipped */ |
456 | dev_err(dev, "reading humidity skipped\n"); |
457 | return -EINVAL; |
458 | } |
459 | *adc_humidity = value_humidity; |
460 | |
461 | return 0; |
462 | } |
463 | |
464 | /* |
465 | * Taken from Bosch BME680 API: |
466 | * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L937 |
467 | * |
468 | * Returns humidity measurement in percent, resolution is 0.001 percent. Output |
469 | * value of "43215" represents 43.215 %rH. |
470 | */ |
471 | static u32 bme680_compensate_humid(struct bme680_data *data, |
472 | u16 adc_humid, s32 t_fine) |
473 | { |
474 | struct bme680_calib *calib = &data->bme680; |
475 | s32 var1, var2, var3, var4, var5, var6, temp_scaled, calc_hum; |
476 | |
477 | temp_scaled = (t_fine * 5 + 128) >> 8; |
478 | var1 = (adc_humid - (((s32)calib->par_h1 * 16))) - |
479 | (((temp_scaled * calib->par_h3) / 100) >> 1); |
480 | var2 = (calib->par_h2 * |
481 | (((temp_scaled * calib->par_h4) / 100) + |
482 | (((temp_scaled * ((temp_scaled * calib->par_h5) / 100)) |
483 | >> 6) / 100) + (1 << 14))) >> 10; |
484 | var3 = var1 * var2; |
485 | var4 = (s32)calib->par_h6 << 7; |
486 | var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4; |
487 | var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; |
488 | var6 = (var4 * var5) >> 1; |
489 | calc_hum = (((var3 + var6) >> 10) * 1000) >> 12; |
490 | |
491 | calc_hum = clamp(calc_hum, 0, 100000); /* clamp between 0-100 %rH */ |
492 | |
493 | return calc_hum; |
494 | } |
495 | |
496 | /* |
497 | * Taken from Bosch BME680 API: |
498 | * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L973 |
499 | * |
500 | * Returns gas measurement in Ohm. Output value of "82986" represent 82986 ohms. |
501 | */ |
502 | static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc, |
503 | u8 gas_range) |
504 | { |
505 | struct bme680_calib *calib = &data->bme680; |
506 | s64 var1; |
507 | u64 var2; |
508 | s64 var3; |
509 | u32 calc_gas_res; |
510 | |
511 | /* Look up table for the possible gas range values */ |
512 | static const u32 lookup_table[16] = { |
513 | 2147483647u, 2147483647u, 2147483647u, 2147483647u, |
514 | 2147483647u, 2126008810u, 2147483647u, 2130303777u, |
515 | 2147483647u, 2147483647u, 2143188679u, 2136746228u, |
516 | 2147483647u, 2126008810u, 2147483647u, 2147483647u |
517 | }; |
518 | |
519 | var1 = ((1340LL + (5 * calib->range_sw_err)) * |
520 | (lookup_table[gas_range])) >> 16; |
521 | var2 = ((gas_res_adc << 15) - 16777216) + var1; |
522 | var3 = ((125000 << (15 - gas_range)) * var1) >> 9; |
523 | var3 += (var2 >> 1); |
524 | calc_gas_res = div64_s64(dividend: var3, divisor: (s64)var2); |
525 | |
526 | return calc_gas_res; |
527 | } |
528 | |
529 | /* |
530 | * Taken from Bosch BME680 API: |
531 | * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1002 |
532 | */ |
533 | static u8 bme680_calc_heater_res(struct bme680_data *data, u16 temp) |
534 | { |
535 | struct bme680_calib *calib = &data->bme680; |
536 | s32 var1, var2, var3, var4, var5, heatr_res_x100; |
537 | u8 heatr_res; |
538 | |
539 | if (temp > 400) /* Cap temperature */ |
540 | temp = 400; |
541 | |
542 | var1 = (((s32)BME680_AMB_TEMP * calib->par_gh3) / 1000) * 256; |
543 | var2 = (calib->par_gh1 + 784) * (((((calib->par_gh2 + 154009) * |
544 | temp * 5) / 100) |
545 | + 3276800) / 10); |
546 | var3 = var1 + (var2 / 2); |
547 | var4 = (var3 / (calib->res_heat_range + 4)); |
548 | var5 = 131 * calib->res_heat_val + 65536; |
549 | heatr_res_x100 = ((var4 / var5) - 250) * 34; |
550 | heatr_res = DIV_ROUND_CLOSEST(heatr_res_x100, 100); |
551 | |
552 | return heatr_res; |
553 | } |
554 | |
555 | /* |
556 | * Taken from Bosch BME680 API: |
557 | * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1188 |
558 | */ |
559 | static u8 bme680_calc_heater_dur(u16 dur) |
560 | { |
561 | u8 durval, factor = 0; |
562 | |
563 | if (dur >= 0xfc0) { |
564 | durval = 0xff; /* Max duration */ |
565 | } else { |
566 | while (dur > 0x3F) { |
567 | dur = dur / 4; |
568 | factor += 1; |
569 | } |
570 | durval = dur + (factor * 64); |
571 | } |
572 | |
573 | return durval; |
574 | } |
575 | |
576 | /* Taken from datasheet, section 5.3.3 */ |
577 | static u8 bme680_calc_heater_preheat_current(u8 curr) |
578 | { |
579 | return 8 * curr - 1; |
580 | } |
581 | |
582 | static int bme680_set_mode(struct bme680_data *data, enum bme680_op_mode mode) |
583 | { |
584 | struct device *dev = regmap_get_device(map: data->regmap); |
585 | int ret; |
586 | |
587 | ret = regmap_write_bits(map: data->regmap, BME680_REG_CTRL_MEAS, |
588 | BME680_MODE_MASK, val: mode); |
589 | if (ret < 0) { |
590 | dev_err(dev, "failed to set ctrl_meas register\n"); |
591 | return ret; |
592 | } |
593 | |
594 | return ret; |
595 | } |
596 | |
597 | static u8 bme680_oversampling_to_reg(u8 val) |
598 | { |
599 | return ilog2(val) + 1; |
600 | } |
601 | |
602 | /* |
603 | * Taken from Bosch BME680 API: |
604 | * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 |
605 | */ |
606 | static int bme680_wait_for_eoc(struct bme680_data *data) |
607 | { |
608 | struct device *dev = regmap_get_device(map: data->regmap); |
609 | int ret; |
610 | /* |
611 | * (Sum of oversampling ratios * time per oversampling) + |
612 | * TPH measurement + gas measurement + wait transition from forced mode |
613 | * + heater duration |
614 | */ |
615 | int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press + |
616 | data->oversampling_humid) * 1936) + (477 * 4) + |
617 | (477 * 5) + 1000 + (data->heater_dur * 1000); |
618 | |
619 | fsleep(usecs: wait_eoc_us); |
620 | |
621 | ret = regmap_read(map: data->regmap, BME680_REG_MEAS_STAT_0, val: &data->check); |
622 | if (ret) { |
623 | dev_err(dev, "failed to read measurement status register.\n"); |
624 | return ret; |
625 | } |
626 | if (data->check & BME680_MEAS_BIT) { |
627 | dev_err(dev, "Device measurement cycle incomplete.\n"); |
628 | return -EBUSY; |
629 | } |
630 | if (!(data->check & BME680_NEW_DATA_BIT)) { |
631 | dev_err(dev, "No new data available from the device.\n"); |
632 | return -ENODATA; |
633 | } |
634 | |
635 | return 0; |
636 | } |
637 | |
638 | static int bme680_chip_config(struct bme680_data *data) |
639 | { |
640 | struct device *dev = regmap_get_device(map: data->regmap); |
641 | int ret; |
642 | u8 osrs; |
643 | |
644 | osrs = FIELD_PREP(BME680_OSRS_HUMIDITY_MASK, |
645 | bme680_oversampling_to_reg(data->oversampling_humid)); |
646 | /* |
647 | * Highly recommended to set oversampling of humidity before |
648 | * temperature/pressure oversampling. |
649 | */ |
650 | ret = regmap_update_bits(map: data->regmap, BME680_REG_CTRL_HUMIDITY, |
651 | BME680_OSRS_HUMIDITY_MASK, val: osrs); |
652 | if (ret < 0) { |
653 | dev_err(dev, "failed to write ctrl_hum register\n"); |
654 | return ret; |
655 | } |
656 | |
657 | /* IIR filter settings */ |
658 | ret = regmap_update_bits(map: data->regmap, BME680_REG_CONFIG, |
659 | BME680_FILTER_MASK, BME680_FILTER_COEFF_VAL); |
660 | if (ret < 0) { |
661 | dev_err(dev, "failed to write config register\n"); |
662 | return ret; |
663 | } |
664 | |
665 | osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK, |
666 | bme680_oversampling_to_reg(data->oversampling_temp)) | |
667 | FIELD_PREP(BME680_OSRS_PRESS_MASK, |
668 | bme680_oversampling_to_reg(data->oversampling_press)); |
669 | ret = regmap_write_bits(map: data->regmap, BME680_REG_CTRL_MEAS, |
670 | BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK, |
671 | val: osrs); |
672 | if (ret < 0) { |
673 | dev_err(dev, "failed to write ctrl_meas register\n"); |
674 | return ret; |
675 | } |
676 | |
677 | return 0; |
678 | } |
679 | |
680 | static int bme680_preheat_curr_config(struct bme680_data *data, u8 val) |
681 | { |
682 | struct device *dev = regmap_get_device(map: data->regmap); |
683 | u8 heatr_curr; |
684 | int ret; |
685 | |
686 | heatr_curr = bme680_calc_heater_preheat_current(curr: val); |
687 | ret = regmap_write(map: data->regmap, BME680_REG_IDAC_HEAT_0, val: heatr_curr); |
688 | if (ret < 0) |
689 | dev_err(dev, "failed to write idac_heat_0 register\n"); |
690 | |
691 | return ret; |
692 | } |
693 | |
694 | static int bme680_gas_config(struct bme680_data *data) |
695 | { |
696 | struct device *dev = regmap_get_device(map: data->regmap); |
697 | int ret; |
698 | u8 heatr_res, heatr_dur; |
699 | |
700 | ret = bme680_set_mode(data, mode: BME680_MODE_SLEEP); |
701 | if (ret < 0) |
702 | return ret; |
703 | |
704 | heatr_res = bme680_calc_heater_res(data, temp: data->heater_temp); |
705 | |
706 | /* set target heater temperature */ |
707 | ret = regmap_write(map: data->regmap, BME680_REG_RES_HEAT_0, val: heatr_res); |
708 | if (ret < 0) { |
709 | dev_err(dev, "failed to write res_heat_0 register\n"); |
710 | return ret; |
711 | } |
712 | |
713 | heatr_dur = bme680_calc_heater_dur(dur: data->heater_dur); |
714 | |
715 | /* set target heating duration */ |
716 | ret = regmap_write(map: data->regmap, BME680_REG_GAS_WAIT_0, val: heatr_dur); |
717 | if (ret < 0) { |
718 | dev_err(dev, "failed to write gas_wait_0 register\n"); |
719 | return ret; |
720 | } |
721 | |
722 | ret = bme680_preheat_curr_config(data, val: data->preheat_curr_mA); |
723 | if (ret) |
724 | return ret; |
725 | |
726 | /* Enable the gas sensor and select heater profile set-point 0 */ |
727 | ret = regmap_update_bits(map: data->regmap, BME680_REG_CTRL_GAS_1, |
728 | BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK, |
729 | FIELD_PREP(BME680_RUN_GAS_MASK, 1) | |
730 | FIELD_PREP(BME680_NB_CONV_MASK, 0)); |
731 | if (ret < 0) |
732 | dev_err(dev, "failed to write ctrl_gas_1 register\n"); |
733 | |
734 | return ret; |
735 | } |
736 | |
737 | static int bme680_read_temp(struct bme680_data *data, s16 *comp_temp) |
738 | { |
739 | int ret; |
740 | u32 adc_temp; |
741 | |
742 | ret = bme680_read_temp_adc(data, adc_temp: &adc_temp); |
743 | if (ret) |
744 | return ret; |
745 | |
746 | *comp_temp = bme680_compensate_temp(data, adc_temp); |
747 | return 0; |
748 | } |
749 | |
750 | static int bme680_read_press(struct bme680_data *data, u32 *comp_press) |
751 | { |
752 | int ret; |
753 | u32 adc_press; |
754 | s32 t_fine; |
755 | |
756 | ret = bme680_get_t_fine(data, t_fine: &t_fine); |
757 | if (ret) |
758 | return ret; |
759 | |
760 | ret = bme680_read_press_adc(data, adc_press: &adc_press); |
761 | if (ret) |
762 | return ret; |
763 | |
764 | *comp_press = bme680_compensate_press(data, adc_press, t_fine); |
765 | return 0; |
766 | } |
767 | |
768 | static int bme680_read_humid(struct bme680_data *data, u32 *comp_humidity) |
769 | { |
770 | int ret; |
771 | u32 adc_humidity; |
772 | s32 t_fine; |
773 | |
774 | ret = bme680_get_t_fine(data, t_fine: &t_fine); |
775 | if (ret) |
776 | return ret; |
777 | |
778 | ret = bme680_read_humid_adc(data, adc_humidity: &adc_humidity); |
779 | if (ret) |
780 | return ret; |
781 | |
782 | *comp_humidity = bme680_compensate_humid(data, adc_humid: adc_humidity, t_fine); |
783 | return 0; |
784 | } |
785 | |
786 | static int bme680_read_gas(struct bme680_data *data, int *comp_gas_res) |
787 | { |
788 | struct device *dev = regmap_get_device(map: data->regmap); |
789 | int ret; |
790 | u16 adc_gas_res, gas_regs_val; |
791 | u8 gas_range; |
792 | |
793 | ret = regmap_read(map: data->regmap, BME680_REG_MEAS_STAT_0, val: &data->check); |
794 | if (data->check & BME680_GAS_MEAS_BIT) { |
795 | dev_err(dev, "gas measurement incomplete\n"); |
796 | return -EBUSY; |
797 | } |
798 | |
799 | ret = regmap_bulk_read(map: data->regmap, BME680_REG_GAS_MSB, |
800 | val: &data->be16, BME680_GAS_NUM_BYTES); |
801 | if (ret < 0) { |
802 | dev_err(dev, "failed to read gas resistance\n"); |
803 | return ret; |
804 | } |
805 | |
806 | gas_regs_val = be16_to_cpu(data->be16); |
807 | adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val); |
808 | |
809 | /* |
810 | * occurs if either the gas heating duration was insuffient |
811 | * to reach the target heater temperature or the target |
812 | * heater temperature was too high for the heater sink to |
813 | * reach. |
814 | */ |
815 | if ((gas_regs_val & BME680_GAS_STAB_BIT) == 0) { |
816 | dev_err(dev, "heater failed to reach the target temperature\n"); |
817 | return -EINVAL; |
818 | } |
819 | |
820 | gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val); |
821 | *comp_gas_res = bme680_compensate_gas(data, gas_res_adc: adc_gas_res, gas_range); |
822 | return 0; |
823 | } |
824 | |
825 | static int __bme680_read_raw(struct iio_dev *indio_dev, |
826 | struct iio_chan_spec const *chan, |
827 | int *val, int *val2, long mask) |
828 | { |
829 | struct bme680_data *data = iio_priv(indio_dev); |
830 | int chan_val, ret; |
831 | s16 temp_chan_val; |
832 | |
833 | guard(mutex)(T: &data->lock); |
834 | |
835 | ret = bme680_set_mode(data, mode: BME680_MODE_FORCED); |
836 | if (ret < 0) |
837 | return ret; |
838 | |
839 | ret = bme680_wait_for_eoc(data); |
840 | if (ret) |
841 | return ret; |
842 | |
843 | switch (mask) { |
844 | case IIO_CHAN_INFO_PROCESSED: |
845 | switch (chan->type) { |
846 | case IIO_TEMP: |
847 | ret = bme680_read_temp(data, comp_temp: &temp_chan_val); |
848 | if (ret) |
849 | return ret; |
850 | |
851 | *val = temp_chan_val * 10; |
852 | return IIO_VAL_INT; |
853 | case IIO_PRESSURE: |
854 | ret = bme680_read_press(data, comp_press: &chan_val); |
855 | if (ret) |
856 | return ret; |
857 | |
858 | *val = chan_val; |
859 | *val2 = 1000; |
860 | return IIO_VAL_FRACTIONAL; |
861 | case IIO_HUMIDITYRELATIVE: |
862 | ret = bme680_read_humid(data, comp_humidity: &chan_val); |
863 | if (ret) |
864 | return ret; |
865 | |
866 | *val = chan_val; |
867 | *val2 = 1000; |
868 | return IIO_VAL_FRACTIONAL; |
869 | case IIO_RESISTANCE: |
870 | ret = bme680_read_gas(data, comp_gas_res: &chan_val); |
871 | if (ret) |
872 | return ret; |
873 | |
874 | *val = chan_val; |
875 | return IIO_VAL_INT; |
876 | default: |
877 | return -EINVAL; |
878 | } |
879 | case IIO_CHAN_INFO_RAW: |
880 | switch (chan->type) { |
881 | case IIO_TEMP: |
882 | ret = bme680_read_temp(data, comp_temp: &temp_chan_val); |
883 | if (ret) |
884 | return ret; |
885 | |
886 | *val = temp_chan_val; |
887 | return IIO_VAL_INT; |
888 | case IIO_PRESSURE: |
889 | ret = bme680_read_press(data, comp_press: &chan_val); |
890 | if (ret) |
891 | return ret; |
892 | |
893 | *val = chan_val; |
894 | return IIO_VAL_INT; |
895 | case IIO_HUMIDITYRELATIVE: |
896 | ret = bme680_read_humid(data, comp_humidity: &chan_val); |
897 | if (ret) |
898 | return ret; |
899 | |
900 | *val = chan_val; |
901 | return IIO_VAL_INT; |
902 | default: |
903 | return -EINVAL; |
904 | } |
905 | case IIO_CHAN_INFO_SCALE: |
906 | switch (chan->type) { |
907 | case IIO_TEMP: |
908 | *val = 10; |
909 | return IIO_VAL_INT; |
910 | case IIO_PRESSURE: |
911 | *val = 1; |
912 | *val2 = 1000; |
913 | return IIO_VAL_FRACTIONAL; |
914 | case IIO_HUMIDITYRELATIVE: |
915 | *val = 1; |
916 | *val2 = 1000; |
917 | return IIO_VAL_FRACTIONAL; |
918 | default: |
919 | return -EINVAL; |
920 | } |
921 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
922 | switch (chan->type) { |
923 | case IIO_TEMP: |
924 | *val = data->oversampling_temp; |
925 | return IIO_VAL_INT; |
926 | case IIO_PRESSURE: |
927 | *val = data->oversampling_press; |
928 | return IIO_VAL_INT; |
929 | case IIO_HUMIDITYRELATIVE: |
930 | *val = data->oversampling_humid; |
931 | return IIO_VAL_INT; |
932 | default: |
933 | return -EINVAL; |
934 | } |
935 | default: |
936 | return -EINVAL; |
937 | } |
938 | } |
939 | |
940 | static int bme680_read_raw(struct iio_dev *indio_dev, |
941 | struct iio_chan_spec const *chan, |
942 | int *val, int *val2, long mask) |
943 | { |
944 | struct bme680_data *data = iio_priv(indio_dev); |
945 | struct device *dev = regmap_get_device(map: data->regmap); |
946 | int ret; |
947 | |
948 | ret = pm_runtime_resume_and_get(dev); |
949 | if (ret) |
950 | return ret; |
951 | |
952 | ret = __bme680_read_raw(indio_dev, chan, val, val2, mask); |
953 | pm_runtime_mark_last_busy(dev); |
954 | pm_runtime_put_autosuspend(dev); |
955 | |
956 | return ret; |
957 | } |
958 | |
959 | static bool bme680_is_valid_oversampling(int rate) |
960 | { |
961 | return (rate > 0 && rate <= 16 && is_power_of_2(n: rate)); |
962 | } |
963 | |
964 | static int __bme680_write_raw(struct iio_dev *indio_dev, |
965 | struct iio_chan_spec const *chan, |
966 | int val, int val2, long mask) |
967 | { |
968 | struct bme680_data *data = iio_priv(indio_dev); |
969 | |
970 | guard(mutex)(T: &data->lock); |
971 | |
972 | if (val2 != 0) |
973 | return -EINVAL; |
974 | |
975 | switch (mask) { |
976 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
977 | { |
978 | if (!bme680_is_valid_oversampling(rate: val)) |
979 | return -EINVAL; |
980 | |
981 | switch (chan->type) { |
982 | case IIO_TEMP: |
983 | data->oversampling_temp = val; |
984 | break; |
985 | case IIO_PRESSURE: |
986 | data->oversampling_press = val; |
987 | break; |
988 | case IIO_HUMIDITYRELATIVE: |
989 | data->oversampling_humid = val; |
990 | break; |
991 | default: |
992 | return -EINVAL; |
993 | } |
994 | |
995 | return bme680_chip_config(data); |
996 | } |
997 | case IIO_CHAN_INFO_PROCESSED: |
998 | { |
999 | switch (chan->type) { |
1000 | case IIO_CURRENT: |
1001 | return bme680_preheat_curr_config(data, val: (u8)val); |
1002 | default: |
1003 | return -EINVAL; |
1004 | } |
1005 | } |
1006 | default: |
1007 | return -EINVAL; |
1008 | } |
1009 | } |
1010 | |
1011 | static int bme680_write_raw(struct iio_dev *indio_dev, |
1012 | struct iio_chan_spec const *chan, |
1013 | int val, int val2, long mask) |
1014 | { |
1015 | struct bme680_data *data = iio_priv(indio_dev); |
1016 | struct device *dev = regmap_get_device(map: data->regmap); |
1017 | int ret; |
1018 | |
1019 | ret = pm_runtime_resume_and_get(dev); |
1020 | if (ret) |
1021 | return ret; |
1022 | |
1023 | ret = __bme680_write_raw(indio_dev, chan, val, val2, mask); |
1024 | pm_runtime_mark_last_busy(dev); |
1025 | pm_runtime_put_autosuspend(dev); |
1026 | |
1027 | return ret; |
1028 | } |
1029 | |
1030 | static const char bme680_oversampling_ratio_show[] = "1 2 4 8 16"; |
1031 | |
1032 | static IIO_CONST_ATTR(oversampling_ratio_available, |
1033 | bme680_oversampling_ratio_show); |
1034 | |
1035 | static struct attribute *bme680_attributes[] = { |
1036 | &iio_const_attr_oversampling_ratio_available.dev_attr.attr, |
1037 | NULL, |
1038 | }; |
1039 | |
1040 | static const struct attribute_group bme680_attribute_group = { |
1041 | .attrs = bme680_attributes, |
1042 | }; |
1043 | |
1044 | static const struct iio_info bme680_info = { |
1045 | .read_raw = &bme680_read_raw, |
1046 | .write_raw = &bme680_write_raw, |
1047 | .attrs = &bme680_attribute_group, |
1048 | }; |
1049 | |
1050 | static const unsigned long bme680_avail_scan_masks[] = { |
1051 | BIT(BME680_GAS) | BIT(BME680_HUMID) | BIT(BME680_PRESS) | BIT(BME680_TEMP), |
1052 | 0 |
1053 | }; |
1054 | |
1055 | static irqreturn_t bme680_trigger_handler(int irq, void *p) |
1056 | { |
1057 | struct iio_poll_func *pf = p; |
1058 | struct iio_dev *indio_dev = pf->indio_dev; |
1059 | struct bme680_data *data = iio_priv(indio_dev); |
1060 | struct device *dev = regmap_get_device(map: data->regmap); |
1061 | u32 adc_temp, adc_press, adc_humid; |
1062 | u16 adc_gas_res, gas_regs_val; |
1063 | u8 gas_range; |
1064 | s32 t_fine; |
1065 | int ret; |
1066 | |
1067 | guard(mutex)(T: &data->lock); |
1068 | |
1069 | ret = bme680_set_mode(data, mode: BME680_MODE_FORCED); |
1070 | if (ret < 0) |
1071 | goto out; |
1072 | |
1073 | ret = bme680_wait_for_eoc(data); |
1074 | if (ret) |
1075 | goto out; |
1076 | |
1077 | ret = regmap_bulk_read(map: data->regmap, BME680_REG_MEAS_STAT_0, |
1078 | val: data->buf, val_count: sizeof(data->buf)); |
1079 | if (ret) { |
1080 | dev_err(dev, "failed to burst read sensor data\n"); |
1081 | goto out; |
1082 | } |
1083 | if (data->buf[0] & BME680_GAS_MEAS_BIT) { |
1084 | dev_err(dev, "gas measurement incomplete\n"); |
1085 | goto out; |
1086 | } |
1087 | |
1088 | /* Temperature calculations */ |
1089 | adc_temp = FIELD_GET(BME680_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[5])); |
1090 | if (adc_temp == BME680_MEAS_SKIPPED) { |
1091 | dev_err(dev, "reading temperature skipped\n"); |
1092 | goto out; |
1093 | } |
1094 | data->scan.chan[0] = bme680_compensate_temp(data, adc_temp); |
1095 | t_fine = bme680_calc_t_fine(data, adc_temp); |
1096 | |
1097 | /* Pressure calculations */ |
1098 | adc_press = FIELD_GET(BME680_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[2])); |
1099 | if (adc_press == BME680_MEAS_SKIPPED) { |
1100 | dev_err(dev, "reading pressure skipped\n"); |
1101 | goto out; |
1102 | } |
1103 | data->scan.chan[1] = bme680_compensate_press(data, adc_press, t_fine); |
1104 | |
1105 | /* Humidity calculations */ |
1106 | adc_humid = get_unaligned_be16(p: &data->buf[8]); |
1107 | if (adc_humid == BME680_MEAS_SKIPPED) { |
1108 | dev_err(dev, "reading humidity skipped\n"); |
1109 | goto out; |
1110 | } |
1111 | data->scan.chan[2] = bme680_compensate_humid(data, adc_humid, t_fine); |
1112 | |
1113 | /* Gas calculations */ |
1114 | gas_regs_val = get_unaligned_be16(p: &data->buf[13]); |
1115 | adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val); |
1116 | if ((gas_regs_val & BME680_GAS_STAB_BIT) == 0) { |
1117 | dev_err(dev, "heater failed to reach the target temperature\n"); |
1118 | goto out; |
1119 | } |
1120 | gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val); |
1121 | data->scan.chan[3] = bme680_compensate_gas(data, gas_res_adc: adc_gas_res, gas_range); |
1122 | |
1123 | iio_push_to_buffers_with_ts(indio_dev, data: &data->scan, data_total_len: sizeof(data->scan), |
1124 | timestamp: iio_get_time_ns(indio_dev)); |
1125 | out: |
1126 | iio_trigger_notify_done(trig: indio_dev->trig); |
1127 | return IRQ_HANDLED; |
1128 | } |
1129 | |
1130 | static int bme680_buffer_preenable(struct iio_dev *indio_dev) |
1131 | { |
1132 | struct bme680_data *data = iio_priv(indio_dev); |
1133 | struct device *dev = regmap_get_device(map: data->regmap); |
1134 | |
1135 | return pm_runtime_resume_and_get(dev); |
1136 | } |
1137 | |
1138 | static int bme680_buffer_postdisable(struct iio_dev *indio_dev) |
1139 | { |
1140 | struct bme680_data *data = iio_priv(indio_dev); |
1141 | struct device *dev = regmap_get_device(map: data->regmap); |
1142 | |
1143 | pm_runtime_mark_last_busy(dev); |
1144 | pm_runtime_put_autosuspend(dev); |
1145 | return 0; |
1146 | } |
1147 | |
1148 | static const struct iio_buffer_setup_ops bme680_buffer_setup_ops = { |
1149 | .preenable = bme680_buffer_preenable, |
1150 | .postdisable = bme680_buffer_postdisable, |
1151 | }; |
1152 | |
1153 | int bme680_core_probe(struct device *dev, struct regmap *regmap, |
1154 | const char *name) |
1155 | { |
1156 | struct iio_dev *indio_dev; |
1157 | struct bme680_data *data; |
1158 | int ret; |
1159 | |
1160 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*data)); |
1161 | if (!indio_dev) |
1162 | return -ENOMEM; |
1163 | |
1164 | data = iio_priv(indio_dev); |
1165 | mutex_init(&data->lock); |
1166 | dev_set_drvdata(dev, data: indio_dev); |
1167 | data->regmap = regmap; |
1168 | indio_dev->name = name; |
1169 | indio_dev->channels = bme680_channels; |
1170 | indio_dev->num_channels = ARRAY_SIZE(bme680_channels); |
1171 | indio_dev->available_scan_masks = bme680_avail_scan_masks; |
1172 | indio_dev->info = &bme680_info; |
1173 | indio_dev->modes = INDIO_DIRECT_MODE; |
1174 | |
1175 | /* default values for the sensor */ |
1176 | data->oversampling_humid = 2; /* 2X oversampling rate */ |
1177 | data->oversampling_press = 4; /* 4X oversampling rate */ |
1178 | data->oversampling_temp = 8; /* 8X oversampling rate */ |
1179 | data->heater_temp = 320; /* degree Celsius */ |
1180 | data->heater_dur = 150; /* milliseconds */ |
1181 | data->preheat_curr_mA = 0; |
1182 | |
1183 | ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(bme680_supply_names), |
1184 | id: bme680_supply_names); |
1185 | if (ret) |
1186 | return dev_err_probe(dev, err: ret, |
1187 | fmt: "failed to get and enable supplies.\n"); |
1188 | |
1189 | fsleep(BME680_STARTUP_TIME_US); |
1190 | |
1191 | ret = regmap_write(map: regmap, BME680_REG_SOFT_RESET, BME680_CMD_SOFTRESET); |
1192 | if (ret < 0) |
1193 | return dev_err_probe(dev, err: ret, fmt: "Failed to reset chip\n"); |
1194 | |
1195 | fsleep(BME680_STARTUP_TIME_US); |
1196 | |
1197 | ret = regmap_read(map: regmap, BME680_REG_CHIP_ID, val: &data->check); |
1198 | if (ret < 0) |
1199 | return dev_err_probe(dev, err: ret, fmt: "Error reading chip ID\n"); |
1200 | |
1201 | if (data->check != BME680_CHIP_ID_VAL) { |
1202 | dev_err(dev, "Wrong chip ID, got %x expected %x\n", |
1203 | data->check, BME680_CHIP_ID_VAL); |
1204 | return -ENODEV; |
1205 | } |
1206 | |
1207 | ret = bme680_read_calib(data, calib: &data->bme680); |
1208 | if (ret < 0) { |
1209 | return dev_err_probe(dev, err: ret, |
1210 | fmt: "failed to read calibration coefficients at probe\n"); |
1211 | } |
1212 | |
1213 | ret = bme680_chip_config(data); |
1214 | if (ret < 0) |
1215 | return dev_err_probe(dev, err: ret, |
1216 | fmt: "failed to set chip_config data\n"); |
1217 | |
1218 | ret = bme680_gas_config(data); |
1219 | if (ret < 0) |
1220 | return dev_err_probe(dev, err: ret, |
1221 | fmt: "failed to set gas config data\n"); |
1222 | |
1223 | ret = devm_iio_triggered_buffer_setup(dev, indio_dev, |
1224 | iio_pollfunc_store_time, |
1225 | bme680_trigger_handler, |
1226 | &bme680_buffer_setup_ops); |
1227 | if (ret) |
1228 | return dev_err_probe(dev, err: ret, |
1229 | fmt: "iio triggered buffer setup failed\n"); |
1230 | |
1231 | /* Enable runtime PM */ |
1232 | pm_runtime_set_autosuspend_delay(dev, BME680_STARTUP_TIME_US); |
1233 | pm_runtime_use_autosuspend(dev); |
1234 | pm_runtime_set_active(dev); |
1235 | ret = devm_pm_runtime_enable(dev); |
1236 | if (ret) |
1237 | return ret; |
1238 | |
1239 | return devm_iio_device_register(dev, indio_dev); |
1240 | } |
1241 | EXPORT_SYMBOL_NS_GPL(bme680_core_probe, "IIO_BME680"); |
1242 | |
1243 | static int bme680_runtime_suspend(struct device *dev) |
1244 | { |
1245 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1246 | struct bme680_data *data = iio_priv(indio_dev); |
1247 | |
1248 | return bme680_set_mode(data, mode: BME680_MODE_SLEEP); |
1249 | } |
1250 | |
1251 | static int bme680_runtime_resume(struct device *dev) |
1252 | { |
1253 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1254 | struct bme680_data *data = iio_priv(indio_dev); |
1255 | int ret; |
1256 | |
1257 | ret = bme680_chip_config(data); |
1258 | if (ret) |
1259 | return ret; |
1260 | |
1261 | return bme680_gas_config(data); |
1262 | } |
1263 | |
1264 | EXPORT_RUNTIME_DEV_PM_OPS(bme680_dev_pm_ops, bme680_runtime_suspend, |
1265 | bme680_runtime_resume, NULL); |
1266 | |
1267 | MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>"); |
1268 | MODULE_DESCRIPTION("Bosch BME680 Driver"); |
1269 | MODULE_LICENSE("GPL v2"); |
1270 |
Definitions
- bme680_calib
- bme680_op_mode
- bme680_scan
- bme680_supply_names
- bme680_data
- bme680_volatile_ranges
- bme680_volatile_table
- bme680_regmap_config
- bme680_channels
- bme680_read_calib
- bme680_read_temp_adc
- bme680_calc_t_fine
- bme680_get_t_fine
- bme680_compensate_temp
- bme680_read_press_adc
- bme680_compensate_press
- bme680_read_humid_adc
- bme680_compensate_humid
- bme680_compensate_gas
- bme680_calc_heater_res
- bme680_calc_heater_dur
- bme680_calc_heater_preheat_current
- bme680_set_mode
- bme680_oversampling_to_reg
- bme680_wait_for_eoc
- bme680_chip_config
- bme680_preheat_curr_config
- bme680_gas_config
- bme680_read_temp
- bme680_read_press
- bme680_read_humid
- bme680_read_gas
- __bme680_read_raw
- bme680_read_raw
- bme680_is_valid_oversampling
- __bme680_write_raw
- bme680_write_raw
- bme680_oversampling_ratio_show
- bme680_attributes
- bme680_attribute_group
- bme680_info
- bme680_avail_scan_masks
- bme680_trigger_handler
- bme680_buffer_preenable
- bme680_buffer_postdisable
- bme680_buffer_setup_ops
- bme680_core_probe
- bme680_runtime_suspend
- bme680_runtime_resume
Improve your Profiling and Debugging skills
Find out more