summaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorHimanshu Jha <himanshujha199640@gmail.com>2018-07-26 07:35:10 -0400
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2018-07-28 06:38:46 -0400
commit1b3bd8592780c87c5eddabbe98666b086bbaee36 (patch)
tree6880cfcd7bf89e6f0376986dd9c04383ac17000b /drivers/iio
parent6431975789fc3c480cb6344256f72d85889df3b2 (diff)
iio: chemical: Add support for Bosch BME680 sensor
Bosch BME680 is a 4-in-1 sensor with temperature, pressure, humidity and gas sensing capability. It supports both I2C and SPI communication protocol for effective data communication. The device supports two modes: 1. Sleep mode 2. Forced mode The measurements only takes place when forced mode is triggered and a single TPHG cycle is performed by the sensor. The sensor automatically goes to sleep after afterwards. The device has various calibration constants/parameters programmed into devices' non-volatile memory(NVM) during production and can't be altered by the user. These constants are used in the compensation functions to get the required compensated readings along with the raw data. The compensation functions/algorithms are provided by Bosch Sensortec GmbH via their API[1]. As these don't change during the measurement cycle, therefore we read and store them at the probe. The default configs supplied by Bosch are also set at probe. 0-day tested with build success. GSoC-2018: https://summerofcode.withgoogle.com/projects/#6691473790074880 Mentor: Daniel Baluta [1] https://github.com/BoschSensortec/BME680_driver Datasheet: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf Note from Jonathan: The compensation functions are 'interesting' and could do with a tidy up in future. However, they work so we can leave that for another day. Cc: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/chemical/Kconfig23
-rw-r--r--drivers/iio/chemical/Makefile3
-rw-r--r--drivers/iio/chemical/bme680.h96
-rw-r--r--drivers/iio/chemical/bme680_core.c959
-rw-r--r--drivers/iio/chemical/bme680_i2c.c85
-rw-r--r--drivers/iio/chemical/bme680_spi.c125
6 files changed, 1291 insertions, 0 deletions
diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
index 5cb5be7612b4..b8e005be4f87 100644
--- a/drivers/iio/chemical/Kconfig
+++ b/drivers/iio/chemical/Kconfig
@@ -21,6 +21,29 @@ config ATLAS_PH_SENSOR
21 To compile this driver as module, choose M here: the 21 To compile this driver as module, choose M here: the
22 module will be called atlas-ph-sensor. 22 module will be called atlas-ph-sensor.
23 23
24config BME680
25 tristate "Bosch Sensortec BME680 sensor driver"
26 depends on (I2C || SPI)
27 select REGMAP
28 select BME680_I2C if I2C
29 select BME680_SPI if SPI
30 help
31 Say yes here to build support for Bosch Sensortec BME680 sensor with
32 temperature, pressure, humidity and gas sensing capability.
33
34 This driver can also be built as a module. If so, the module for I2C
35 would be called bme680_i2c and bme680_spi for SPI support.
36
37config BME680_I2C
38 tristate
39 depends on I2C && BME680
40 select REGMAP_I2C
41
42config BME680_SPI
43 tristate
44 depends on SPI && BME680
45 select REGMAP_SPI
46
24config CCS811 47config CCS811
25 tristate "AMS CCS811 VOC sensor" 48 tristate "AMS CCS811 VOC sensor"
26 depends on I2C 49 depends on I2C
diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile
index a629b29d1e0b..2f4c4ba4d781 100644
--- a/drivers/iio/chemical/Makefile
+++ b/drivers/iio/chemical/Makefile
@@ -4,6 +4,9 @@
4 4
5# When adding new entries keep the list in alphabetical order 5# When adding new entries keep the list in alphabetical order
6obj-$(CONFIG_ATLAS_PH_SENSOR) += atlas-ph-sensor.o 6obj-$(CONFIG_ATLAS_PH_SENSOR) += atlas-ph-sensor.o
7obj-$(CONFIG_BME680) += bme680_core.o
8obj-$(CONFIG_BME680_I2C) += bme680_i2c.o
9obj-$(CONFIG_BME680_SPI) += bme680_spi.o
7obj-$(CONFIG_CCS811) += ccs811.o 10obj-$(CONFIG_CCS811) += ccs811.o
8obj-$(CONFIG_IAQCORE) += ams-iaq-core.o 11obj-$(CONFIG_IAQCORE) += ams-iaq-core.o
9obj-$(CONFIG_VZ89X) += vz89x.o 12obj-$(CONFIG_VZ89X) += vz89x.o
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
new file mode 100644
index 000000000000..e049323f209a
--- /dev/null
+++ b/drivers/iio/chemical/bme680.h
@@ -0,0 +1,96 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef BME680_H_
3#define BME680_H_
4
5#define BME680_REG_CHIP_I2C_ID 0xD0
6#define BME680_REG_CHIP_SPI_ID 0x50
7#define BME680_CHIP_ID_VAL 0x61
8#define BME680_REG_SOFT_RESET_I2C 0xE0
9#define BME680_REG_SOFT_RESET_SPI 0x60
10#define BME680_CMD_SOFTRESET 0xB6
11#define BME680_REG_STATUS 0x73
12#define BME680_SPI_MEM_PAGE_BIT BIT(4)
13#define BME680_SPI_MEM_PAGE_1_VAL 1
14
15#define BME680_REG_TEMP_MSB 0x22
16#define BME680_REG_PRESS_MSB 0x1F
17#define BM6880_REG_HUMIDITY_MSB 0x25
18#define BME680_REG_GAS_MSB 0x2A
19#define BME680_REG_GAS_R_LSB 0x2B
20#define BME680_GAS_STAB_BIT BIT(4)
21
22#define BME680_REG_CTRL_HUMIDITY 0x72
23#define BME680_OSRS_HUMIDITY_MASK GENMASK(2, 0)
24
25#define BME680_REG_CTRL_MEAS 0x74
26#define BME680_OSRS_TEMP_MASK GENMASK(7, 5)
27#define BME680_OSRS_PRESS_MASK GENMASK(4, 2)
28#define BME680_MODE_MASK GENMASK(1, 0)
29
30#define BME680_MODE_FORCED 1
31#define BME680_MODE_SLEEP 0
32
33#define BME680_REG_CONFIG 0x75
34#define BME680_FILTER_MASK GENMASK(4, 2)
35#define BME680_FILTER_COEFF_VAL BIT(1)
36
37/* TEMP/PRESS/HUMID reading skipped */
38#define BME680_MEAS_SKIPPED 0x8000
39
40#define BME680_MAX_OVERFLOW_VAL 0x40000000
41#define BME680_HUM_REG_SHIFT_VAL 4
42#define BME680_BIT_H1_DATA_MSK 0x0F
43
44#define BME680_REG_RES_HEAT_RANGE 0x02
45#define BME680_RHRANGE_MSK 0x30
46#define BME680_REG_RES_HEAT_VAL 0x00
47#define BME680_REG_RANGE_SW_ERR 0x04
48#define BME680_RSERROR_MSK 0xF0
49#define BME680_REG_RES_HEAT_0 0x5A
50#define BME680_REG_GAS_WAIT_0 0x64
51#define BME680_GAS_RANGE_MASK 0x0F
52#define BME680_ADC_GAS_RES_SHIFT 6
53#define BME680_AMB_TEMP 25
54
55#define BME680_REG_CTRL_GAS_1 0x71
56#define BME680_RUN_GAS_MASK BIT(4)
57#define BME680_NB_CONV_MASK GENMASK(3, 0)
58#define BME680_RUN_GAS_EN_BIT BIT(4)
59#define BME680_NB_CONV_0_VAL 0
60
61#define BME680_REG_MEAS_STAT_0 0x1D
62#define BME680_GAS_MEAS_BIT BIT(6)
63
64/* Calibration Parameters */
65#define BME680_T2_LSB_REG 0x8A
66#define BME680_T3_REG 0x8C
67#define BME680_P1_LSB_REG 0x8E
68#define BME680_P2_LSB_REG 0x90
69#define BME680_P3_REG 0x92
70#define BME680_P4_LSB_REG 0x94
71#define BME680_P5_LSB_REG 0x96
72#define BME680_P7_REG 0x98
73#define BME680_P6_REG 0x99
74#define BME680_P8_LSB_REG 0x9C
75#define BME680_P9_LSB_REG 0x9E
76#define BME680_P10_REG 0xA0
77#define BME680_H2_LSB_REG 0xE2
78#define BME680_H2_MSB_REG 0xE1
79#define BME680_H1_MSB_REG 0xE3
80#define BME680_H1_LSB_REG 0xE2
81#define BME680_H3_REG 0xE4
82#define BME680_H4_REG 0xE5
83#define BME680_H5_REG 0xE6
84#define BME680_H6_REG 0xE7
85#define BME680_H7_REG 0xE8
86#define BME680_T1_LSB_REG 0xE9
87#define BME680_GH2_LSB_REG 0xEB
88#define BME680_GH1_REG 0xED
89#define BME680_GH3_REG 0xEE
90
91extern const struct regmap_config bme680_regmap_config;
92
93int bme680_core_probe(struct device *dev, struct regmap *regmap,
94 const char *name);
95
96#endif /* BME680_H_ */
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
new file mode 100644
index 000000000000..7d9bb62baa3f
--- /dev/null
+++ b/drivers/iio/chemical/bme680_core.c
@@ -0,0 +1,959 @@
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/acpi.h>
12#include <linux/bitfield.h>
13#include <linux/device.h>
14#include <linux/module.h>
15#include <linux/log2.h>
16#include <linux/regmap.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
19
20#include "bme680.h"
21
22struct bme680_calib {
23 u16 par_t1;
24 s16 par_t2;
25 s8 par_t3;
26 u16 par_p1;
27 s16 par_p2;
28 s8 par_p3;
29 s16 par_p4;
30 s16 par_p5;
31 s8 par_p6;
32 s8 par_p7;
33 s16 par_p8;
34 s16 par_p9;
35 u8 par_p10;
36 u16 par_h1;
37 u16 par_h2;
38 s8 par_h3;
39 s8 par_h4;
40 s8 par_h5;
41 s8 par_h6;
42 s8 par_h7;
43 s8 par_gh1;
44 s16 par_gh2;
45 s8 par_gh3;
46 u8 res_heat_range;
47 s8 res_heat_val;
48 s8 range_sw_err;
49};
50
51struct bme680_data {
52 struct regmap *regmap;
53 struct bme680_calib bme680;
54 u8 oversampling_temp;
55 u8 oversampling_press;
56 u8 oversampling_humid;
57 u16 heater_dur;
58 u16 heater_temp;
59 /*
60 * Carryover value from temperature conversion, used in pressure
61 * and humidity compensation calculations.
62 */
63 s32 t_fine;
64};
65
66const struct regmap_config bme680_regmap_config = {
67 .reg_bits = 8,
68 .val_bits = 8,
69};
70EXPORT_SYMBOL(bme680_regmap_config);
71
72static const struct iio_chan_spec bme680_channels[] = {
73 {
74 .type = IIO_TEMP,
75 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
76 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
77 },
78 {
79 .type = IIO_PRESSURE,
80 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
81 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
82 },
83 {
84 .type = IIO_HUMIDITYRELATIVE,
85 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
86 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
87 },
88 {
89 .type = IIO_RESISTANCE,
90 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
91 },
92};
93
94static const int bme680_oversampling_avail[] = { 1, 2, 4, 8, 16 };
95
96static int bme680_read_calib(struct bme680_data *data,
97 struct bme680_calib *calib)
98{
99 struct device *dev = regmap_get_device(data->regmap);
100 unsigned int tmp, tmp_msb, tmp_lsb;
101 int ret;
102 __le16 buf;
103
104 /* Temperature related coefficients */
105 ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG,
106 (u8 *) &buf, 2);
107 if (ret < 0) {
108 dev_err(dev, "failed to read BME680_T1_LSB_REG\n");
109 return ret;
110 }
111 calib->par_t1 = le16_to_cpu(buf);
112
113 ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG,
114 (u8 *) &buf, 2);
115 if (ret < 0) {
116 dev_err(dev, "failed to read BME680_T2_LSB_REG\n");
117 return ret;
118 }
119 calib->par_t2 = le16_to_cpu(buf);
120
121 ret = regmap_read(data->regmap, BME680_T3_REG, &tmp);
122 if (ret < 0) {
123 dev_err(dev, "failed to read BME680_T3_REG\n");
124 return ret;
125 }
126 calib->par_t3 = tmp;
127
128 /* Pressure related coefficients */
129 ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG,
130 (u8 *) &buf, 2);
131 if (ret < 0) {
132 dev_err(dev, "failed to read BME680_P1_LSB_REG\n");
133 return ret;
134 }
135 calib->par_p1 = le16_to_cpu(buf);
136
137 ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG,
138 (u8 *) &buf, 2);
139 if (ret < 0) {
140 dev_err(dev, "failed to read BME680_P2_LSB_REG\n");
141 return ret;
142 }
143 calib->par_p2 = le16_to_cpu(buf);
144
145 ret = regmap_read(data->regmap, BME680_P3_REG, &tmp);
146 if (ret < 0) {
147 dev_err(dev, "failed to read BME680_P3_REG\n");
148 return ret;
149 }
150 calib->par_p3 = tmp;
151
152 ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG,
153 (u8 *) &buf, 2);
154 if (ret < 0) {
155 dev_err(dev, "failed to read BME680_P4_LSB_REG\n");
156 return ret;
157 }
158 calib->par_p4 = le16_to_cpu(buf);
159
160 ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG,
161 (u8 *) &buf, 2);
162 if (ret < 0) {
163 dev_err(dev, "failed to read BME680_P5_LSB_REG\n");
164 return ret;
165 }
166 calib->par_p5 = le16_to_cpu(buf);
167
168 ret = regmap_read(data->regmap, BME680_P6_REG, &tmp);
169 if (ret < 0) {
170 dev_err(dev, "failed to read BME680_P6_REG\n");
171 return ret;
172 }
173 calib->par_p6 = tmp;
174
175 ret = regmap_read(data->regmap, BME680_P7_REG, &tmp);
176 if (ret < 0) {
177 dev_err(dev, "failed to read BME680_P7_REG\n");
178 return ret;
179 }
180 calib->par_p7 = tmp;
181
182 ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG,
183 (u8 *) &buf, 2);
184 if (ret < 0) {
185 dev_err(dev, "failed to read BME680_P8_LSB_REG\n");
186 return ret;
187 }
188 calib->par_p8 = le16_to_cpu(buf);
189
190 ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG,
191 (u8 *) &buf, 2);
192 if (ret < 0) {
193 dev_err(dev, "failed to read BME680_P9_LSB_REG\n");
194 return ret;
195 }
196 calib->par_p9 = le16_to_cpu(buf);
197
198 ret = regmap_read(data->regmap, BME680_P10_REG, &tmp);
199 if (ret < 0) {
200 dev_err(dev, "failed to read BME680_P10_REG\n");
201 return ret;
202 }
203 calib->par_p10 = tmp;
204
205 /* Humidity related coefficients */
206 ret = regmap_read(data->regmap, BME680_H1_MSB_REG, &tmp_msb);
207 if (ret < 0) {
208 dev_err(dev, "failed to read BME680_H1_MSB_REG\n");
209 return ret;
210 }
211
212 ret = regmap_read(data->regmap, BME680_H1_LSB_REG, &tmp_lsb);
213 if (ret < 0) {
214 dev_err(dev, "failed to read BME680_H1_LSB_REG\n");
215 return ret;
216 }
217
218 calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
219 (tmp_lsb & BME680_BIT_H1_DATA_MSK);
220
221 ret = regmap_read(data->regmap, BME680_H2_MSB_REG, &tmp_msb);
222 if (ret < 0) {
223 dev_err(dev, "failed to read BME680_H2_MSB_REG\n");
224 return ret;
225 }
226
227 ret = regmap_read(data->regmap, BME680_H2_LSB_REG, &tmp_lsb);
228 if (ret < 0) {
229 dev_err(dev, "failed to read BME680_H2_LSB_REG\n");
230 return ret;
231 }
232
233 calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
234 (tmp_lsb >> BME680_HUM_REG_SHIFT_VAL);
235
236 ret = regmap_read(data->regmap, BME680_H3_REG, &tmp);
237 if (ret < 0) {
238 dev_err(dev, "failed to read BME680_H3_REG\n");
239 return ret;
240 }
241 calib->par_h3 = tmp;
242
243 ret = regmap_read(data->regmap, BME680_H4_REG, &tmp);
244 if (ret < 0) {
245 dev_err(dev, "failed to read BME680_H4_REG\n");
246 return ret;
247 }
248 calib->par_h4 = tmp;
249
250 ret = regmap_read(data->regmap, BME680_H5_REG, &tmp);
251 if (ret < 0) {
252 dev_err(dev, "failed to read BME680_H5_REG\n");
253 return ret;
254 }
255 calib->par_h5 = tmp;
256
257 ret = regmap_read(data->regmap, BME680_H6_REG, &tmp);
258 if (ret < 0) {
259 dev_err(dev, "failed to read BME680_H6_REG\n");
260 return ret;
261 }
262 calib->par_h6 = tmp;
263
264 ret = regmap_read(data->regmap, BME680_H7_REG, &tmp);
265 if (ret < 0) {
266 dev_err(dev, "failed to read BME680_H7_REG\n");
267 return ret;
268 }
269 calib->par_h7 = tmp;
270
271 /* Gas heater related coefficients */
272 ret = regmap_read(data->regmap, BME680_GH1_REG, &tmp);
273 if (ret < 0) {
274 dev_err(dev, "failed to read BME680_GH1_REG\n");
275 return ret;
276 }
277 calib->par_gh1 = tmp;
278
279 ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG,
280 (u8 *) &buf, 2);
281 if (ret < 0) {
282 dev_err(dev, "failed to read BME680_GH2_LSB_REG\n");
283 return ret;
284 }
285 calib->par_gh2 = le16_to_cpu(buf);
286
287 ret = regmap_read(data->regmap, BME680_GH3_REG, &tmp);
288 if (ret < 0) {
289 dev_err(dev, "failed to read BME680_GH3_REG\n");
290 return ret;
291 }
292 calib->par_gh3 = tmp;
293
294 /* Other coefficients */
295 ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_RANGE, &tmp);
296 if (ret < 0) {
297 dev_err(dev, "failed to read resistance heat range\n");
298 return ret;
299 }
300 calib->res_heat_range = (tmp & BME680_RHRANGE_MSK) / 16;
301
302 ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_VAL, &tmp);
303 if (ret < 0) {
304 dev_err(dev, "failed to read resistance heat value\n");
305 return ret;
306 }
307 calib->res_heat_val = tmp;
308
309 ret = regmap_read(data->regmap, BME680_REG_RANGE_SW_ERR, &tmp);
310 if (ret < 0) {
311 dev_err(dev, "failed to read range software error\n");
312 return ret;
313 }
314 calib->range_sw_err = (tmp & BME680_RSERROR_MSK) / 16;
315
316 return 0;
317}
318
319/*
320 * Taken from Bosch BME680 API:
321 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L876
322 *
323 * Returns temperature measurement in DegC, resolutions is 0.01 DegC. Therefore,
324 * output value of "3233" represents 32.33 DegC.
325 */
326static s16 bme680_compensate_temp(struct bme680_data *data,
327 s32 adc_temp)
328{
329 struct bme680_calib *calib = &data->bme680;
330 s64 var1, var2, var3;
331 s16 calc_temp;
332
333 var1 = (adc_temp >> 3) - (calib->par_t1 << 1);
334 var2 = (var1 * calib->par_t2) >> 11;
335 var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
336 var3 = (var3 * (calib->par_t3 << 4)) >> 14;
337 data->t_fine = var2 + var3;
338 calc_temp = (data->t_fine * 5 + 128) >> 8;
339
340 return calc_temp;
341}
342
343/*
344 * Taken from Bosch BME680 API:
345 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L896
346 *
347 * Returns pressure measurement in Pa. Output value of "97356" represents
348 * 97356 Pa = 973.56 hPa.
349 */
350static u32 bme680_compensate_press(struct bme680_data *data,
351 u32 adc_press)
352{
353 struct bme680_calib *calib = &data->bme680;
354 s32 var1, var2, var3, press_comp;
355
356 var1 = (data->t_fine >> 1) - 64000;
357 var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2;
358 var2 = var2 + (var1 * calib->par_p5 << 1);
359 var2 = (var2 >> 2) + (calib->par_p4 << 16);
360 var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
361 (calib->par_p3 << 5)) >> 3) +
362 ((calib->par_p2 * var1) >> 1);
363 var1 = var1 >> 18;
364 var1 = ((32768 + var1) * calib->par_p1) >> 15;
365 press_comp = 1048576 - adc_press;
366 press_comp = ((press_comp - (var2 >> 12)) * 3125);
367
368 if (press_comp >= BME680_MAX_OVERFLOW_VAL)
369 press_comp = ((press_comp / (u32)var1) << 1);
370 else
371 press_comp = ((press_comp << 1) / (u32)var1);
372
373 var1 = (calib->par_p9 * (((press_comp >> 3) *
374 (press_comp >> 3)) >> 13)) >> 12;
375 var2 = ((press_comp >> 2) * calib->par_p8) >> 13;
376 var3 = ((press_comp >> 8) * (press_comp >> 8) *
377 (press_comp >> 8) * calib->par_p10) >> 17;
378
379 press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4;
380
381 return press_comp;
382}
383
384/*
385 * Taken from Bosch BME680 API:
386 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L937
387 *
388 * Returns humidity measurement in percent, resolution is 0.001 percent. Output
389 * value of "43215" represents 43.215 %rH.
390 */
391static u32 bme680_compensate_humid(struct bme680_data *data,
392 u16 adc_humid)
393{
394 struct bme680_calib *calib = &data->bme680;
395 s32 var1, var2, var3, var4, var5, var6, temp_scaled, calc_hum;
396
397 temp_scaled = (data->t_fine * 5 + 128) >> 8;
398 var1 = (adc_humid - ((s32) ((s32) calib->par_h1 * 16))) -
399 (((temp_scaled * (s32) calib->par_h3) / 100) >> 1);
400 var2 = ((s32) calib->par_h2 *
401 (((temp_scaled * calib->par_h4) / 100) +
402 (((temp_scaled * ((temp_scaled * calib->par_h5) / 100))
403 >> 6) / 100) + (1 << 14))) >> 10;
404 var3 = var1 * var2;
405 var4 = calib->par_h6 << 7;
406 var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4;
407 var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
408 var6 = (var4 * var5) >> 1;
409 calc_hum = (((var3 + var6) >> 10) * 1000) >> 12;
410
411 if (calc_hum > 100000) /* Cap at 100%rH */
412 calc_hum = 100000;
413 else if (calc_hum < 0)
414 calc_hum = 0;
415
416 return calc_hum;
417}
418
419/*
420 * Taken from Bosch BME680 API:
421 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L973
422 *
423 * Returns gas measurement in Ohm. Output value of "82986" represent 82986 ohms.
424 */
425static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc,
426 u8 gas_range)
427{
428 struct bme680_calib *calib = &data->bme680;
429 s64 var1;
430 u64 var2;
431 s64 var3;
432 u32 calc_gas_res;
433
434 /* Look up table for the possible gas range values */
435 const u32 lookupTable[16] = {2147483647u, 2147483647u,
436 2147483647u, 2147483647u, 2147483647u,
437 2126008810u, 2147483647u, 2130303777u,
438 2147483647u, 2147483647u, 2143188679u,
439 2136746228u, 2147483647u, 2126008810u,
440 2147483647u, 2147483647u};
441
442 var1 = ((1340 + (5 * (s64) calib->range_sw_err)) *
443 ((s64) lookupTable[gas_range])) >> 16;
444 var2 = ((gas_res_adc << 15) - 16777216) + var1;
445 var3 = ((125000 << (15 - gas_range)) * var1) >> 9;
446 var3 += (var2 >> 1);
447 calc_gas_res = div64_s64(var3, (s64) var2);
448
449 return calc_gas_res;
450}
451
452/*
453 * Taken from Bosch BME680 API:
454 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1002
455 */
456static u8 bme680_calc_heater_res(struct bme680_data *data, u16 temp)
457{
458 struct bme680_calib *calib = &data->bme680;
459 s32 var1, var2, var3, var4, var5, heatr_res_x100;
460 u8 heatr_res;
461
462 if (temp > 400) /* Cap temperature */
463 temp = 400;
464
465 var1 = (((s32) BME680_AMB_TEMP * calib->par_gh3) / 1000) * 256;
466 var2 = (calib->par_gh1 + 784) * (((((calib->par_gh2 + 154009) *
467 temp * 5) / 100)
468 + 3276800) / 10);
469 var3 = var1 + (var2 / 2);
470 var4 = (var3 / (calib->res_heat_range + 4));
471 var5 = 131 * calib->res_heat_val + 65536;
472 heatr_res_x100 = ((var4 / var5) - 250) * 34;
473 heatr_res = (heatr_res_x100 + 50) / 100;
474
475 return heatr_res;
476}
477
478/*
479 * Taken from Bosch BME680 API:
480 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1188
481 */
482static u8 bme680_calc_heater_dur(u16 dur)
483{
484 u8 durval, factor = 0;
485
486 if (dur >= 0xfc0) {
487 durval = 0xff; /* Max duration */
488 } else {
489 while (dur > 0x3F) {
490 dur = dur / 4;
491 factor += 1;
492 }
493 durval = dur + (factor * 64);
494 }
495
496 return durval;
497}
498
499static int bme680_set_mode(struct bme680_data *data, bool mode)
500{
501 struct device *dev = regmap_get_device(data->regmap);
502 int ret;
503
504 if (mode) {
505 ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
506 BME680_MODE_MASK, BME680_MODE_FORCED);
507 if (ret < 0)
508 dev_err(dev, "failed to set forced mode\n");
509
510 } else {
511 ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
512 BME680_MODE_MASK, BME680_MODE_SLEEP);
513 if (ret < 0)
514 dev_err(dev, "failed to set sleep mode\n");
515
516 }
517
518 return ret;
519}
520
521static int bme680_chip_config(struct bme680_data *data)
522{
523 struct device *dev = regmap_get_device(data->regmap);
524 int ret;
525 u8 osrs = FIELD_PREP(BME680_OSRS_HUMIDITY_MASK,
526 data->oversampling_humid + 1);
527 /*
528 * Highly recommended to set oversampling of humidity before
529 * temperature/pressure oversampling.
530 */
531 ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_HUMIDITY,
532 BME680_OSRS_HUMIDITY_MASK, osrs);
533 if (ret < 0) {
534 dev_err(dev, "failed to write ctrl_hum register\n");
535 return ret;
536 }
537
538 /* IIR filter settings */
539 ret = regmap_update_bits(data->regmap, BME680_REG_CONFIG,
540 BME680_FILTER_MASK,
541 BME680_FILTER_COEFF_VAL);
542 if (ret < 0) {
543 dev_err(dev, "failed to write config register\n");
544 return ret;
545 }
546
547 osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK, data->oversampling_temp + 1) |
548 FIELD_PREP(BME680_OSRS_PRESS_MASK, data->oversampling_press + 1);
549
550 ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
551 BME680_OSRS_TEMP_MASK |
552 BME680_OSRS_PRESS_MASK,
553 osrs);
554 if (ret < 0)
555 dev_err(dev, "failed to write ctrl_meas register\n");
556
557 return ret;
558}
559
560static int bme680_gas_config(struct bme680_data *data)
561{
562 struct device *dev = regmap_get_device(data->regmap);
563 int ret;
564 u8 heatr_res, heatr_dur;
565
566 heatr_res = bme680_calc_heater_res(data, data->heater_temp);
567
568 /* set target heater temperature */
569 ret = regmap_write(data->regmap, BME680_REG_RES_HEAT_0, heatr_res);
570 if (ret < 0) {
571 dev_err(dev, "failed to write res_heat_0 register\n");
572 return ret;
573 }
574
575 heatr_dur = bme680_calc_heater_dur(data->heater_dur);
576
577 /* set target heating duration */
578 ret = regmap_write(data->regmap, BME680_REG_GAS_WAIT_0, heatr_dur);
579 if (ret < 0) {
580 dev_err(dev, "failted to write gas_wait_0 register\n");
581 return ret;
582 }
583
584 /* Selecting the runGas and NB conversion settings for the sensor */
585 ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_GAS_1,
586 BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK,
587 BME680_RUN_GAS_EN_BIT | BME680_NB_CONV_0_VAL);
588 if (ret < 0)
589 dev_err(dev, "failed to write ctrl_gas_1 register\n");
590
591 return ret;
592}
593
594static int bme680_read_temp(struct bme680_data *data,
595 int *val, int *val2)
596{
597 struct device *dev = regmap_get_device(data->regmap);
598 int ret;
599 __be32 tmp = 0;
600 s32 adc_temp;
601 s16 comp_temp;
602
603 /* set forced mode to trigger measurement */
604 ret = bme680_set_mode(data, true);
605 if (ret < 0)
606 return ret;
607
608 ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
609 (u8 *) &tmp, 3);
610 if (ret < 0) {
611 dev_err(dev, "failed to read temperature\n");
612 return ret;
613 }
614
615 adc_temp = be32_to_cpu(tmp) >> 12;
616 if (adc_temp == BME680_MEAS_SKIPPED) {
617 /* reading was skipped */
618 dev_err(dev, "reading temperature skipped\n");
619 return -EINVAL;
620 }
621 comp_temp = bme680_compensate_temp(data, adc_temp);
622 /*
623 * val might be NULL if we're called by the read_press/read_humid
624 * routine which is callled to get t_fine value used in
625 * compensate_press/compensate_humid to get compensated
626 * pressure/humidity readings.
627 */
628 if (val && val2) {
629 *val = comp_temp;
630 *val2 = 100;
631 return IIO_VAL_FRACTIONAL;
632 }
633
634 return ret;
635}
636
637static int bme680_read_press(struct bme680_data *data,
638 int *val, int *val2)
639{
640 struct device *dev = regmap_get_device(data->regmap);
641 int ret;
642 __be32 tmp = 0;
643 s32 adc_press;
644
645 /* Read and compensate temperature to get a reading of t_fine */
646 ret = bme680_read_temp(data, NULL, NULL);
647 if (ret < 0)
648 return ret;
649
650 ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,
651 (u8 *) &tmp, 3);
652 if (ret < 0) {
653 dev_err(dev, "failed to read pressure\n");
654 return ret;
655 }
656
657 adc_press = be32_to_cpu(tmp) >> 12;
658 if (adc_press == BME680_MEAS_SKIPPED) {
659 /* reading was skipped */
660 dev_err(dev, "reading pressure skipped\n");
661 return -EINVAL;
662 }
663
664 *val = bme680_compensate_press(data, adc_press);
665 *val2 = 100;
666 return IIO_VAL_FRACTIONAL;
667}
668
669static int bme680_read_humid(struct bme680_data *data,
670 int *val, int *val2)
671{
672 struct device *dev = regmap_get_device(data->regmap);
673 int ret;
674 __be16 tmp = 0;
675 s32 adc_humidity;
676 u32 comp_humidity;
677
678 /* Read and compensate temperature to get a reading of t_fine */
679 ret = bme680_read_temp(data, NULL, NULL);
680 if (ret < 0)
681 return ret;
682
683 ret = regmap_bulk_read(data->regmap, BM6880_REG_HUMIDITY_MSB,
684 (u8 *) &tmp, 2);
685 if (ret < 0) {
686 dev_err(dev, "failed to read humidity\n");
687 return ret;
688 }
689
690 adc_humidity = be16_to_cpu(tmp);
691 if (adc_humidity == BME680_MEAS_SKIPPED) {
692 /* reading was skipped */
693 dev_err(dev, "reading humidity skipped\n");
694 return -EINVAL;
695 }
696 comp_humidity = bme680_compensate_humid(data, adc_humidity);
697
698 *val = comp_humidity;
699 *val2 = 1000;
700 return IIO_VAL_FRACTIONAL;
701}
702
703static int bme680_read_gas(struct bme680_data *data,
704 int *val)
705{
706 struct device *dev = regmap_get_device(data->regmap);
707 int ret;
708 __be16 tmp = 0;
709 unsigned int check;
710 u16 adc_gas_res;
711 u8 gas_range;
712
713 /* Set heater settings */
714 ret = bme680_gas_config(data);
715 if (ret < 0) {
716 dev_err(dev, "failed to set gas config\n");
717 return ret;
718 }
719
720 /* set forced mode to trigger measurement */
721 ret = bme680_set_mode(data, true);
722 if (ret < 0)
723 return ret;
724
725 ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
726 if (check & BME680_GAS_MEAS_BIT) {
727 dev_err(dev, "gas measurement incomplete\n");
728 return -EBUSY;
729 }
730
731 ret = regmap_read(data->regmap, BME680_REG_GAS_R_LSB, &check);
732 if (ret < 0) {
733 dev_err(dev, "failed to read gas_r_lsb register\n");
734 return ret;
735 }
736
737 /*
738 * occurs if either the gas heating duration was insuffient
739 * to reach the target heater temperature or the target
740 * heater temperature was too high for the heater sink to
741 * reach.
742 */
743 if ((check & BME680_GAS_STAB_BIT) == 0) {
744 dev_err(dev, "heater failed to reach the target temperature\n");
745 return -EINVAL;
746 }
747
748 ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,
749 (u8 *) &tmp, 2);
750 if (ret < 0) {
751 dev_err(dev, "failed to read gas resistance\n");
752 return ret;
753 }
754
755 gas_range = check & BME680_GAS_RANGE_MASK;
756 adc_gas_res = be16_to_cpu(tmp) >> BME680_ADC_GAS_RES_SHIFT;
757
758 *val = bme680_compensate_gas(data, adc_gas_res, gas_range);
759 return IIO_VAL_INT;
760}
761
762static int bme680_read_raw(struct iio_dev *indio_dev,
763 struct iio_chan_spec const *chan,
764 int *val, int *val2, long mask)
765{
766 struct bme680_data *data = iio_priv(indio_dev);
767
768 switch (mask) {
769 case IIO_CHAN_INFO_PROCESSED:
770 switch (chan->type) {
771 case IIO_TEMP:
772 return bme680_read_temp(data, val, val2);
773 case IIO_PRESSURE:
774 return bme680_read_press(data, val, val2);
775 case IIO_HUMIDITYRELATIVE:
776 return bme680_read_humid(data, val, val2);
777 case IIO_RESISTANCE:
778 return bme680_read_gas(data, val);
779 default:
780 return -EINVAL;
781 }
782 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
783 switch (chan->type) {
784 case IIO_TEMP:
785 *val = 1 << data->oversampling_temp;
786 return IIO_VAL_INT;
787 case IIO_PRESSURE:
788 *val = 1 << data->oversampling_press;
789 return IIO_VAL_INT;
790 case IIO_HUMIDITYRELATIVE:
791 *val = 1 << data->oversampling_humid;
792 return IIO_VAL_INT;
793 default:
794 return -EINVAL;
795 }
796 default:
797 return -EINVAL;
798 }
799}
800
801static int bme680_write_oversampling_ratio_temp(struct bme680_data *data,
802 int val)
803{
804 int i;
805
806 for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
807 if (bme680_oversampling_avail[i] == val) {
808 data->oversampling_temp = ilog2(val);
809
810 return bme680_chip_config(data);
811 }
812 }
813
814 return -EINVAL;
815}
816
817static int bme680_write_oversampling_ratio_press(struct bme680_data *data,
818 int val)
819{
820 int i;
821
822 for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
823 if (bme680_oversampling_avail[i] == val) {
824 data->oversampling_press = ilog2(val);
825
826 return bme680_chip_config(data);
827 }
828 }
829
830 return -EINVAL;
831}
832
833static int bme680_write_oversampling_ratio_humid(struct bme680_data *data,
834 int val)
835{
836 int i;
837
838 for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
839 if (bme680_oversampling_avail[i] == val) {
840 data->oversampling_humid = ilog2(val);
841
842 return bme680_chip_config(data);
843 }
844 }
845
846 return -EINVAL;
847}
848
849static int bme680_write_raw(struct iio_dev *indio_dev,
850 struct iio_chan_spec const *chan,
851 int val, int val2, long mask)
852{
853 struct bme680_data *data = iio_priv(indio_dev);
854
855 switch (mask) {
856 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
857 switch (chan->type) {
858 case IIO_TEMP:
859 return bme680_write_oversampling_ratio_temp(data, val);
860 case IIO_PRESSURE:
861 return bme680_write_oversampling_ratio_press(data, val);
862 case IIO_HUMIDITYRELATIVE:
863 return bme680_write_oversampling_ratio_humid(data, val);
864 default:
865 return -EINVAL;
866 }
867 default:
868 return -EINVAL;
869 }
870}
871
872static const char bme680_oversampling_ratio_show[] = "1 2 4 8 16";
873
874static IIO_CONST_ATTR(oversampling_ratio_available,
875 bme680_oversampling_ratio_show);
876
877static struct attribute *bme680_attributes[] = {
878 &iio_const_attr_oversampling_ratio_available.dev_attr.attr,
879 NULL,
880};
881
882static const struct attribute_group bme680_attribute_group = {
883 .attrs = bme680_attributes,
884};
885
886static const struct iio_info bme680_info = {
887 .read_raw = &bme680_read_raw,
888 .write_raw = &bme680_write_raw,
889 .attrs = &bme680_attribute_group,
890};
891
892static const char *bme680_match_acpi_device(struct device *dev)
893{
894 const struct acpi_device_id *id;
895
896 id = acpi_match_device(dev->driver->acpi_match_table, dev);
897 if (!id)
898 return NULL;
899
900 return dev_name(dev);
901}
902
903int bme680_core_probe(struct device *dev, struct regmap *regmap,
904 const char *name)
905{
906 struct iio_dev *indio_dev;
907 struct bme680_data *data;
908 int ret;
909
910 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
911 if (!indio_dev)
912 return -ENOMEM;
913
914 if (!name && ACPI_HANDLE(dev))
915 name = bme680_match_acpi_device(dev);
916
917 data = iio_priv(indio_dev);
918 dev_set_drvdata(dev, indio_dev);
919 data->regmap = regmap;
920 indio_dev->dev.parent = dev;
921 indio_dev->name = name;
922 indio_dev->channels = bme680_channels;
923 indio_dev->num_channels = ARRAY_SIZE(bme680_channels);
924 indio_dev->info = &bme680_info;
925 indio_dev->modes = INDIO_DIRECT_MODE;
926
927 /* default values for the sensor */
928 data->oversampling_humid = ilog2(2); /* 2X oversampling rate */
929 data->oversampling_press = ilog2(4); /* 4X oversampling rate */
930 data->oversampling_temp = ilog2(8); /* 8X oversampling rate */
931 data->heater_temp = 320; /* degree Celsius */
932 data->heater_dur = 150; /* milliseconds */
933
934 ret = bme680_chip_config(data);
935 if (ret < 0) {
936 dev_err(dev, "failed to set chip_config data\n");
937 return ret;
938 }
939
940 ret = bme680_gas_config(data);
941 if (ret < 0) {
942 dev_err(dev, "failed to set gas config data\n");
943 return ret;
944 }
945
946 ret = bme680_read_calib(data, &data->bme680);
947 if (ret < 0) {
948 dev_err(dev,
949 "failed to read calibration coefficients at probe\n");
950 return ret;
951 }
952
953 return devm_iio_device_register(dev, indio_dev);
954}
955EXPORT_SYMBOL_GPL(bme680_core_probe);
956
957MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>");
958MODULE_DESCRIPTION("Bosch BME680 Driver");
959MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/chemical/bme680_i2c.c b/drivers/iio/chemical/bme680_i2c.c
new file mode 100644
index 000000000000..06d4be539d2e
--- /dev/null
+++ b/drivers/iio/chemical/bme680_i2c.c
@@ -0,0 +1,85 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * BME680 - I2C Driver
4 *
5 * Copyright (C) 2018 Himanshu Jha <himanshujha199640@gmail.com>
6 *
7 * 7-Bit I2C slave address is:
8 * - 0x76 if SDO is pulled to GND
9 * - 0x77 if SDO is pulled to VDDIO
10 *
11 * Note: SDO pin cannot be left floating otherwise I2C address
12 * will be undefined.
13 */
14#include <linux/acpi.h>
15#include <linux/i2c.h>
16#include <linux/module.h>
17#include <linux/regmap.h>
18
19#include "bme680.h"
20
21static int bme680_i2c_probe(struct i2c_client *client,
22 const struct i2c_device_id *id)
23{
24 struct regmap *regmap;
25 const char *name = NULL;
26 unsigned int val;
27 int ret;
28
29 regmap = devm_regmap_init_i2c(client, &bme680_regmap_config);
30 if (IS_ERR(regmap)) {
31 dev_err(&client->dev, "Failed to register i2c regmap %d\n",
32 (int)PTR_ERR(regmap));
33 return PTR_ERR(regmap);
34 }
35
36 ret = regmap_write(regmap, BME680_REG_SOFT_RESET_I2C,
37 BME680_CMD_SOFTRESET);
38 if (ret < 0) {
39 dev_err(&client->dev, "Failed to reset chip\n");
40 return ret;
41 }
42
43 ret = regmap_read(regmap, BME680_REG_CHIP_I2C_ID, &val);
44 if (ret < 0) {
45 dev_err(&client->dev, "Error reading I2C chip ID\n");
46 return ret;
47 }
48
49 if (val != BME680_CHIP_ID_VAL) {
50 dev_err(&client->dev, "Wrong chip ID, got %x expected %x\n",
51 val, BME680_CHIP_ID_VAL);
52 return -ENODEV;
53 }
54
55 if (id)
56 name = id->name;
57
58 return bme680_core_probe(&client->dev, regmap, name);
59}
60
61static const struct i2c_device_id bme680_i2c_id[] = {
62 {"bme680", 0},
63 {},
64};
65MODULE_DEVICE_TABLE(i2c, bme680_i2c_id);
66
67static const struct acpi_device_id bme680_acpi_match[] = {
68 {"BME0680", 0},
69 {},
70};
71MODULE_DEVICE_TABLE(acpi, bme680_acpi_match);
72
73static struct i2c_driver bme680_i2c_driver = {
74 .driver = {
75 .name = "bme680_i2c",
76 .acpi_match_table = ACPI_PTR(bme680_acpi_match),
77 },
78 .probe = bme680_i2c_probe,
79 .id_table = bme680_i2c_id,
80};
81module_i2c_driver(bme680_i2c_driver);
82
83MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>");
84MODULE_DESCRIPTION("BME680 I2C driver");
85MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/chemical/bme680_spi.c b/drivers/iio/chemical/bme680_spi.c
new file mode 100644
index 000000000000..c9fb05e8d0b9
--- /dev/null
+++ b/drivers/iio/chemical/bme680_spi.c
@@ -0,0 +1,125 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * BME680 - SPI Driver
4 *
5 * Copyright (C) 2018 Himanshu Jha <himanshujha199640@gmail.com>
6 */
7#include <linux/acpi.h>
8#include <linux/module.h>
9#include <linux/regmap.h>
10#include <linux/spi/spi.h>
11
12#include "bme680.h"
13
14static int bme680_regmap_spi_write(void *context, const void *data,
15 size_t count)
16{
17 struct spi_device *spi = context;
18 u8 buf[2];
19
20 memcpy(buf, data, 2);
21 /*
22 * The SPI register address (= full register address without bit 7)
23 * and the write command (bit7 = RW = '0')
24 */
25 buf[0] &= ~0x80;
26
27 return spi_write_then_read(spi, buf, 2, NULL, 0);
28}
29
30static int bme680_regmap_spi_read(void *context, const void *reg,
31 size_t reg_size, void *val, size_t val_size)
32{
33 struct spi_device *spi = context;
34
35 return spi_write_then_read(spi, reg, reg_size, val, val_size);
36}
37
38static struct regmap_bus bme680_regmap_bus = {
39 .write = bme680_regmap_spi_write,
40 .read = bme680_regmap_spi_read,
41 .reg_format_endian_default = REGMAP_ENDIAN_BIG,
42 .val_format_endian_default = REGMAP_ENDIAN_BIG,
43};
44
45static int bme680_spi_probe(struct spi_device *spi)
46{
47 const struct spi_device_id *id = spi_get_device_id(spi);
48 struct regmap *regmap;
49 unsigned int val;
50 int ret;
51
52 spi->bits_per_word = 8;
53 ret = spi_setup(spi);
54 if (ret < 0) {
55 dev_err(&spi->dev, "spi_setup failed!\n");
56 return ret;
57 }
58
59 regmap = devm_regmap_init(&spi->dev, &bme680_regmap_bus,
60 &spi->dev, &bme680_regmap_config);
61 if (IS_ERR(regmap)) {
62 dev_err(&spi->dev, "Failed to register spi regmap %d\n",
63 (int)PTR_ERR(regmap));
64 return PTR_ERR(regmap);
65 }
66
67 ret = regmap_write(regmap, BME680_REG_SOFT_RESET_SPI,
68 BME680_CMD_SOFTRESET);
69 if (ret < 0) {
70 dev_err(&spi->dev, "Failed to reset chip\n");
71 return ret;
72 }
73
74 /* after power-on reset, Page 0(0x80-0xFF) of spi_mem_page is active */
75 ret = regmap_read(regmap, BME680_REG_CHIP_SPI_ID, &val);
76 if (ret < 0) {
77 dev_err(&spi->dev, "Error reading SPI chip ID\n");
78 return ret;
79 }
80
81 if (val != BME680_CHIP_ID_VAL) {
82 dev_err(&spi->dev, "Wrong chip ID, got %x expected %x\n",
83 val, BME680_CHIP_ID_VAL);
84 return -ENODEV;
85 }
86 /*
87 * select Page 1 of spi_mem_page to enable access to
88 * to registers from address 0x00 to 0x7F.
89 */
90 ret = regmap_write_bits(regmap, BME680_REG_STATUS,
91 BME680_SPI_MEM_PAGE_BIT,
92 BME680_SPI_MEM_PAGE_1_VAL);
93 if (ret < 0) {
94 dev_err(&spi->dev, "failed to set page 1 of spi_mem_page\n");
95 return ret;
96 }
97
98 return bme680_core_probe(&spi->dev, regmap, id->name);
99}
100
101static const struct spi_device_id bme680_spi_id[] = {
102 {"bme680", 0},
103 {},
104};
105MODULE_DEVICE_TABLE(spi, bme680_spi_id);
106
107static const struct acpi_device_id bme680_acpi_match[] = {
108 {"BME0680", 0},
109 {},
110};
111MODULE_DEVICE_TABLE(acpi, bme680_acpi_match);
112
113static struct spi_driver bme680_spi_driver = {
114 .driver = {
115 .name = "bme680_spi",
116 .acpi_match_table = ACPI_PTR(bme680_acpi_match),
117 },
118 .probe = bme680_spi_probe,
119 .id_table = bme680_spi_id,
120};
121module_spi_driver(bme680_spi_driver);
122
123MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>");
124MODULE_DESCRIPTION("Bosch BME680 SPI driver");
125MODULE_LICENSE("GPL v2");