| .. | .. |
|---|
| 105 | 105 | }, |
|---|
| 106 | 106 | }; |
|---|
| 107 | 107 | |
|---|
| 108 | | -static const int bme680_oversampling_avail[] = { 1, 2, 4, 8, 16 }; |
|---|
| 109 | | - |
|---|
| 110 | 108 | static int bme680_read_calib(struct bme680_data *data, |
|---|
| 111 | 109 | struct bme680_calib *calib) |
|---|
| 112 | 110 | { |
|---|
| .. | .. |
|---|
| 117 | 115 | |
|---|
| 118 | 116 | /* Temperature related coefficients */ |
|---|
| 119 | 117 | ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG, |
|---|
| 120 | | - (u8 *) &buf, 2); |
|---|
| 118 | + &buf, sizeof(buf)); |
|---|
| 121 | 119 | if (ret < 0) { |
|---|
| 122 | 120 | dev_err(dev, "failed to read BME680_T1_LSB_REG\n"); |
|---|
| 123 | 121 | return ret; |
|---|
| .. | .. |
|---|
| 125 | 123 | calib->par_t1 = le16_to_cpu(buf); |
|---|
| 126 | 124 | |
|---|
| 127 | 125 | ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG, |
|---|
| 128 | | - (u8 *) &buf, 2); |
|---|
| 126 | + &buf, sizeof(buf)); |
|---|
| 129 | 127 | if (ret < 0) { |
|---|
| 130 | 128 | dev_err(dev, "failed to read BME680_T2_LSB_REG\n"); |
|---|
| 131 | 129 | return ret; |
|---|
| .. | .. |
|---|
| 141 | 139 | |
|---|
| 142 | 140 | /* Pressure related coefficients */ |
|---|
| 143 | 141 | ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG, |
|---|
| 144 | | - (u8 *) &buf, 2); |
|---|
| 142 | + &buf, sizeof(buf)); |
|---|
| 145 | 143 | if (ret < 0) { |
|---|
| 146 | 144 | dev_err(dev, "failed to read BME680_P1_LSB_REG\n"); |
|---|
| 147 | 145 | return ret; |
|---|
| .. | .. |
|---|
| 149 | 147 | calib->par_p1 = le16_to_cpu(buf); |
|---|
| 150 | 148 | |
|---|
| 151 | 149 | ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG, |
|---|
| 152 | | - (u8 *) &buf, 2); |
|---|
| 150 | + &buf, sizeof(buf)); |
|---|
| 153 | 151 | if (ret < 0) { |
|---|
| 154 | 152 | dev_err(dev, "failed to read BME680_P2_LSB_REG\n"); |
|---|
| 155 | 153 | return ret; |
|---|
| .. | .. |
|---|
| 164 | 162 | calib->par_p3 = tmp; |
|---|
| 165 | 163 | |
|---|
| 166 | 164 | ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG, |
|---|
| 167 | | - (u8 *) &buf, 2); |
|---|
| 165 | + &buf, sizeof(buf)); |
|---|
| 168 | 166 | if (ret < 0) { |
|---|
| 169 | 167 | dev_err(dev, "failed to read BME680_P4_LSB_REG\n"); |
|---|
| 170 | 168 | return ret; |
|---|
| .. | .. |
|---|
| 172 | 170 | calib->par_p4 = le16_to_cpu(buf); |
|---|
| 173 | 171 | |
|---|
| 174 | 172 | ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG, |
|---|
| 175 | | - (u8 *) &buf, 2); |
|---|
| 173 | + &buf, sizeof(buf)); |
|---|
| 176 | 174 | if (ret < 0) { |
|---|
| 177 | 175 | dev_err(dev, "failed to read BME680_P5_LSB_REG\n"); |
|---|
| 178 | 176 | return ret; |
|---|
| .. | .. |
|---|
| 194 | 192 | calib->par_p7 = tmp; |
|---|
| 195 | 193 | |
|---|
| 196 | 194 | ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG, |
|---|
| 197 | | - (u8 *) &buf, 2); |
|---|
| 195 | + &buf, sizeof(buf)); |
|---|
| 198 | 196 | if (ret < 0) { |
|---|
| 199 | 197 | dev_err(dev, "failed to read BME680_P8_LSB_REG\n"); |
|---|
| 200 | 198 | return ret; |
|---|
| .. | .. |
|---|
| 202 | 200 | calib->par_p8 = le16_to_cpu(buf); |
|---|
| 203 | 201 | |
|---|
| 204 | 202 | ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG, |
|---|
| 205 | | - (u8 *) &buf, 2); |
|---|
| 203 | + &buf, sizeof(buf)); |
|---|
| 206 | 204 | if (ret < 0) { |
|---|
| 207 | 205 | dev_err(dev, "failed to read BME680_P9_LSB_REG\n"); |
|---|
| 208 | 206 | return ret; |
|---|
| .. | .. |
|---|
| 222 | 220 | dev_err(dev, "failed to read BME680_H1_MSB_REG\n"); |
|---|
| 223 | 221 | return ret; |
|---|
| 224 | 222 | } |
|---|
| 225 | | - |
|---|
| 226 | 223 | ret = regmap_read(data->regmap, BME680_H1_LSB_REG, &tmp_lsb); |
|---|
| 227 | 224 | if (ret < 0) { |
|---|
| 228 | 225 | dev_err(dev, "failed to read BME680_H1_LSB_REG\n"); |
|---|
| 229 | 226 | return ret; |
|---|
| 230 | 227 | } |
|---|
| 231 | | - |
|---|
| 232 | 228 | calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) | |
|---|
| 233 | | - (tmp_lsb & BME680_BIT_H1_DATA_MSK); |
|---|
| 229 | + (tmp_lsb & BME680_BIT_H1_DATA_MASK); |
|---|
| 234 | 230 | |
|---|
| 235 | 231 | ret = regmap_read(data->regmap, BME680_H2_MSB_REG, &tmp_msb); |
|---|
| 236 | 232 | if (ret < 0) { |
|---|
| 237 | 233 | dev_err(dev, "failed to read BME680_H2_MSB_REG\n"); |
|---|
| 238 | 234 | return ret; |
|---|
| 239 | 235 | } |
|---|
| 240 | | - |
|---|
| 241 | 236 | ret = regmap_read(data->regmap, BME680_H2_LSB_REG, &tmp_lsb); |
|---|
| 242 | 237 | if (ret < 0) { |
|---|
| 243 | 238 | dev_err(dev, "failed to read BME680_H2_LSB_REG\n"); |
|---|
| 244 | 239 | return ret; |
|---|
| 245 | 240 | } |
|---|
| 246 | | - |
|---|
| 247 | 241 | calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) | |
|---|
| 248 | | - (tmp_lsb >> BME680_HUM_REG_SHIFT_VAL); |
|---|
| 242 | + (tmp_lsb >> BME680_HUM_REG_SHIFT_VAL); |
|---|
| 249 | 243 | |
|---|
| 250 | 244 | ret = regmap_read(data->regmap, BME680_H3_REG, &tmp); |
|---|
| 251 | 245 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 291 | 285 | calib->par_gh1 = tmp; |
|---|
| 292 | 286 | |
|---|
| 293 | 287 | ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG, |
|---|
| 294 | | - (u8 *) &buf, 2); |
|---|
| 288 | + &buf, sizeof(buf)); |
|---|
| 295 | 289 | if (ret < 0) { |
|---|
| 296 | 290 | dev_err(dev, "failed to read BME680_GH2_LSB_REG\n"); |
|---|
| 297 | 291 | return ret; |
|---|
| .. | .. |
|---|
| 311 | 305 | dev_err(dev, "failed to read resistance heat range\n"); |
|---|
| 312 | 306 | return ret; |
|---|
| 313 | 307 | } |
|---|
| 314 | | - calib->res_heat_range = (tmp & BME680_RHRANGE_MSK) / 16; |
|---|
| 308 | + calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK, tmp); |
|---|
| 315 | 309 | |
|---|
| 316 | 310 | ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_VAL, &tmp); |
|---|
| 317 | 311 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 325 | 319 | dev_err(dev, "failed to read range software error\n"); |
|---|
| 326 | 320 | return ret; |
|---|
| 327 | 321 | } |
|---|
| 328 | | - calib->range_sw_err = (tmp & BME680_RSERROR_MSK) / 16; |
|---|
| 322 | + calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK, tmp); |
|---|
| 329 | 323 | |
|---|
| 330 | 324 | return 0; |
|---|
| 331 | 325 | } |
|---|
| .. | .. |
|---|
| 426 | 420 | var6 = (var4 * var5) >> 1; |
|---|
| 427 | 421 | calc_hum = (((var3 + var6) >> 10) * 1000) >> 12; |
|---|
| 428 | 422 | |
|---|
| 429 | | - if (calc_hum > 100000) /* Cap at 100%rH */ |
|---|
| 430 | | - calc_hum = 100000; |
|---|
| 431 | | - else if (calc_hum < 0) |
|---|
| 432 | | - calc_hum = 0; |
|---|
| 423 | + calc_hum = clamp(calc_hum, 0, 100000); /* clamp between 0-100 %rH */ |
|---|
| 433 | 424 | |
|---|
| 434 | 425 | return calc_hum; |
|---|
| 435 | 426 | } |
|---|
| .. | .. |
|---|
| 536 | 527 | return ret; |
|---|
| 537 | 528 | } |
|---|
| 538 | 529 | |
|---|
| 530 | +static u8 bme680_oversampling_to_reg(u8 val) |
|---|
| 531 | +{ |
|---|
| 532 | + return ilog2(val) + 1; |
|---|
| 533 | +} |
|---|
| 534 | + |
|---|
| 539 | 535 | static int bme680_chip_config(struct bme680_data *data) |
|---|
| 540 | 536 | { |
|---|
| 541 | 537 | struct device *dev = regmap_get_device(data->regmap); |
|---|
| 542 | 538 | int ret; |
|---|
| 543 | | - u8 osrs = FIELD_PREP(BME680_OSRS_HUMIDITY_MASK, |
|---|
| 544 | | - data->oversampling_humid + 1); |
|---|
| 539 | + u8 osrs; |
|---|
| 540 | + |
|---|
| 541 | + osrs = FIELD_PREP( |
|---|
| 542 | + BME680_OSRS_HUMIDITY_MASK, |
|---|
| 543 | + bme680_oversampling_to_reg(data->oversampling_humid)); |
|---|
| 545 | 544 | /* |
|---|
| 546 | 545 | * Highly recommended to set oversampling of humidity before |
|---|
| 547 | 546 | * temperature/pressure oversampling. |
|---|
| .. | .. |
|---|
| 562 | 561 | return ret; |
|---|
| 563 | 562 | } |
|---|
| 564 | 563 | |
|---|
| 565 | | - osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK, data->oversampling_temp + 1) | |
|---|
| 566 | | - FIELD_PREP(BME680_OSRS_PRESS_MASK, data->oversampling_press + 1); |
|---|
| 567 | | - |
|---|
| 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 | 568 | ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS, |
|---|
| 569 | | - BME680_OSRS_TEMP_MASK | |
|---|
| 570 | | - BME680_OSRS_PRESS_MASK, |
|---|
| 569 | + BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK, |
|---|
| 571 | 570 | osrs); |
|---|
| 572 | 571 | if (ret < 0) |
|---|
| 573 | 572 | dev_err(dev, "failed to write ctrl_meas register\n"); |
|---|
| .. | .. |
|---|
| 595 | 594 | /* set target heating duration */ |
|---|
| 596 | 595 | ret = regmap_write(data->regmap, BME680_REG_GAS_WAIT_0, heatr_dur); |
|---|
| 597 | 596 | if (ret < 0) { |
|---|
| 598 | | - dev_err(dev, "failted to write gas_wait_0 register\n"); |
|---|
| 597 | + dev_err(dev, "failed to write gas_wait_0 register\n"); |
|---|
| 599 | 598 | return ret; |
|---|
| 600 | 599 | } |
|---|
| 601 | 600 | |
|---|
| 602 | | - /* Selecting the runGas and NB conversion settings for the sensor */ |
|---|
| 601 | + /* Enable the gas sensor and select heater profile set-point 0 */ |
|---|
| 603 | 602 | ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_GAS_1, |
|---|
| 604 | 603 | BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK, |
|---|
| 605 | | - BME680_RUN_GAS_EN_BIT | BME680_NB_CONV_0_VAL); |
|---|
| 604 | + FIELD_PREP(BME680_RUN_GAS_MASK, 1) | |
|---|
| 605 | + FIELD_PREP(BME680_NB_CONV_MASK, 0)); |
|---|
| 606 | 606 | if (ret < 0) |
|---|
| 607 | 607 | dev_err(dev, "failed to write ctrl_gas_1 register\n"); |
|---|
| 608 | 608 | |
|---|
| .. | .. |
|---|
| 623 | 623 | return ret; |
|---|
| 624 | 624 | |
|---|
| 625 | 625 | ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB, |
|---|
| 626 | | - (u8 *) &tmp, 3); |
|---|
| 626 | + &tmp, 3); |
|---|
| 627 | 627 | if (ret < 0) { |
|---|
| 628 | 628 | dev_err(dev, "failed to read temperature\n"); |
|---|
| 629 | 629 | return ret; |
|---|
| .. | .. |
|---|
| 664 | 664 | return ret; |
|---|
| 665 | 665 | |
|---|
| 666 | 666 | ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB, |
|---|
| 667 | | - (u8 *) &tmp, 3); |
|---|
| 667 | + &tmp, 3); |
|---|
| 668 | 668 | if (ret < 0) { |
|---|
| 669 | 669 | dev_err(dev, "failed to read pressure\n"); |
|---|
| 670 | 670 | return ret; |
|---|
| .. | .. |
|---|
| 697 | 697 | return ret; |
|---|
| 698 | 698 | |
|---|
| 699 | 699 | ret = regmap_bulk_read(data->regmap, BM6880_REG_HUMIDITY_MSB, |
|---|
| 700 | | - (u8 *) &tmp, 2); |
|---|
| 700 | + &tmp, sizeof(tmp)); |
|---|
| 701 | 701 | if (ret < 0) { |
|---|
| 702 | 702 | dev_err(dev, "failed to read humidity\n"); |
|---|
| 703 | 703 | return ret; |
|---|
| .. | .. |
|---|
| 762 | 762 | } |
|---|
| 763 | 763 | |
|---|
| 764 | 764 | ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB, |
|---|
| 765 | | - (u8 *) &tmp, 2); |
|---|
| 765 | + &tmp, sizeof(tmp)); |
|---|
| 766 | 766 | if (ret < 0) { |
|---|
| 767 | 767 | dev_err(dev, "failed to read gas resistance\n"); |
|---|
| 768 | 768 | return ret; |
|---|
| .. | .. |
|---|
| 798 | 798 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
|---|
| 799 | 799 | switch (chan->type) { |
|---|
| 800 | 800 | case IIO_TEMP: |
|---|
| 801 | | - *val = 1 << data->oversampling_temp; |
|---|
| 801 | + *val = data->oversampling_temp; |
|---|
| 802 | 802 | return IIO_VAL_INT; |
|---|
| 803 | 803 | case IIO_PRESSURE: |
|---|
| 804 | | - *val = 1 << data->oversampling_press; |
|---|
| 804 | + *val = data->oversampling_press; |
|---|
| 805 | 805 | return IIO_VAL_INT; |
|---|
| 806 | 806 | case IIO_HUMIDITYRELATIVE: |
|---|
| 807 | | - *val = 1 << data->oversampling_humid; |
|---|
| 807 | + *val = data->oversampling_humid; |
|---|
| 808 | 808 | return IIO_VAL_INT; |
|---|
| 809 | 809 | default: |
|---|
| 810 | 810 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 814 | 814 | } |
|---|
| 815 | 815 | } |
|---|
| 816 | 816 | |
|---|
| 817 | | -static int bme680_write_oversampling_ratio_temp(struct bme680_data *data, |
|---|
| 818 | | - int val) |
|---|
| 817 | +static bool bme680_is_valid_oversampling(int rate) |
|---|
| 819 | 818 | { |
|---|
| 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_temp = ilog2(val); |
|---|
| 825 | | - |
|---|
| 826 | | - return bme680_chip_config(data); |
|---|
| 827 | | - } |
|---|
| 828 | | - } |
|---|
| 829 | | - |
|---|
| 830 | | - return -EINVAL; |
|---|
| 831 | | -} |
|---|
| 832 | | - |
|---|
| 833 | | -static int bme680_write_oversampling_ratio_press(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_press = ilog2(val); |
|---|
| 841 | | - |
|---|
| 842 | | - return bme680_chip_config(data); |
|---|
| 843 | | - } |
|---|
| 844 | | - } |
|---|
| 845 | | - |
|---|
| 846 | | - return -EINVAL; |
|---|
| 847 | | -} |
|---|
| 848 | | - |
|---|
| 849 | | -static int bme680_write_oversampling_ratio_humid(struct bme680_data *data, |
|---|
| 850 | | - int val) |
|---|
| 851 | | -{ |
|---|
| 852 | | - int i; |
|---|
| 853 | | - |
|---|
| 854 | | - for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) { |
|---|
| 855 | | - if (bme680_oversampling_avail[i] == val) { |
|---|
| 856 | | - data->oversampling_humid = ilog2(val); |
|---|
| 857 | | - |
|---|
| 858 | | - return bme680_chip_config(data); |
|---|
| 859 | | - } |
|---|
| 860 | | - } |
|---|
| 861 | | - |
|---|
| 862 | | - return -EINVAL; |
|---|
| 819 | + return (rate > 0 && rate <= 16 && is_power_of_2(rate)); |
|---|
| 863 | 820 | } |
|---|
| 864 | 821 | |
|---|
| 865 | 822 | static int bme680_write_raw(struct iio_dev *indio_dev, |
|---|
| .. | .. |
|---|
| 868 | 825 | { |
|---|
| 869 | 826 | struct bme680_data *data = iio_priv(indio_dev); |
|---|
| 870 | 827 | |
|---|
| 828 | + if (val2 != 0) |
|---|
| 829 | + return -EINVAL; |
|---|
| 830 | + |
|---|
| 871 | 831 | switch (mask) { |
|---|
| 872 | 832 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
|---|
| 833 | + { |
|---|
| 834 | + if (!bme680_is_valid_oversampling(val)) |
|---|
| 835 | + return -EINVAL; |
|---|
| 836 | + |
|---|
| 873 | 837 | switch (chan->type) { |
|---|
| 874 | 838 | case IIO_TEMP: |
|---|
| 875 | | - return bme680_write_oversampling_ratio_temp(data, val); |
|---|
| 839 | + data->oversampling_temp = val; |
|---|
| 840 | + break; |
|---|
| 876 | 841 | case IIO_PRESSURE: |
|---|
| 877 | | - return bme680_write_oversampling_ratio_press(data, val); |
|---|
| 842 | + data->oversampling_press = val; |
|---|
| 843 | + break; |
|---|
| 878 | 844 | case IIO_HUMIDITYRELATIVE: |
|---|
| 879 | | - return bme680_write_oversampling_ratio_humid(data, val); |
|---|
| 845 | + data->oversampling_humid = val; |
|---|
| 846 | + break; |
|---|
| 880 | 847 | default: |
|---|
| 881 | 848 | return -EINVAL; |
|---|
| 882 | 849 | } |
|---|
| 850 | + |
|---|
| 851 | + return bme680_chip_config(data); |
|---|
| 852 | + } |
|---|
| 883 | 853 | default: |
|---|
| 884 | 854 | return -EINVAL; |
|---|
| 885 | 855 | } |
|---|
| .. | .. |
|---|
| 953 | 923 | data = iio_priv(indio_dev); |
|---|
| 954 | 924 | dev_set_drvdata(dev, indio_dev); |
|---|
| 955 | 925 | data->regmap = regmap; |
|---|
| 956 | | - indio_dev->dev.parent = dev; |
|---|
| 957 | 926 | indio_dev->name = name; |
|---|
| 958 | 927 | indio_dev->channels = bme680_channels; |
|---|
| 959 | 928 | indio_dev->num_channels = ARRAY_SIZE(bme680_channels); |
|---|
| .. | .. |
|---|
| 961 | 930 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 962 | 931 | |
|---|
| 963 | 932 | /* default values for the sensor */ |
|---|
| 964 | | - data->oversampling_humid = ilog2(2); /* 2X oversampling rate */ |
|---|
| 965 | | - data->oversampling_press = ilog2(4); /* 4X oversampling rate */ |
|---|
| 966 | | - data->oversampling_temp = ilog2(8); /* 8X oversampling rate */ |
|---|
| 933 | + data->oversampling_humid = 2; /* 2X oversampling rate */ |
|---|
| 934 | + data->oversampling_press = 4; /* 4X oversampling rate */ |
|---|
| 935 | + data->oversampling_temp = 8; /* 8X oversampling rate */ |
|---|
| 967 | 936 | data->heater_temp = 320; /* degree Celsius */ |
|---|
| 968 | 937 | data->heater_dur = 150; /* milliseconds */ |
|---|
| 969 | 938 | |
|---|