brintos

brintos / linux-shallow public Read only

0
0
Text · 23.6 KiB · 0b96534 Raw
932 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Bosch BME680 - Temperature, Pressure, Humidity & Gas Sensor4 *5 * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH6 * 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.pdf10 */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/regmap.h>18 19#include <linux/iio/iio.h>20#include <linux/iio/sysfs.h>21 22#include <linux/unaligned.h>23 24#include "bme680.h"25 26/* 1st set of calibration data */27enum {28	/* Temperature calib indexes */29	T2_LSB = 0,30	T3 = 2,31	/* Pressure calib indexes */32	P1_LSB = 4,33	P2_LSB = 6,34	P3 = 8,35	P4_LSB = 10,36	P5_LSB = 12,37	P7 = 14,38	P6 = 15,39	P8_LSB = 18,40	P9_LSB = 20,41	P10 = 22,42};43 44/* 2nd set of calibration data */45enum {46	/* Humidity calib indexes */47	H2_MSB = 0,48	H1_LSB = 1,49	H3 = 3,50	H4 = 4,51	H5 = 5,52	H6 = 6,53	H7 = 7,54	/* Stray T1 calib index */55	T1_LSB = 8,56	/* Gas heater calib indexes */57	GH2_LSB = 10,58	GH1 = 12,59	GH3 = 13,60};61 62/* 3rd set of calibration data */63enum {64	RES_HEAT_VAL = 0,65	RES_HEAT_RANGE = 2,66	RANGE_SW_ERR = 4,67};68 69struct bme680_calib {70	u16 par_t1;71	s16 par_t2;72	s8  par_t3;73	u16 par_p1;74	s16 par_p2;75	s8  par_p3;76	s16 par_p4;77	s16 par_p5;78	s8  par_p6;79	s8  par_p7;80	s16 par_p8;81	s16 par_p9;82	u8  par_p10;83	u16 par_h1;84	u16 par_h2;85	s8  par_h3;86	s8  par_h4;87	s8  par_h5;88	u8  par_h6;89	s8  par_h7;90	s8  par_gh1;91	s16 par_gh2;92	s8  par_gh3;93	u8  res_heat_range;94	s8  res_heat_val;95	s8  range_sw_err;96};97 98struct bme680_data {99	struct regmap *regmap;100	struct bme680_calib bme680;101	struct mutex lock; /* Protect multiple serial R/W ops to device. */102	u8 oversampling_temp;103	u8 oversampling_press;104	u8 oversampling_humid;105	u16 heater_dur;106	u16 heater_temp;107 108	union {109		u8 buf[3];110		unsigned int check;111		__be16 be16;112		u8 bme680_cal_buf_1[BME680_CALIB_RANGE_1_LEN];113		u8 bme680_cal_buf_2[BME680_CALIB_RANGE_2_LEN];114		u8 bme680_cal_buf_3[BME680_CALIB_RANGE_3_LEN];115	};116};117 118static const struct regmap_range bme680_volatile_ranges[] = {119	regmap_reg_range(BME680_REG_MEAS_STAT_0, BME680_REG_GAS_R_LSB),120	regmap_reg_range(BME680_REG_STATUS, BME680_REG_STATUS),121	regmap_reg_range(BME680_T2_LSB_REG, BME680_GH3_REG),122};123 124static const struct regmap_access_table bme680_volatile_table = {125	.yes_ranges	= bme680_volatile_ranges,126	.n_yes_ranges	= ARRAY_SIZE(bme680_volatile_ranges),127};128 129const struct regmap_config bme680_regmap_config = {130	.reg_bits = 8,131	.val_bits = 8,132	.max_register = 0xef,133	.volatile_table = &bme680_volatile_table,134	.cache_type = REGCACHE_RBTREE,135};136EXPORT_SYMBOL_NS(bme680_regmap_config, IIO_BME680);137 138static const struct iio_chan_spec bme680_channels[] = {139	{140		.type = IIO_TEMP,141		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |142				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),143	},144	{145		.type = IIO_PRESSURE,146		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |147				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),148	},149	{150		.type = IIO_HUMIDITYRELATIVE,151		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |152				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),153	},154	{155		.type = IIO_RESISTANCE,156		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),157	},158};159 160static int bme680_read_calib(struct bme680_data *data,161			     struct bme680_calib *calib)162{163	struct device *dev = regmap_get_device(data->regmap);164	unsigned int tmp_msb, tmp_lsb;165	int ret;166 167	ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG,168			       data->bme680_cal_buf_1,169			       sizeof(data->bme680_cal_buf_1));170	if (ret < 0) {171		dev_err(dev, "failed to read 1st set of calib data;\n");172		return ret;173	}174 175	calib->par_t2 = get_unaligned_le16(&data->bme680_cal_buf_1[T2_LSB]);176	calib->par_t3 = data->bme680_cal_buf_1[T3];177	calib->par_p1 = get_unaligned_le16(&data->bme680_cal_buf_1[P1_LSB]);178	calib->par_p2 = get_unaligned_le16(&data->bme680_cal_buf_1[P2_LSB]);179	calib->par_p3 = data->bme680_cal_buf_1[P3];180	calib->par_p4 = get_unaligned_le16(&data->bme680_cal_buf_1[P4_LSB]);181	calib->par_p5 = get_unaligned_le16(&data->bme680_cal_buf_1[P5_LSB]);182	calib->par_p7 = data->bme680_cal_buf_1[P7];183	calib->par_p6 = data->bme680_cal_buf_1[P6];184	calib->par_p8 = get_unaligned_le16(&data->bme680_cal_buf_1[P8_LSB]);185	calib->par_p9 = get_unaligned_le16(&data->bme680_cal_buf_1[P9_LSB]);186	calib->par_p10 = data->bme680_cal_buf_1[P10];187 188	ret = regmap_bulk_read(data->regmap, BME680_H2_MSB_REG,189			       data->bme680_cal_buf_2,190			       sizeof(data->bme680_cal_buf_2));191	if (ret < 0) {192		dev_err(dev, "failed to read 2nd set of calib data;\n");193		return ret;194	}195 196	tmp_lsb = data->bme680_cal_buf_2[H1_LSB];197	tmp_msb = data->bme680_cal_buf_2[H1_LSB + 1];198	calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |199			(tmp_lsb & BME680_BIT_H1_DATA_MASK);200 201	tmp_msb = data->bme680_cal_buf_2[H2_MSB];202	tmp_lsb = data->bme680_cal_buf_2[H2_MSB + 1];203	calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |204			(tmp_lsb >> BME680_HUM_REG_SHIFT_VAL);205 206	calib->par_h3 = data->bme680_cal_buf_2[H3];207	calib->par_h4 = data->bme680_cal_buf_2[H4];208	calib->par_h5 = data->bme680_cal_buf_2[H5];209	calib->par_h6 = data->bme680_cal_buf_2[H6];210	calib->par_h7 = data->bme680_cal_buf_2[H7];211	calib->par_t1 = get_unaligned_le16(&data->bme680_cal_buf_2[T1_LSB]);212	calib->par_gh2 = get_unaligned_le16(&data->bme680_cal_buf_2[GH2_LSB]);213	calib->par_gh1 = data->bme680_cal_buf_2[GH1];214	calib->par_gh3 = data->bme680_cal_buf_2[GH3];215 216	ret = regmap_bulk_read(data->regmap, BME680_REG_RES_HEAT_VAL,217			       data->bme680_cal_buf_3,218			       sizeof(data->bme680_cal_buf_3));219	if (ret < 0) {220		dev_err(dev, "failed to read 3rd set of calib data;\n");221		return ret;222	}223 224	calib->res_heat_val = data->bme680_cal_buf_3[RES_HEAT_VAL];225 226	calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK,227					data->bme680_cal_buf_3[RES_HEAT_RANGE]);228 229	calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK,230					data->bme680_cal_buf_3[RANGE_SW_ERR]);231 232	return 0;233}234 235static int bme680_read_temp_adc(struct bme680_data *data, u32 *adc_temp)236{237	struct device *dev = regmap_get_device(data->regmap);238	u32 value_temp;239	int ret;240 241	ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,242			       data->buf, BME680_TEMP_NUM_BYTES);243	if (ret < 0) {244		dev_err(dev, "failed to read temperature\n");245		return ret;246	}247 248	value_temp = FIELD_GET(BME680_MEAS_TRIM_MASK,249			       get_unaligned_be24(data->buf));250	if (value_temp == BME680_MEAS_SKIPPED) {251		/* reading was skipped */252		dev_err(dev, "reading temperature skipped\n");253		return -EINVAL;254	}255	*adc_temp = value_temp;256 257	return 0;258}259 260/*261 * Taken from Bosch BME680 API:262 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L876263 *264 * Returns temperature measurement in DegC, resolutions is 0.01 DegC. Therefore,265 * output value of "3233" represents 32.33 DegC.266 */267static s32 bme680_calc_t_fine(struct bme680_data *data, u32 adc_temp)268{269	struct bme680_calib *calib = &data->bme680;270	s64 var1, var2, var3;271 272	/* If the calibration is invalid, attempt to reload it */273	if (!calib->par_t2)274		bme680_read_calib(data, calib);275 276	var1 = ((s32)adc_temp >> 3) - ((s32)calib->par_t1 << 1);277	var2 = (var1 * calib->par_t2) >> 11;278	var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;279	var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14;280	return var2 + var3; /* t_fine = var2 + var3 */281}282 283static int bme680_get_t_fine(struct bme680_data *data, s32 *t_fine)284{285	u32 adc_temp;286	int ret;287 288	ret = bme680_read_temp_adc(data, &adc_temp);289	if (ret)290		return ret;291 292	*t_fine = bme680_calc_t_fine(data, adc_temp);293 294	return 0;295}296 297static s16 bme680_compensate_temp(struct bme680_data *data,298				  u32 adc_temp)299{300	return (bme680_calc_t_fine(data, adc_temp) * 5 + 128) / 256;301}302 303static int bme680_read_press_adc(struct bme680_data *data, u32 *adc_press)304{305	struct device *dev = regmap_get_device(data->regmap);306	u32 value_press;307	int ret;308 309	ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,310			       data->buf, BME680_PRESS_NUM_BYTES);311	if (ret < 0) {312		dev_err(dev, "failed to read pressure\n");313		return ret;314	}315 316	value_press = FIELD_GET(BME680_MEAS_TRIM_MASK,317				get_unaligned_be24(data->buf));318	if (value_press == BME680_MEAS_SKIPPED) {319		/* reading was skipped */320		dev_err(dev, "reading pressure skipped\n");321		return -EINVAL;322	}323	*adc_press = value_press;324 325	return 0;326}327 328/*329 * Taken from Bosch BME680 API:330 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L896331 *332 * Returns pressure measurement in Pa. Output value of "97356" represents333 * 97356 Pa = 973.56 hPa.334 */335static u32 bme680_compensate_press(struct bme680_data *data,336				   u32 adc_press, s32 t_fine)337{338	struct bme680_calib *calib = &data->bme680;339	s32 var1, var2, var3, press_comp;340 341	var1 = (t_fine >> 1) - 64000;342	var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2;343	var2 = var2 + (var1 * calib->par_p5 << 1);344	var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16);345	var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *346			((s32)calib->par_p3 << 5)) >> 3) +347			((calib->par_p2 * var1) >> 1);348	var1 = var1 >> 18;349	var1 = ((32768 + var1) * calib->par_p1) >> 15;350	press_comp = 1048576 - adc_press;351	press_comp = ((press_comp - (var2 >> 12)) * 3125);352 353	if (press_comp >= BME680_MAX_OVERFLOW_VAL)354		press_comp = ((press_comp / (u32)var1) << 1);355	else356		press_comp = ((press_comp << 1) / (u32)var1);357 358	var1 = (calib->par_p9 * (((press_comp >> 3) *359			(press_comp >> 3)) >> 13)) >> 12;360	var2 = ((press_comp >> 2) * calib->par_p8) >> 13;361	var3 = ((press_comp >> 8) * (press_comp >> 8) *362			(press_comp >> 8) * calib->par_p10) >> 17;363 364	press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4;365 366	return press_comp;367}368 369static int bme680_read_humid_adc(struct bme680_data *data, u32 *adc_humidity)370{371	struct device *dev = regmap_get_device(data->regmap);372	u32 value_humidity;373	int ret;374 375	ret = regmap_bulk_read(data->regmap, BME680_REG_HUMIDITY_MSB,376			       &data->be16, BME680_HUMID_NUM_BYTES);377	if (ret < 0) {378		dev_err(dev, "failed to read humidity\n");379		return ret;380	}381 382	value_humidity = be16_to_cpu(data->be16);383	if (value_humidity == BME680_MEAS_SKIPPED) {384		/* reading was skipped */385		dev_err(dev, "reading humidity skipped\n");386		return -EINVAL;387	}388	*adc_humidity = value_humidity;389 390	return 0;391}392 393/*394 * Taken from Bosch BME680 API:395 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L937396 *397 * Returns humidity measurement in percent, resolution is 0.001 percent. Output398 * value of "43215" represents 43.215 %rH.399 */400static u32 bme680_compensate_humid(struct bme680_data *data,401				   u16 adc_humid, s32 t_fine)402{403	struct bme680_calib *calib = &data->bme680;404	s32 var1, var2, var3, var4, var5, var6, temp_scaled, calc_hum;405 406	temp_scaled = (t_fine * 5 + 128) >> 8;407	var1 = (adc_humid - (((s32)calib->par_h1 * 16))) -408		(((temp_scaled * calib->par_h3) / 100) >> 1);409	var2 = (calib->par_h2 *410		(((temp_scaled * calib->par_h4) / 100) +411		 (((temp_scaled * ((temp_scaled * calib->par_h5) / 100))412		   >> 6) / 100) + (1 << 14))) >> 10;413	var3 = var1 * var2;414	var4 = (s32)calib->par_h6 << 7;415	var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4;416	var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;417	var6 = (var4 * var5) >> 1;418	calc_hum = (((var3 + var6) >> 10) * 1000) >> 12;419 420	calc_hum = clamp(calc_hum, 0, 100000); /* clamp between 0-100 %rH */421 422	return calc_hum;423}424 425/*426 * Taken from Bosch BME680 API:427 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L973428 *429 * Returns gas measurement in Ohm. Output value of "82986" represent 82986 ohms.430 */431static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc,432				 u8 gas_range)433{434	struct bme680_calib *calib = &data->bme680;435	s64 var1;436	u64 var2;437	s64 var3;438	u32 calc_gas_res;439 440	/* Look up table for the possible gas range values */441	static const u32 lookupTable[16] = {2147483647u, 2147483647u,442				2147483647u, 2147483647u, 2147483647u,443				2126008810u, 2147483647u, 2130303777u,444				2147483647u, 2147483647u, 2143188679u,445				2136746228u, 2147483647u, 2126008810u,446				2147483647u, 2147483647u};447 448	var1 = ((1340 + (5 * (s64) calib->range_sw_err)) *449			((s64) lookupTable[gas_range])) >> 16;450	var2 = ((gas_res_adc << 15) - 16777216) + var1;451	var3 = ((125000 << (15 - gas_range)) * var1) >> 9;452	var3 += (var2 >> 1);453	calc_gas_res = div64_s64(var3, (s64) var2);454 455	return calc_gas_res;456}457 458/*459 * Taken from Bosch BME680 API:460 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1002461 */462static u8 bme680_calc_heater_res(struct bme680_data *data, u16 temp)463{464	struct bme680_calib *calib = &data->bme680;465	s32 var1, var2, var3, var4, var5, heatr_res_x100;466	u8 heatr_res;467 468	if (temp > 400) /* Cap temperature */469		temp = 400;470 471	var1 = (((s32) BME680_AMB_TEMP * calib->par_gh3) / 1000) * 256;472	var2 = (calib->par_gh1 + 784) * (((((calib->par_gh2 + 154009) *473						temp * 5) / 100)474						+ 3276800) / 10);475	var3 = var1 + (var2 / 2);476	var4 = (var3 / (calib->res_heat_range + 4));477	var5 = 131 * calib->res_heat_val + 65536;478	heatr_res_x100 = ((var4 / var5) - 250) * 34;479	heatr_res = DIV_ROUND_CLOSEST(heatr_res_x100, 100);480 481	return heatr_res;482}483 484/*485 * Taken from Bosch BME680 API:486 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1188487 */488static u8 bme680_calc_heater_dur(u16 dur)489{490	u8 durval, factor = 0;491 492	if (dur >= 0xfc0) {493		durval = 0xff; /* Max duration */494	} else {495		while (dur > 0x3F) {496			dur = dur / 4;497			factor += 1;498		}499		durval = dur + (factor * 64);500	}501 502	return durval;503}504 505static int bme680_set_mode(struct bme680_data *data, bool mode)506{507	struct device *dev = regmap_get_device(data->regmap);508	int ret;509 510	if (mode) {511		ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,512					BME680_MODE_MASK, BME680_MODE_FORCED);513		if (ret < 0)514			dev_err(dev, "failed to set forced mode\n");515 516	} else {517		ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,518					BME680_MODE_MASK, BME680_MODE_SLEEP);519		if (ret < 0)520			dev_err(dev, "failed to set sleep mode\n");521 522	}523 524	return ret;525}526 527static u8 bme680_oversampling_to_reg(u8 val)528{529	return ilog2(val) + 1;530}531 532/*533 * Taken from Bosch BME680 API:534 * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490535 */536static int bme680_wait_for_eoc(struct bme680_data *data)537{538	struct device *dev = regmap_get_device(data->regmap);539	int ret;540	/*541	 * (Sum of oversampling ratios * time per oversampling) +542	 * TPH measurement + gas measurement + wait transition from forced mode543	 * + heater duration544	 */545	int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press +546			   data->oversampling_humid) * 1936) + (477 * 4) +547			   (477 * 5) + 1000 + (data->heater_dur * 1000);548 549	usleep_range(wait_eoc_us, wait_eoc_us + 100);550 551	ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &data->check);552	if (ret) {553		dev_err(dev, "failed to read measurement status register.\n");554		return ret;555	}556	if (data->check & BME680_MEAS_BIT) {557		dev_err(dev, "Device measurement cycle incomplete.\n");558		return -EBUSY;559	}560	if (!(data->check & BME680_NEW_DATA_BIT)) {561		dev_err(dev, "No new data available from the device.\n");562		return -ENODATA;563	}564 565	return 0;566}567 568static int bme680_chip_config(struct bme680_data *data)569{570	struct device *dev = regmap_get_device(data->regmap);571	int ret;572	u8 osrs;573 574	osrs = FIELD_PREP(575		BME680_OSRS_HUMIDITY_MASK,576		bme680_oversampling_to_reg(data->oversampling_humid));577	/*578	 * Highly recommended to set oversampling of humidity before579	 * temperature/pressure oversampling.580	 */581	ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_HUMIDITY,582				 BME680_OSRS_HUMIDITY_MASK, osrs);583	if (ret < 0) {584		dev_err(dev, "failed to write ctrl_hum register\n");585		return ret;586	}587 588	/* IIR filter settings */589	ret = regmap_update_bits(data->regmap, BME680_REG_CONFIG,590				 BME680_FILTER_MASK,591				 BME680_FILTER_COEFF_VAL);592	if (ret < 0) {593		dev_err(dev, "failed to write config register\n");594		return ret;595	}596 597	osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK,598			  bme680_oversampling_to_reg(data->oversampling_temp)) |599	       FIELD_PREP(BME680_OSRS_PRESS_MASK,600			  bme680_oversampling_to_reg(data->oversampling_press));601	ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,602				BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK,603				osrs);604	if (ret < 0) {605		dev_err(dev, "failed to write ctrl_meas register\n");606		return ret;607	}608 609	return 0;610}611 612static int bme680_gas_config(struct bme680_data *data)613{614	struct device *dev = regmap_get_device(data->regmap);615	int ret;616	u8 heatr_res, heatr_dur;617 618	/* Go to sleep */619	ret = bme680_set_mode(data, false);620	if (ret < 0)621		return ret;622 623	heatr_res = bme680_calc_heater_res(data, data->heater_temp);624 625	/* set target heater temperature */626	ret = regmap_write(data->regmap, BME680_REG_RES_HEAT_0, heatr_res);627	if (ret < 0) {628		dev_err(dev, "failed to write res_heat_0 register\n");629		return ret;630	}631 632	heatr_dur = bme680_calc_heater_dur(data->heater_dur);633 634	/* set target heating duration */635	ret = regmap_write(data->regmap, BME680_REG_GAS_WAIT_0, heatr_dur);636	if (ret < 0) {637		dev_err(dev, "failed to write gas_wait_0 register\n");638		return ret;639	}640 641	/* Enable the gas sensor and select heater profile set-point 0 */642	ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_GAS_1,643				 BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK,644				 FIELD_PREP(BME680_RUN_GAS_MASK, 1) |645				 FIELD_PREP(BME680_NB_CONV_MASK, 0));646	if (ret < 0)647		dev_err(dev, "failed to write ctrl_gas_1 register\n");648 649	return ret;650}651 652static int bme680_read_temp(struct bme680_data *data, int *val)653{654	int ret;655	u32 adc_temp;656	s16 comp_temp;657 658	ret = bme680_read_temp_adc(data, &adc_temp);659	if (ret)660		return ret;661 662	comp_temp = bme680_compensate_temp(data, adc_temp);663	*val = comp_temp * 10; /* Centidegrees to millidegrees */664	return IIO_VAL_INT;665}666 667static int bme680_read_press(struct bme680_data *data,668			     int *val, int *val2)669{670	int ret;671	u32 adc_press;672	s32 t_fine;673 674	ret = bme680_get_t_fine(data, &t_fine);675	if (ret)676		return ret;677 678	ret = bme680_read_press_adc(data, &adc_press);679	if (ret)680		return ret;681 682	*val = bme680_compensate_press(data, adc_press, t_fine);683	*val2 = 1000;684	return IIO_VAL_FRACTIONAL;685}686 687static int bme680_read_humid(struct bme680_data *data,688			     int *val, int *val2)689{690	int ret;691	u32 adc_humidity, comp_humidity;692	s32 t_fine;693 694	ret = bme680_get_t_fine(data, &t_fine);695	if (ret)696		return ret;697 698	ret = bme680_read_humid_adc(data, &adc_humidity);699	if (ret)700		return ret;701 702	comp_humidity = bme680_compensate_humid(data, adc_humidity, t_fine);703 704	*val = comp_humidity;705	*val2 = 1000;706	return IIO_VAL_FRACTIONAL;707}708 709static int bme680_read_gas(struct bme680_data *data,710			   int *val)711{712	struct device *dev = regmap_get_device(data->regmap);713	int ret;714	u16 adc_gas_res, gas_regs_val;715	u8 gas_range;716 717	ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &data->check);718	if (data->check & BME680_GAS_MEAS_BIT) {719		dev_err(dev, "gas measurement incomplete\n");720		return -EBUSY;721	}722 723	ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,724			       &data->be16, BME680_GAS_NUM_BYTES);725	if (ret < 0) {726		dev_err(dev, "failed to read gas resistance\n");727		return ret;728	}729 730	gas_regs_val = be16_to_cpu(data->be16);731	adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val);732 733	/*734	 * occurs if either the gas heating duration was insuffient735	 * to reach the target heater temperature or the target736	 * heater temperature was too high for the heater sink to737	 * reach.738	 */739	if ((gas_regs_val & BME680_GAS_STAB_BIT) == 0) {740		dev_err(dev, "heater failed to reach the target temperature\n");741		return -EINVAL;742	}743 744	gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val);745 746	*val = bme680_compensate_gas(data, adc_gas_res, gas_range);747	return IIO_VAL_INT;748}749 750static int bme680_read_raw(struct iio_dev *indio_dev,751			   struct iio_chan_spec const *chan,752			   int *val, int *val2, long mask)753{754	struct bme680_data *data = iio_priv(indio_dev);755	int ret;756 757	guard(mutex)(&data->lock);758 759	/* set forced mode to trigger measurement */760	ret = bme680_set_mode(data, true);761	if (ret < 0)762		return ret;763 764	ret = bme680_wait_for_eoc(data);765	if (ret)766		return ret;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);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 = data->oversampling_temp;786			return IIO_VAL_INT;787		case IIO_PRESSURE:788			*val = data->oversampling_press;789			return IIO_VAL_INT;790		case IIO_HUMIDITYRELATIVE:791			*val = data->oversampling_humid;792			return IIO_VAL_INT;793		default:794			return -EINVAL;795		}796	default:797		return -EINVAL;798	}799}800 801static bool bme680_is_valid_oversampling(int rate)802{803	return (rate > 0 && rate <= 16 && is_power_of_2(rate));804}805 806static int bme680_write_raw(struct iio_dev *indio_dev,807			    struct iio_chan_spec const *chan,808			    int val, int val2, long mask)809{810	struct bme680_data *data = iio_priv(indio_dev);811 812	guard(mutex)(&data->lock);813 814	if (val2 != 0)815		return -EINVAL;816 817	switch (mask) {818	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:819	{820		if (!bme680_is_valid_oversampling(val))821			return -EINVAL;822 823		switch (chan->type) {824		case IIO_TEMP:825			data->oversampling_temp = val;826			break;827		case IIO_PRESSURE:828			data->oversampling_press = val;829			break;830		case IIO_HUMIDITYRELATIVE:831			data->oversampling_humid = val;832			break;833		default:834			return -EINVAL;835		}836 837		return bme680_chip_config(data);838	}839	default:840		return -EINVAL;841	}842}843 844static const char bme680_oversampling_ratio_show[] = "1 2 4 8 16";845 846static IIO_CONST_ATTR(oversampling_ratio_available,847		      bme680_oversampling_ratio_show);848 849static struct attribute *bme680_attributes[] = {850	&iio_const_attr_oversampling_ratio_available.dev_attr.attr,851	NULL,852};853 854static const struct attribute_group bme680_attribute_group = {855	.attrs = bme680_attributes,856};857 858static const struct iio_info bme680_info = {859	.read_raw = &bme680_read_raw,860	.write_raw = &bme680_write_raw,861	.attrs = &bme680_attribute_group,862};863 864int bme680_core_probe(struct device *dev, struct regmap *regmap,865		      const char *name)866{867	struct iio_dev *indio_dev;868	struct bme680_data *data;869	int ret;870 871	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));872	if (!indio_dev)873		return -ENOMEM;874 875	data = iio_priv(indio_dev);876	mutex_init(&data->lock);877	dev_set_drvdata(dev, indio_dev);878	data->regmap = regmap;879	indio_dev->name = name;880	indio_dev->channels = bme680_channels;881	indio_dev->num_channels = ARRAY_SIZE(bme680_channels);882	indio_dev->info = &bme680_info;883	indio_dev->modes = INDIO_DIRECT_MODE;884 885	/* default values for the sensor */886	data->oversampling_humid = 2; /* 2X oversampling rate */887	data->oversampling_press = 4; /* 4X oversampling rate */888	data->oversampling_temp = 8;  /* 8X oversampling rate */889	data->heater_temp = 320; /* degree Celsius */890	data->heater_dur = 150;  /* milliseconds */891 892	ret = regmap_write(regmap, BME680_REG_SOFT_RESET,893			   BME680_CMD_SOFTRESET);894	if (ret < 0)895		return dev_err_probe(dev, ret, "Failed to reset chip\n");896 897	usleep_range(BME680_STARTUP_TIME_US, BME680_STARTUP_TIME_US + 1000);898 899	ret = regmap_read(regmap, BME680_REG_CHIP_ID, &data->check);900	if (ret < 0)901		return dev_err_probe(dev, ret, "Error reading chip ID\n");902 903	if (data->check != BME680_CHIP_ID_VAL) {904		dev_err(dev, "Wrong chip ID, got %x expected %x\n",905			data->check, BME680_CHIP_ID_VAL);906		return -ENODEV;907	}908 909	ret = bme680_read_calib(data, &data->bme680);910	if (ret < 0) {911		return dev_err_probe(dev, ret,912			"failed to read calibration coefficients at probe\n");913	}914 915	ret = bme680_chip_config(data);916	if (ret < 0)917		return dev_err_probe(dev, ret,918				     "failed to set chip_config data\n");919 920	ret = bme680_gas_config(data);921	if (ret < 0)922		return dev_err_probe(dev, ret,923				     "failed to set gas config data\n");924 925	return devm_iio_device_register(dev, indio_dev);926}927EXPORT_SYMBOL_NS_GPL(bme680_core_probe, IIO_BME680);928 929MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>");930MODULE_DESCRIPTION("Bosch BME680 Driver");931MODULE_LICENSE("GPL v2");932