Merge tag 'block-5.11-2021-01-10' of git://git.kernel.dk/linux-block
[linux/fpc-iii.git] / drivers / iio / humidity / hts221_core.c
blob6a39615b696114cd43d486465ed6f944c08406a8
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * STMicroelectronics hts221 sensor driver
5 * Copyright 2016 STMicroelectronics Inc.
7 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
8 */
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/device.h>
13 #include <linux/iio/sysfs.h>
14 #include <linux/delay.h>
15 #include <linux/pm.h>
16 #include <linux/regmap.h>
17 #include <linux/bitfield.h>
19 #include "hts221.h"
21 #define HTS221_REG_WHOAMI_ADDR 0x0f
22 #define HTS221_REG_WHOAMI_VAL 0xbc
24 #define HTS221_REG_CNTRL1_ADDR 0x20
25 #define HTS221_REG_CNTRL2_ADDR 0x21
27 #define HTS221_ODR_MASK 0x03
28 #define HTS221_BDU_MASK BIT(2)
29 #define HTS221_ENABLE_MASK BIT(7)
31 /* calibration registers */
32 #define HTS221_REG_0RH_CAL_X_H 0x36
33 #define HTS221_REG_1RH_CAL_X_H 0x3a
34 #define HTS221_REG_0RH_CAL_Y_H 0x30
35 #define HTS221_REG_1RH_CAL_Y_H 0x31
36 #define HTS221_REG_0T_CAL_X_L 0x3c
37 #define HTS221_REG_1T_CAL_X_L 0x3e
38 #define HTS221_REG_0T_CAL_Y_H 0x32
39 #define HTS221_REG_1T_CAL_Y_H 0x33
40 #define HTS221_REG_T1_T0_CAL_Y_H 0x35
42 struct hts221_odr {
43 u8 hz;
44 u8 val;
47 #define HTS221_AVG_DEPTH 8
48 struct hts221_avg {
49 u8 addr;
50 u8 mask;
51 u16 avg_avl[HTS221_AVG_DEPTH];
54 static const struct hts221_odr hts221_odr_table[] = {
55 { 1, 0x01 }, /* 1Hz */
56 { 7, 0x02 }, /* 7Hz */
57 { 13, 0x03 }, /* 12.5Hz */
60 static const struct hts221_avg hts221_avg_list[] = {
62 .addr = 0x10,
63 .mask = 0x07,
64 .avg_avl = {
65 4, /* 0.4 %RH */
66 8, /* 0.3 %RH */
67 16, /* 0.2 %RH */
68 32, /* 0.15 %RH */
69 64, /* 0.1 %RH */
70 128, /* 0.07 %RH */
71 256, /* 0.05 %RH */
72 512, /* 0.03 %RH */
76 .addr = 0x10,
77 .mask = 0x38,
78 .avg_avl = {
79 2, /* 0.08 degC */
80 4, /* 0.05 degC */
81 8, /* 0.04 degC */
82 16, /* 0.03 degC */
83 32, /* 0.02 degC */
84 64, /* 0.015 degC */
85 128, /* 0.01 degC */
86 256, /* 0.007 degC */
91 static const struct iio_chan_spec hts221_channels[] = {
93 .type = IIO_HUMIDITYRELATIVE,
94 .address = 0x28,
95 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
96 BIT(IIO_CHAN_INFO_OFFSET) |
97 BIT(IIO_CHAN_INFO_SCALE) |
98 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
99 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
100 .scan_index = 0,
101 .scan_type = {
102 .sign = 's',
103 .realbits = 16,
104 .storagebits = 16,
105 .endianness = IIO_LE,
109 .type = IIO_TEMP,
110 .address = 0x2a,
111 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
112 BIT(IIO_CHAN_INFO_OFFSET) |
113 BIT(IIO_CHAN_INFO_SCALE) |
114 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
115 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
116 .scan_index = 1,
117 .scan_type = {
118 .sign = 's',
119 .realbits = 16,
120 .storagebits = 16,
121 .endianness = IIO_LE,
124 IIO_CHAN_SOFT_TIMESTAMP(2),
127 static int hts221_check_whoami(struct hts221_hw *hw)
129 int err, data;
131 err = regmap_read(hw->regmap, HTS221_REG_WHOAMI_ADDR, &data);
132 if (err < 0) {
133 dev_err(hw->dev, "failed to read whoami register\n");
134 return err;
137 if (data != HTS221_REG_WHOAMI_VAL) {
138 dev_err(hw->dev, "wrong whoami {%02x vs %02x}\n",
139 data, HTS221_REG_WHOAMI_VAL);
140 return -ENODEV;
143 return 0;
146 static int hts221_update_odr(struct hts221_hw *hw, u8 odr)
148 int i, err;
150 for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
151 if (hts221_odr_table[i].hz == odr)
152 break;
154 if (i == ARRAY_SIZE(hts221_odr_table))
155 return -EINVAL;
157 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
158 HTS221_ODR_MASK,
159 FIELD_PREP(HTS221_ODR_MASK,
160 hts221_odr_table[i].val));
161 if (err < 0)
162 return err;
164 hw->odr = odr;
166 return 0;
169 static int hts221_update_avg(struct hts221_hw *hw,
170 enum hts221_sensor_type type,
171 u16 val)
173 const struct hts221_avg *avg = &hts221_avg_list[type];
174 int i, err, data;
176 for (i = 0; i < HTS221_AVG_DEPTH; i++)
177 if (avg->avg_avl[i] == val)
178 break;
180 if (i == HTS221_AVG_DEPTH)
181 return -EINVAL;
183 data = ((i << __ffs(avg->mask)) & avg->mask);
184 err = regmap_update_bits(hw->regmap, avg->addr,
185 avg->mask, data);
186 if (err < 0)
187 return err;
189 hw->sensors[type].cur_avg_idx = i;
191 return 0;
194 static ssize_t hts221_sysfs_sampling_freq(struct device *dev,
195 struct device_attribute *attr,
196 char *buf)
198 int i;
199 ssize_t len = 0;
201 for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
202 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
203 hts221_odr_table[i].hz);
204 buf[len - 1] = '\n';
206 return len;
209 static ssize_t
210 hts221_sysfs_rh_oversampling_avail(struct device *dev,
211 struct device_attribute *attr,
212 char *buf)
214 const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H];
215 ssize_t len = 0;
216 int i;
218 for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
219 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
220 avg->avg_avl[i]);
221 buf[len - 1] = '\n';
223 return len;
226 static ssize_t
227 hts221_sysfs_temp_oversampling_avail(struct device *dev,
228 struct device_attribute *attr,
229 char *buf)
231 const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T];
232 ssize_t len = 0;
233 int i;
235 for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
236 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
237 avg->avg_avl[i]);
238 buf[len - 1] = '\n';
240 return len;
243 int hts221_set_enable(struct hts221_hw *hw, bool enable)
245 int err;
247 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
248 HTS221_ENABLE_MASK,
249 FIELD_PREP(HTS221_ENABLE_MASK, enable));
250 if (err < 0)
251 return err;
253 hw->enabled = enable;
255 return 0;
258 static int hts221_parse_temp_caldata(struct hts221_hw *hw)
260 int err, *slope, *b_gen, cal0, cal1;
261 s16 cal_x0, cal_x1, cal_y0, cal_y1;
262 __le16 val;
264 err = regmap_read(hw->regmap, HTS221_REG_0T_CAL_Y_H, &cal0);
265 if (err < 0)
266 return err;
268 err = regmap_read(hw->regmap, HTS221_REG_T1_T0_CAL_Y_H, &cal1);
269 if (err < 0)
270 return err;
271 cal_y0 = ((cal1 & 0x3) << 8) | cal0;
273 err = regmap_read(hw->regmap, HTS221_REG_1T_CAL_Y_H, &cal0);
274 if (err < 0)
275 return err;
276 cal_y1 = (((cal1 & 0xc) >> 2) << 8) | cal0;
278 err = regmap_bulk_read(hw->regmap, HTS221_REG_0T_CAL_X_L,
279 &val, sizeof(val));
280 if (err < 0)
281 return err;
282 cal_x0 = le16_to_cpu(val);
284 err = regmap_bulk_read(hw->regmap, HTS221_REG_1T_CAL_X_L,
285 &val, sizeof(val));
286 if (err < 0)
287 return err;
288 cal_x1 = le16_to_cpu(val);
290 slope = &hw->sensors[HTS221_SENSOR_T].slope;
291 b_gen = &hw->sensors[HTS221_SENSOR_T].b_gen;
293 *slope = ((cal_y1 - cal_y0) * 8000) / (cal_x1 - cal_x0);
294 *b_gen = (((s32)cal_x1 * cal_y0 - (s32)cal_x0 * cal_y1) * 1000) /
295 (cal_x1 - cal_x0);
296 *b_gen *= 8;
298 return 0;
301 static int hts221_parse_rh_caldata(struct hts221_hw *hw)
303 int err, *slope, *b_gen, data;
304 s16 cal_x0, cal_x1, cal_y0, cal_y1;
305 __le16 val;
307 err = regmap_read(hw->regmap, HTS221_REG_0RH_CAL_Y_H, &data);
308 if (err < 0)
309 return err;
310 cal_y0 = data;
312 err = regmap_read(hw->regmap, HTS221_REG_1RH_CAL_Y_H, &data);
313 if (err < 0)
314 return err;
315 cal_y1 = data;
317 err = regmap_bulk_read(hw->regmap, HTS221_REG_0RH_CAL_X_H,
318 &val, sizeof(val));
319 if (err < 0)
320 return err;
321 cal_x0 = le16_to_cpu(val);
323 err = regmap_bulk_read(hw->regmap, HTS221_REG_1RH_CAL_X_H,
324 &val, sizeof(val));
325 if (err < 0)
326 return err;
327 cal_x1 = le16_to_cpu(val);
329 slope = &hw->sensors[HTS221_SENSOR_H].slope;
330 b_gen = &hw->sensors[HTS221_SENSOR_H].b_gen;
332 *slope = ((cal_y1 - cal_y0) * 8000) / (cal_x1 - cal_x0);
333 *b_gen = (((s32)cal_x1 * cal_y0 - (s32)cal_x0 * cal_y1) * 1000) /
334 (cal_x1 - cal_x0);
335 *b_gen *= 8;
337 return 0;
340 static int hts221_get_sensor_scale(struct hts221_hw *hw,
341 enum iio_chan_type ch_type,
342 int *val, int *val2)
344 s64 tmp;
345 s32 rem, div, data;
347 switch (ch_type) {
348 case IIO_HUMIDITYRELATIVE:
349 data = hw->sensors[HTS221_SENSOR_H].slope;
350 div = (1 << 4) * 1000;
351 break;
352 case IIO_TEMP:
353 data = hw->sensors[HTS221_SENSOR_T].slope;
354 div = (1 << 6) * 1000;
355 break;
356 default:
357 return -EINVAL;
360 tmp = div_s64(data * 1000000000LL, div);
361 tmp = div_s64_rem(tmp, 1000000000LL, &rem);
363 *val = tmp;
364 *val2 = rem;
366 return IIO_VAL_INT_PLUS_NANO;
369 static int hts221_get_sensor_offset(struct hts221_hw *hw,
370 enum iio_chan_type ch_type,
371 int *val, int *val2)
373 s64 tmp;
374 s32 rem, div, data;
376 switch (ch_type) {
377 case IIO_HUMIDITYRELATIVE:
378 data = hw->sensors[HTS221_SENSOR_H].b_gen;
379 div = hw->sensors[HTS221_SENSOR_H].slope;
380 break;
381 case IIO_TEMP:
382 data = hw->sensors[HTS221_SENSOR_T].b_gen;
383 div = hw->sensors[HTS221_SENSOR_T].slope;
384 break;
385 default:
386 return -EINVAL;
389 tmp = div_s64(data * 1000000000LL, div);
390 tmp = div_s64_rem(tmp, 1000000000LL, &rem);
392 *val = tmp;
393 *val2 = rem;
395 return IIO_VAL_INT_PLUS_NANO;
398 static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val)
400 __le16 data;
401 int err;
403 err = hts221_set_enable(hw, true);
404 if (err < 0)
405 return err;
407 msleep(50);
409 err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data));
410 if (err < 0)
411 return err;
413 hts221_set_enable(hw, false);
415 *val = (s16)le16_to_cpu(data);
417 return IIO_VAL_INT;
420 static int hts221_read_raw(struct iio_dev *iio_dev,
421 struct iio_chan_spec const *ch,
422 int *val, int *val2, long mask)
424 struct hts221_hw *hw = iio_priv(iio_dev);
425 int ret;
427 ret = iio_device_claim_direct_mode(iio_dev);
428 if (ret)
429 return ret;
431 switch (mask) {
432 case IIO_CHAN_INFO_RAW:
433 ret = hts221_read_oneshot(hw, ch->address, val);
434 break;
435 case IIO_CHAN_INFO_SCALE:
436 ret = hts221_get_sensor_scale(hw, ch->type, val, val2);
437 break;
438 case IIO_CHAN_INFO_OFFSET:
439 ret = hts221_get_sensor_offset(hw, ch->type, val, val2);
440 break;
441 case IIO_CHAN_INFO_SAMP_FREQ:
442 *val = hw->odr;
443 ret = IIO_VAL_INT;
444 break;
445 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: {
446 u8 idx;
447 const struct hts221_avg *avg;
449 switch (ch->type) {
450 case IIO_HUMIDITYRELATIVE:
451 avg = &hts221_avg_list[HTS221_SENSOR_H];
452 idx = hw->sensors[HTS221_SENSOR_H].cur_avg_idx;
453 *val = avg->avg_avl[idx];
454 ret = IIO_VAL_INT;
455 break;
456 case IIO_TEMP:
457 avg = &hts221_avg_list[HTS221_SENSOR_T];
458 idx = hw->sensors[HTS221_SENSOR_T].cur_avg_idx;
459 *val = avg->avg_avl[idx];
460 ret = IIO_VAL_INT;
461 break;
462 default:
463 ret = -EINVAL;
464 break;
466 break;
468 default:
469 ret = -EINVAL;
470 break;
473 iio_device_release_direct_mode(iio_dev);
475 return ret;
478 static int hts221_write_raw(struct iio_dev *iio_dev,
479 struct iio_chan_spec const *chan,
480 int val, int val2, long mask)
482 struct hts221_hw *hw = iio_priv(iio_dev);
483 int ret;
485 ret = iio_device_claim_direct_mode(iio_dev);
486 if (ret)
487 return ret;
489 switch (mask) {
490 case IIO_CHAN_INFO_SAMP_FREQ:
491 ret = hts221_update_odr(hw, val);
492 break;
493 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
494 switch (chan->type) {
495 case IIO_HUMIDITYRELATIVE:
496 ret = hts221_update_avg(hw, HTS221_SENSOR_H, val);
497 break;
498 case IIO_TEMP:
499 ret = hts221_update_avg(hw, HTS221_SENSOR_T, val);
500 break;
501 default:
502 ret = -EINVAL;
503 break;
505 break;
506 default:
507 ret = -EINVAL;
508 break;
511 iio_device_release_direct_mode(iio_dev);
513 return ret;
516 static int hts221_validate_trigger(struct iio_dev *iio_dev,
517 struct iio_trigger *trig)
519 struct hts221_hw *hw = iio_priv(iio_dev);
521 return hw->trig == trig ? 0 : -EINVAL;
524 static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO,
525 hts221_sysfs_rh_oversampling_avail, NULL, 0);
526 static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO,
527 hts221_sysfs_temp_oversampling_avail, NULL, 0);
528 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq);
530 static struct attribute *hts221_attributes[] = {
531 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
532 &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr,
533 &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
534 NULL,
537 static const struct attribute_group hts221_attribute_group = {
538 .attrs = hts221_attributes,
541 static const struct iio_info hts221_info = {
542 .attrs = &hts221_attribute_group,
543 .read_raw = hts221_read_raw,
544 .write_raw = hts221_write_raw,
545 .validate_trigger = hts221_validate_trigger,
548 static const unsigned long hts221_scan_masks[] = {0x3, 0x0};
550 static int hts221_init_regulators(struct device *dev)
552 struct iio_dev *iio_dev = dev_get_drvdata(dev);
553 struct hts221_hw *hw = iio_priv(iio_dev);
554 int err;
556 hw->vdd = devm_regulator_get(dev, "vdd");
557 if (IS_ERR(hw->vdd))
558 return dev_err_probe(dev, PTR_ERR(hw->vdd),
559 "failed to get vdd regulator\n");
561 err = regulator_enable(hw->vdd);
562 if (err) {
563 dev_err(dev, "failed to enable vdd regulator: %d\n", err);
564 return err;
567 msleep(50);
569 return 0;
572 static void hts221_chip_uninit(void *data)
574 struct hts221_hw *hw = data;
576 regulator_disable(hw->vdd);
579 int hts221_probe(struct device *dev, int irq, const char *name,
580 struct regmap *regmap)
582 struct iio_dev *iio_dev;
583 struct hts221_hw *hw;
584 int err;
585 u8 data;
587 iio_dev = devm_iio_device_alloc(dev, sizeof(*hw));
588 if (!iio_dev)
589 return -ENOMEM;
591 dev_set_drvdata(dev, (void *)iio_dev);
593 hw = iio_priv(iio_dev);
594 hw->name = name;
595 hw->dev = dev;
596 hw->irq = irq;
597 hw->regmap = regmap;
599 err = hts221_init_regulators(dev);
600 if (err)
601 return err;
603 err = devm_add_action_or_reset(dev, hts221_chip_uninit, hw);
604 if (err)
605 return err;
607 err = hts221_check_whoami(hw);
608 if (err < 0)
609 return err;
611 iio_dev->modes = INDIO_DIRECT_MODE;
612 iio_dev->available_scan_masks = hts221_scan_masks;
613 iio_dev->channels = hts221_channels;
614 iio_dev->num_channels = ARRAY_SIZE(hts221_channels);
615 iio_dev->name = HTS221_DEV_NAME;
616 iio_dev->info = &hts221_info;
618 /* enable Block Data Update */
619 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
620 HTS221_BDU_MASK,
621 FIELD_PREP(HTS221_BDU_MASK, 1));
622 if (err < 0)
623 return err;
625 err = hts221_update_odr(hw, hts221_odr_table[0].hz);
626 if (err < 0)
627 return err;
629 /* configure humidity sensor */
630 err = hts221_parse_rh_caldata(hw);
631 if (err < 0) {
632 dev_err(hw->dev, "failed to get rh calibration data\n");
633 return err;
636 data = hts221_avg_list[HTS221_SENSOR_H].avg_avl[3];
637 err = hts221_update_avg(hw, HTS221_SENSOR_H, data);
638 if (err < 0) {
639 dev_err(hw->dev, "failed to set rh oversampling ratio\n");
640 return err;
643 /* configure temperature sensor */
644 err = hts221_parse_temp_caldata(hw);
645 if (err < 0) {
646 dev_err(hw->dev,
647 "failed to get temperature calibration data\n");
648 return err;
651 data = hts221_avg_list[HTS221_SENSOR_T].avg_avl[3];
652 err = hts221_update_avg(hw, HTS221_SENSOR_T, data);
653 if (err < 0) {
654 dev_err(hw->dev,
655 "failed to set temperature oversampling ratio\n");
656 return err;
659 if (hw->irq > 0) {
660 err = hts221_allocate_buffers(iio_dev);
661 if (err < 0)
662 return err;
664 err = hts221_allocate_trigger(iio_dev);
665 if (err)
666 return err;
669 return devm_iio_device_register(hw->dev, iio_dev);
671 EXPORT_SYMBOL(hts221_probe);
673 static int __maybe_unused hts221_suspend(struct device *dev)
675 struct iio_dev *iio_dev = dev_get_drvdata(dev);
676 struct hts221_hw *hw = iio_priv(iio_dev);
678 return regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
679 HTS221_ENABLE_MASK,
680 FIELD_PREP(HTS221_ENABLE_MASK, false));
683 static int __maybe_unused hts221_resume(struct device *dev)
685 struct iio_dev *iio_dev = dev_get_drvdata(dev);
686 struct hts221_hw *hw = iio_priv(iio_dev);
687 int err = 0;
689 if (hw->enabled)
690 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
691 HTS221_ENABLE_MASK,
692 FIELD_PREP(HTS221_ENABLE_MASK,
693 true));
694 return err;
697 const struct dev_pm_ops hts221_pm_ops = {
698 SET_SYSTEM_SLEEP_PM_OPS(hts221_suspend, hts221_resume)
700 EXPORT_SYMBOL(hts221_pm_ops);
702 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
703 MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
704 MODULE_LICENSE("GPL v2");