.. | .. |
---|
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 | |
---|