cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bme680_core.c (24752B)


      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
     66static const struct regmap_range bme680_volatile_ranges[] = {
     67	regmap_reg_range(BME680_REG_MEAS_STAT_0, BME680_REG_GAS_R_LSB),
     68	regmap_reg_range(BME680_REG_STATUS, BME680_REG_STATUS),
     69	regmap_reg_range(BME680_T2_LSB_REG, BME680_GH3_REG),
     70};
     71
     72static const struct regmap_access_table bme680_volatile_table = {
     73	.yes_ranges	= bme680_volatile_ranges,
     74	.n_yes_ranges	= ARRAY_SIZE(bme680_volatile_ranges),
     75};
     76
     77const struct regmap_config bme680_regmap_config = {
     78	.reg_bits = 8,
     79	.val_bits = 8,
     80	.max_register = 0xef,
     81	.volatile_table = &bme680_volatile_table,
     82	.cache_type = REGCACHE_RBTREE,
     83};
     84EXPORT_SYMBOL_NS(bme680_regmap_config, IIO_BME680);
     85
     86static const struct iio_chan_spec bme680_channels[] = {
     87	{
     88		.type = IIO_TEMP,
     89		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
     90				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
     91	},
     92	{
     93		.type = IIO_PRESSURE,
     94		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
     95				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
     96	},
     97	{
     98		.type = IIO_HUMIDITYRELATIVE,
     99		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
    100				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
    101	},
    102	{
    103		.type = IIO_RESISTANCE,
    104		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
    105	},
    106};
    107
    108static int bme680_read_calib(struct bme680_data *data,
    109			     struct bme680_calib *calib)
    110{
    111	struct device *dev = regmap_get_device(data->regmap);
    112	unsigned int tmp, tmp_msb, tmp_lsb;
    113	int ret;
    114	__le16 buf;
    115
    116	/* Temperature related coefficients */
    117	ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG,
    118			       &buf, sizeof(buf));
    119	if (ret < 0) {
    120		dev_err(dev, "failed to read BME680_T1_LSB_REG\n");
    121		return ret;
    122	}
    123	calib->par_t1 = le16_to_cpu(buf);
    124
    125	ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG,
    126			       &buf, sizeof(buf));
    127	if (ret < 0) {
    128		dev_err(dev, "failed to read BME680_T2_LSB_REG\n");
    129		return ret;
    130	}
    131	calib->par_t2 = le16_to_cpu(buf);
    132
    133	ret = regmap_read(data->regmap, BME680_T3_REG, &tmp);
    134	if (ret < 0) {
    135		dev_err(dev, "failed to read BME680_T3_REG\n");
    136		return ret;
    137	}
    138	calib->par_t3 = tmp;
    139
    140	/* Pressure related coefficients */
    141	ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG,
    142			       &buf, sizeof(buf));
    143	if (ret < 0) {
    144		dev_err(dev, "failed to read BME680_P1_LSB_REG\n");
    145		return ret;
    146	}
    147	calib->par_p1 = le16_to_cpu(buf);
    148
    149	ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG,
    150			       &buf, sizeof(buf));
    151	if (ret < 0) {
    152		dev_err(dev, "failed to read BME680_P2_LSB_REG\n");
    153		return ret;
    154	}
    155	calib->par_p2 = le16_to_cpu(buf);
    156
    157	ret = regmap_read(data->regmap, BME680_P3_REG, &tmp);
    158	if (ret < 0) {
    159		dev_err(dev, "failed to read BME680_P3_REG\n");
    160		return ret;
    161	}
    162	calib->par_p3 = tmp;
    163
    164	ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG,
    165			       &buf, sizeof(buf));
    166	if (ret < 0) {
    167		dev_err(dev, "failed to read BME680_P4_LSB_REG\n");
    168		return ret;
    169	}
    170	calib->par_p4 = le16_to_cpu(buf);
    171
    172	ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG,
    173			       &buf, sizeof(buf));
    174	if (ret < 0) {
    175		dev_err(dev, "failed to read BME680_P5_LSB_REG\n");
    176		return ret;
    177	}
    178	calib->par_p5 = le16_to_cpu(buf);
    179
    180	ret = regmap_read(data->regmap, BME680_P6_REG, &tmp);
    181	if (ret < 0) {
    182		dev_err(dev, "failed to read BME680_P6_REG\n");
    183		return ret;
    184	}
    185	calib->par_p6 = tmp;
    186
    187	ret = regmap_read(data->regmap, BME680_P7_REG, &tmp);
    188	if (ret < 0) {
    189		dev_err(dev, "failed to read BME680_P7_REG\n");
    190		return ret;
    191	}
    192	calib->par_p7 = tmp;
    193
    194	ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG,
    195			       &buf, sizeof(buf));
    196	if (ret < 0) {
    197		dev_err(dev, "failed to read BME680_P8_LSB_REG\n");
    198		return ret;
    199	}
    200	calib->par_p8 = le16_to_cpu(buf);
    201
    202	ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG,
    203			       &buf, sizeof(buf));
    204	if (ret < 0) {
    205		dev_err(dev, "failed to read BME680_P9_LSB_REG\n");
    206		return ret;
    207	}
    208	calib->par_p9 = le16_to_cpu(buf);
    209
    210	ret = regmap_read(data->regmap, BME680_P10_REG, &tmp);
    211	if (ret < 0) {
    212		dev_err(dev, "failed to read BME680_P10_REG\n");
    213		return ret;
    214	}
    215	calib->par_p10 = tmp;
    216
    217	/* Humidity related coefficients */
    218	ret = regmap_read(data->regmap, BME680_H1_MSB_REG, &tmp_msb);
    219	if (ret < 0) {
    220		dev_err(dev, "failed to read BME680_H1_MSB_REG\n");
    221		return ret;
    222	}
    223	ret = regmap_read(data->regmap, BME680_H1_LSB_REG, &tmp_lsb);
    224	if (ret < 0) {
    225		dev_err(dev, "failed to read BME680_H1_LSB_REG\n");
    226		return ret;
    227	}
    228	calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
    229			(tmp_lsb & BME680_BIT_H1_DATA_MASK);
    230
    231	ret = regmap_read(data->regmap, BME680_H2_MSB_REG, &tmp_msb);
    232	if (ret < 0) {
    233		dev_err(dev, "failed to read BME680_H2_MSB_REG\n");
    234		return ret;
    235	}
    236	ret = regmap_read(data->regmap, BME680_H2_LSB_REG, &tmp_lsb);
    237	if (ret < 0) {
    238		dev_err(dev, "failed to read BME680_H2_LSB_REG\n");
    239		return ret;
    240	}
    241	calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
    242			(tmp_lsb >> BME680_HUM_REG_SHIFT_VAL);
    243
    244	ret = regmap_read(data->regmap, BME680_H3_REG, &tmp);
    245	if (ret < 0) {
    246		dev_err(dev, "failed to read BME680_H3_REG\n");
    247		return ret;
    248	}
    249	calib->par_h3 = tmp;
    250
    251	ret = regmap_read(data->regmap, BME680_H4_REG, &tmp);
    252	if (ret < 0) {
    253		dev_err(dev, "failed to read BME680_H4_REG\n");
    254		return ret;
    255	}
    256	calib->par_h4 = tmp;
    257
    258	ret = regmap_read(data->regmap, BME680_H5_REG, &tmp);
    259	if (ret < 0) {
    260		dev_err(dev, "failed to read BME680_H5_REG\n");
    261		return ret;
    262	}
    263	calib->par_h5 = tmp;
    264
    265	ret = regmap_read(data->regmap, BME680_H6_REG, &tmp);
    266	if (ret < 0) {
    267		dev_err(dev, "failed to read BME680_H6_REG\n");
    268		return ret;
    269	}
    270	calib->par_h6 = tmp;
    271
    272	ret = regmap_read(data->regmap, BME680_H7_REG, &tmp);
    273	if (ret < 0) {
    274		dev_err(dev, "failed to read BME680_H7_REG\n");
    275		return ret;
    276	}
    277	calib->par_h7 = tmp;
    278
    279	/* Gas heater related coefficients */
    280	ret = regmap_read(data->regmap, BME680_GH1_REG, &tmp);
    281	if (ret < 0) {
    282		dev_err(dev, "failed to read BME680_GH1_REG\n");
    283		return ret;
    284	}
    285	calib->par_gh1 = tmp;
    286
    287	ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG,
    288			       &buf, sizeof(buf));
    289	if (ret < 0) {
    290		dev_err(dev, "failed to read BME680_GH2_LSB_REG\n");
    291		return ret;
    292	}
    293	calib->par_gh2 = le16_to_cpu(buf);
    294
    295	ret = regmap_read(data->regmap, BME680_GH3_REG, &tmp);
    296	if (ret < 0) {
    297		dev_err(dev, "failed to read BME680_GH3_REG\n");
    298		return ret;
    299	}
    300	calib->par_gh3 = tmp;
    301
    302	/* Other coefficients */
    303	ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_RANGE, &tmp);
    304	if (ret < 0) {
    305		dev_err(dev, "failed to read resistance heat range\n");
    306		return ret;
    307	}
    308	calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK, tmp);
    309
    310	ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_VAL, &tmp);
    311	if (ret < 0) {
    312		dev_err(dev, "failed to read resistance heat value\n");
    313		return ret;
    314	}
    315	calib->res_heat_val = tmp;
    316
    317	ret = regmap_read(data->regmap, BME680_REG_RANGE_SW_ERR, &tmp);
    318	if (ret < 0) {
    319		dev_err(dev, "failed to read range software error\n");
    320		return ret;
    321	}
    322	calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK, tmp);
    323
    324	return 0;
    325}
    326
    327/*
    328 * Taken from Bosch BME680 API:
    329 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L876
    330 *
    331 * Returns temperature measurement in DegC, resolutions is 0.01 DegC. Therefore,
    332 * output value of "3233" represents 32.33 DegC.
    333 */
    334static s16 bme680_compensate_temp(struct bme680_data *data,
    335				  s32 adc_temp)
    336{
    337	struct bme680_calib *calib = &data->bme680;
    338	s64 var1, var2, var3;
    339	s16 calc_temp;
    340
    341	/* If the calibration is invalid, attempt to reload it */
    342	if (!calib->par_t2)
    343		bme680_read_calib(data, calib);
    344
    345	var1 = (adc_temp >> 3) - (calib->par_t1 << 1);
    346	var2 = (var1 * calib->par_t2) >> 11;
    347	var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
    348	var3 = (var3 * (calib->par_t3 << 4)) >> 14;
    349	data->t_fine = var2 + var3;
    350	calc_temp = (data->t_fine * 5 + 128) >> 8;
    351
    352	return calc_temp;
    353}
    354
    355/*
    356 * Taken from Bosch BME680 API:
    357 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L896
    358 *
    359 * Returns pressure measurement in Pa. Output value of "97356" represents
    360 * 97356 Pa = 973.56 hPa.
    361 */
    362static u32 bme680_compensate_press(struct bme680_data *data,
    363				   u32 adc_press)
    364{
    365	struct bme680_calib *calib = &data->bme680;
    366	s32 var1, var2, var3, press_comp;
    367
    368	var1 = (data->t_fine >> 1) - 64000;
    369	var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2;
    370	var2 = var2 + (var1 * calib->par_p5 << 1);
    371	var2 = (var2 >> 2) + (calib->par_p4 << 16);
    372	var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
    373			(calib->par_p3 << 5)) >> 3) +
    374			((calib->par_p2 * var1) >> 1);
    375	var1 = var1 >> 18;
    376	var1 = ((32768 + var1) * calib->par_p1) >> 15;
    377	press_comp = 1048576 - adc_press;
    378	press_comp = ((press_comp - (var2 >> 12)) * 3125);
    379
    380	if (press_comp >= BME680_MAX_OVERFLOW_VAL)
    381		press_comp = ((press_comp / (u32)var1) << 1);
    382	else
    383		press_comp = ((press_comp << 1) / (u32)var1);
    384
    385	var1 = (calib->par_p9 * (((press_comp >> 3) *
    386			(press_comp >> 3)) >> 13)) >> 12;
    387	var2 = ((press_comp >> 2) * calib->par_p8) >> 13;
    388	var3 = ((press_comp >> 8) * (press_comp >> 8) *
    389			(press_comp >> 8) * calib->par_p10) >> 17;
    390
    391	press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4;
    392
    393	return press_comp;
    394}
    395
    396/*
    397 * Taken from Bosch BME680 API:
    398 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L937
    399 *
    400 * Returns humidity measurement in percent, resolution is 0.001 percent. Output
    401 * value of "43215" represents 43.215 %rH.
    402 */
    403static u32 bme680_compensate_humid(struct bme680_data *data,
    404				   u16 adc_humid)
    405{
    406	struct bme680_calib *calib = &data->bme680;
    407	s32 var1, var2, var3, var4, var5, var6, temp_scaled, calc_hum;
    408
    409	temp_scaled = (data->t_fine * 5 + 128) >> 8;
    410	var1 = (adc_humid - ((s32) ((s32) calib->par_h1 * 16))) -
    411		(((temp_scaled * (s32) calib->par_h3) / 100) >> 1);
    412	var2 = ((s32) calib->par_h2 *
    413		(((temp_scaled * calib->par_h4) / 100) +
    414		 (((temp_scaled * ((temp_scaled * calib->par_h5) / 100))
    415		   >> 6) / 100) + (1 << 14))) >> 10;
    416	var3 = var1 * var2;
    417	var4 = calib->par_h6 << 7;
    418	var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4;
    419	var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
    420	var6 = (var4 * var5) >> 1;
    421	calc_hum = (((var3 + var6) >> 10) * 1000) >> 12;
    422
    423	calc_hum = clamp(calc_hum, 0, 100000); /* clamp between 0-100 %rH */
    424
    425	return calc_hum;
    426}
    427
    428/*
    429 * Taken from Bosch BME680 API:
    430 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L973
    431 *
    432 * Returns gas measurement in Ohm. Output value of "82986" represent 82986 ohms.
    433 */
    434static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc,
    435				 u8 gas_range)
    436{
    437	struct bme680_calib *calib = &data->bme680;
    438	s64 var1;
    439	u64 var2;
    440	s64 var3;
    441	u32 calc_gas_res;
    442
    443	/* Look up table for the possible gas range values */
    444	const u32 lookupTable[16] = {2147483647u, 2147483647u,
    445				2147483647u, 2147483647u, 2147483647u,
    446				2126008810u, 2147483647u, 2130303777u,
    447				2147483647u, 2147483647u, 2143188679u,
    448				2136746228u, 2147483647u, 2126008810u,
    449				2147483647u, 2147483647u};
    450
    451	var1 = ((1340 + (5 * (s64) calib->range_sw_err)) *
    452			((s64) lookupTable[gas_range])) >> 16;
    453	var2 = ((gas_res_adc << 15) - 16777216) + var1;
    454	var3 = ((125000 << (15 - gas_range)) * var1) >> 9;
    455	var3 += (var2 >> 1);
    456	calc_gas_res = div64_s64(var3, (s64) var2);
    457
    458	return calc_gas_res;
    459}
    460
    461/*
    462 * Taken from Bosch BME680 API:
    463 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1002
    464 */
    465static u8 bme680_calc_heater_res(struct bme680_data *data, u16 temp)
    466{
    467	struct bme680_calib *calib = &data->bme680;
    468	s32 var1, var2, var3, var4, var5, heatr_res_x100;
    469	u8 heatr_res;
    470
    471	if (temp > 400) /* Cap temperature */
    472		temp = 400;
    473
    474	var1 = (((s32) BME680_AMB_TEMP * calib->par_gh3) / 1000) * 256;
    475	var2 = (calib->par_gh1 + 784) * (((((calib->par_gh2 + 154009) *
    476						temp * 5) / 100)
    477						+ 3276800) / 10);
    478	var3 = var1 + (var2 / 2);
    479	var4 = (var3 / (calib->res_heat_range + 4));
    480	var5 = 131 * calib->res_heat_val + 65536;
    481	heatr_res_x100 = ((var4 / var5) - 250) * 34;
    482	heatr_res = DIV_ROUND_CLOSEST(heatr_res_x100, 100);
    483
    484	return heatr_res;
    485}
    486
    487/*
    488 * Taken from Bosch BME680 API:
    489 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L1188
    490 */
    491static u8 bme680_calc_heater_dur(u16 dur)
    492{
    493	u8 durval, factor = 0;
    494
    495	if (dur >= 0xfc0) {
    496		durval = 0xff; /* Max duration */
    497	} else {
    498		while (dur > 0x3F) {
    499			dur = dur / 4;
    500			factor += 1;
    501		}
    502		durval = dur + (factor * 64);
    503	}
    504
    505	return durval;
    506}
    507
    508static int bme680_set_mode(struct bme680_data *data, bool mode)
    509{
    510	struct device *dev = regmap_get_device(data->regmap);
    511	int ret;
    512
    513	if (mode) {
    514		ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
    515					BME680_MODE_MASK, BME680_MODE_FORCED);
    516		if (ret < 0)
    517			dev_err(dev, "failed to set forced mode\n");
    518
    519	} else {
    520		ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
    521					BME680_MODE_MASK, BME680_MODE_SLEEP);
    522		if (ret < 0)
    523			dev_err(dev, "failed to set sleep mode\n");
    524
    525	}
    526
    527	return ret;
    528}
    529
    530static u8 bme680_oversampling_to_reg(u8 val)
    531{
    532	return ilog2(val) + 1;
    533}
    534
    535static int bme680_chip_config(struct bme680_data *data)
    536{
    537	struct device *dev = regmap_get_device(data->regmap);
    538	int ret;
    539	u8 osrs;
    540
    541	osrs = FIELD_PREP(
    542		BME680_OSRS_HUMIDITY_MASK,
    543		bme680_oversampling_to_reg(data->oversampling_humid));
    544	/*
    545	 * Highly recommended to set oversampling of humidity before
    546	 * temperature/pressure oversampling.
    547	 */
    548	ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_HUMIDITY,
    549				 BME680_OSRS_HUMIDITY_MASK, osrs);
    550	if (ret < 0) {
    551		dev_err(dev, "failed to write ctrl_hum register\n");
    552		return ret;
    553	}
    554
    555	/* IIR filter settings */
    556	ret = regmap_update_bits(data->regmap, BME680_REG_CONFIG,
    557				 BME680_FILTER_MASK,
    558				 BME680_FILTER_COEFF_VAL);
    559	if (ret < 0) {
    560		dev_err(dev, "failed to write config register\n");
    561		return ret;
    562	}
    563
    564	osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK,
    565			  bme680_oversampling_to_reg(data->oversampling_temp)) |
    566	       FIELD_PREP(BME680_OSRS_PRESS_MASK,
    567			  bme680_oversampling_to_reg(data->oversampling_press));
    568	ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
    569				BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK,
    570				osrs);
    571	if (ret < 0)
    572		dev_err(dev, "failed to write ctrl_meas register\n");
    573
    574	return ret;
    575}
    576
    577static int bme680_gas_config(struct bme680_data *data)
    578{
    579	struct device *dev = regmap_get_device(data->regmap);
    580	int ret;
    581	u8 heatr_res, heatr_dur;
    582
    583	heatr_res = bme680_calc_heater_res(data, data->heater_temp);
    584
    585	/* set target heater temperature */
    586	ret = regmap_write(data->regmap, BME680_REG_RES_HEAT_0, heatr_res);
    587	if (ret < 0) {
    588		dev_err(dev, "failed to write res_heat_0 register\n");
    589		return ret;
    590	}
    591
    592	heatr_dur = bme680_calc_heater_dur(data->heater_dur);
    593
    594	/* set target heating duration */
    595	ret = regmap_write(data->regmap, BME680_REG_GAS_WAIT_0, heatr_dur);
    596	if (ret < 0) {
    597		dev_err(dev, "failed to write gas_wait_0 register\n");
    598		return ret;
    599	}
    600
    601	/* Enable the gas sensor and select heater profile set-point 0 */
    602	ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_GAS_1,
    603				 BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK,
    604				 FIELD_PREP(BME680_RUN_GAS_MASK, 1) |
    605				 FIELD_PREP(BME680_NB_CONV_MASK, 0));
    606	if (ret < 0)
    607		dev_err(dev, "failed to write ctrl_gas_1 register\n");
    608
    609	return ret;
    610}
    611
    612static int bme680_read_temp(struct bme680_data *data, int *val)
    613{
    614	struct device *dev = regmap_get_device(data->regmap);
    615	int ret;
    616	__be32 tmp = 0;
    617	s32 adc_temp;
    618	s16 comp_temp;
    619
    620	/* set forced mode to trigger measurement */
    621	ret = bme680_set_mode(data, true);
    622	if (ret < 0)
    623		return ret;
    624
    625	ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
    626			       &tmp, 3);
    627	if (ret < 0) {
    628		dev_err(dev, "failed to read temperature\n");
    629		return ret;
    630	}
    631
    632	adc_temp = be32_to_cpu(tmp) >> 12;
    633	if (adc_temp == BME680_MEAS_SKIPPED) {
    634		/* reading was skipped */
    635		dev_err(dev, "reading temperature skipped\n");
    636		return -EINVAL;
    637	}
    638	comp_temp = bme680_compensate_temp(data, adc_temp);
    639	/*
    640	 * val might be NULL if we're called by the read_press/read_humid
    641	 * routine which is callled to get t_fine value used in
    642	 * compensate_press/compensate_humid to get compensated
    643	 * pressure/humidity readings.
    644	 */
    645	if (val) {
    646		*val = comp_temp * 10; /* Centidegrees to millidegrees */
    647		return IIO_VAL_INT;
    648	}
    649
    650	return ret;
    651}
    652
    653static int bme680_read_press(struct bme680_data *data,
    654			     int *val, int *val2)
    655{
    656	struct device *dev = regmap_get_device(data->regmap);
    657	int ret;
    658	__be32 tmp = 0;
    659	s32 adc_press;
    660
    661	/* Read and compensate temperature to get a reading of t_fine */
    662	ret = bme680_read_temp(data, NULL);
    663	if (ret < 0)
    664		return ret;
    665
    666	ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,
    667			       &tmp, 3);
    668	if (ret < 0) {
    669		dev_err(dev, "failed to read pressure\n");
    670		return ret;
    671	}
    672
    673	adc_press = be32_to_cpu(tmp) >> 12;
    674	if (adc_press == BME680_MEAS_SKIPPED) {
    675		/* reading was skipped */
    676		dev_err(dev, "reading pressure skipped\n");
    677		return -EINVAL;
    678	}
    679
    680	*val = bme680_compensate_press(data, adc_press);
    681	*val2 = 100;
    682	return IIO_VAL_FRACTIONAL;
    683}
    684
    685static int bme680_read_humid(struct bme680_data *data,
    686			     int *val, int *val2)
    687{
    688	struct device *dev = regmap_get_device(data->regmap);
    689	int ret;
    690	__be16 tmp = 0;
    691	s32 adc_humidity;
    692	u32 comp_humidity;
    693
    694	/* Read and compensate temperature to get a reading of t_fine */
    695	ret = bme680_read_temp(data, NULL);
    696	if (ret < 0)
    697		return ret;
    698
    699	ret = regmap_bulk_read(data->regmap, BM6880_REG_HUMIDITY_MSB,
    700			       &tmp, sizeof(tmp));
    701	if (ret < 0) {
    702		dev_err(dev, "failed to read humidity\n");
    703		return ret;
    704	}
    705
    706	adc_humidity = be16_to_cpu(tmp);
    707	if (adc_humidity == BME680_MEAS_SKIPPED) {
    708		/* reading was skipped */
    709		dev_err(dev, "reading humidity skipped\n");
    710		return -EINVAL;
    711	}
    712	comp_humidity = bme680_compensate_humid(data, adc_humidity);
    713
    714	*val = comp_humidity;
    715	*val2 = 1000;
    716	return IIO_VAL_FRACTIONAL;
    717}
    718
    719static int bme680_read_gas(struct bme680_data *data,
    720			   int *val)
    721{
    722	struct device *dev = regmap_get_device(data->regmap);
    723	int ret;
    724	__be16 tmp = 0;
    725	unsigned int check;
    726	u16 adc_gas_res;
    727	u8 gas_range;
    728
    729	/* Set heater settings */
    730	ret = bme680_gas_config(data);
    731	if (ret < 0) {
    732		dev_err(dev, "failed to set gas config\n");
    733		return ret;
    734	}
    735
    736	/* set forced mode to trigger measurement */
    737	ret = bme680_set_mode(data, true);
    738	if (ret < 0)
    739		return ret;
    740
    741	ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
    742	if (check & BME680_GAS_MEAS_BIT) {
    743		dev_err(dev, "gas measurement incomplete\n");
    744		return -EBUSY;
    745	}
    746
    747	ret = regmap_read(data->regmap, BME680_REG_GAS_R_LSB, &check);
    748	if (ret < 0) {
    749		dev_err(dev, "failed to read gas_r_lsb register\n");
    750		return ret;
    751	}
    752
    753	/*
    754	 * occurs if either the gas heating duration was insuffient
    755	 * to reach the target heater temperature or the target
    756	 * heater temperature was too high for the heater sink to
    757	 * reach.
    758	 */
    759	if ((check & BME680_GAS_STAB_BIT) == 0) {
    760		dev_err(dev, "heater failed to reach the target temperature\n");
    761		return -EINVAL;
    762	}
    763
    764	ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,
    765			       &tmp, sizeof(tmp));
    766	if (ret < 0) {
    767		dev_err(dev, "failed to read gas resistance\n");
    768		return ret;
    769	}
    770
    771	gas_range = check & BME680_GAS_RANGE_MASK;
    772	adc_gas_res = be16_to_cpu(tmp) >> BME680_ADC_GAS_RES_SHIFT;
    773
    774	*val = bme680_compensate_gas(data, adc_gas_res, gas_range);
    775	return IIO_VAL_INT;
    776}
    777
    778static int bme680_read_raw(struct iio_dev *indio_dev,
    779			   struct iio_chan_spec const *chan,
    780			   int *val, int *val2, long mask)
    781{
    782	struct bme680_data *data = iio_priv(indio_dev);
    783
    784	switch (mask) {
    785	case IIO_CHAN_INFO_PROCESSED:
    786		switch (chan->type) {
    787		case IIO_TEMP:
    788			return bme680_read_temp(data, val);
    789		case IIO_PRESSURE:
    790			return bme680_read_press(data, val, val2);
    791		case IIO_HUMIDITYRELATIVE:
    792			return bme680_read_humid(data, val, val2);
    793		case IIO_RESISTANCE:
    794			return bme680_read_gas(data, val);
    795		default:
    796			return -EINVAL;
    797		}
    798	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
    799		switch (chan->type) {
    800		case IIO_TEMP:
    801			*val = data->oversampling_temp;
    802			return IIO_VAL_INT;
    803		case IIO_PRESSURE:
    804			*val = data->oversampling_press;
    805			return IIO_VAL_INT;
    806		case IIO_HUMIDITYRELATIVE:
    807			*val = data->oversampling_humid;
    808			return IIO_VAL_INT;
    809		default:
    810			return -EINVAL;
    811		}
    812	default:
    813		return -EINVAL;
    814	}
    815}
    816
    817static bool bme680_is_valid_oversampling(int rate)
    818{
    819	return (rate > 0 && rate <= 16 && is_power_of_2(rate));
    820}
    821
    822static int bme680_write_raw(struct iio_dev *indio_dev,
    823			    struct iio_chan_spec const *chan,
    824			    int val, int val2, long mask)
    825{
    826	struct bme680_data *data = iio_priv(indio_dev);
    827
    828	if (val2 != 0)
    829		return -EINVAL;
    830
    831	switch (mask) {
    832	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
    833	{
    834		if (!bme680_is_valid_oversampling(val))
    835			return -EINVAL;
    836
    837		switch (chan->type) {
    838		case IIO_TEMP:
    839			data->oversampling_temp = val;
    840			break;
    841		case IIO_PRESSURE:
    842			data->oversampling_press = val;
    843			break;
    844		case IIO_HUMIDITYRELATIVE:
    845			data->oversampling_humid = val;
    846			break;
    847		default:
    848			return -EINVAL;
    849		}
    850
    851		return bme680_chip_config(data);
    852	}
    853	default:
    854		return -EINVAL;
    855	}
    856}
    857
    858static const char bme680_oversampling_ratio_show[] = "1 2 4 8 16";
    859
    860static IIO_CONST_ATTR(oversampling_ratio_available,
    861		      bme680_oversampling_ratio_show);
    862
    863static struct attribute *bme680_attributes[] = {
    864	&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
    865	NULL,
    866};
    867
    868static const struct attribute_group bme680_attribute_group = {
    869	.attrs = bme680_attributes,
    870};
    871
    872static const struct iio_info bme680_info = {
    873	.read_raw = &bme680_read_raw,
    874	.write_raw = &bme680_write_raw,
    875	.attrs = &bme680_attribute_group,
    876};
    877
    878static const char *bme680_match_acpi_device(struct device *dev)
    879{
    880	const struct acpi_device_id *id;
    881
    882	id = acpi_match_device(dev->driver->acpi_match_table, dev);
    883	if (!id)
    884		return NULL;
    885
    886	return dev_name(dev);
    887}
    888
    889int bme680_core_probe(struct device *dev, struct regmap *regmap,
    890		      const char *name)
    891{
    892	struct iio_dev *indio_dev;
    893	struct bme680_data *data;
    894	unsigned int val;
    895	int ret;
    896
    897	ret = regmap_write(regmap, BME680_REG_SOFT_RESET,
    898			   BME680_CMD_SOFTRESET);
    899	if (ret < 0) {
    900		dev_err(dev, "Failed to reset chip\n");
    901		return ret;
    902	}
    903
    904	ret = regmap_read(regmap, BME680_REG_CHIP_ID, &val);
    905	if (ret < 0) {
    906		dev_err(dev, "Error reading chip ID\n");
    907		return ret;
    908	}
    909
    910	if (val != BME680_CHIP_ID_VAL) {
    911		dev_err(dev, "Wrong chip ID, got %x expected %x\n",
    912				val, BME680_CHIP_ID_VAL);
    913		return -ENODEV;
    914	}
    915
    916	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
    917	if (!indio_dev)
    918		return -ENOMEM;
    919
    920	if (!name && ACPI_HANDLE(dev))
    921		name = bme680_match_acpi_device(dev);
    922
    923	data = iio_priv(indio_dev);
    924	dev_set_drvdata(dev, indio_dev);
    925	data->regmap = regmap;
    926	indio_dev->name = name;
    927	indio_dev->channels = bme680_channels;
    928	indio_dev->num_channels = ARRAY_SIZE(bme680_channels);
    929	indio_dev->info = &bme680_info;
    930	indio_dev->modes = INDIO_DIRECT_MODE;
    931
    932	/* default values for the sensor */
    933	data->oversampling_humid = 2; /* 2X oversampling rate */
    934	data->oversampling_press = 4; /* 4X oversampling rate */
    935	data->oversampling_temp = 8;  /* 8X oversampling rate */
    936	data->heater_temp = 320; /* degree Celsius */
    937	data->heater_dur = 150;  /* milliseconds */
    938
    939	ret = bme680_chip_config(data);
    940	if (ret < 0) {
    941		dev_err(dev, "failed to set chip_config data\n");
    942		return ret;
    943	}
    944
    945	ret = bme680_gas_config(data);
    946	if (ret < 0) {
    947		dev_err(dev, "failed to set gas config data\n");
    948		return ret;
    949	}
    950
    951	ret = bme680_read_calib(data, &data->bme680);
    952	if (ret < 0) {
    953		dev_err(dev,
    954			"failed to read calibration coefficients at probe\n");
    955		return ret;
    956	}
    957
    958	return devm_iio_device_register(dev, indio_dev);
    959}
    960EXPORT_SYMBOL_NS_GPL(bme680_core_probe, IIO_BME680);
    961
    962MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>");
    963MODULE_DESCRIPTION("Bosch BME680 Driver");
    964MODULE_LICENSE("GPL v2");