1 // SPDX-License-Identifier: GPL-2.0-only
3 * STMicroelectronics hts221 sensor driver
5 * Copyright 2016 STMicroelectronics Inc.
7 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
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>
16 #include <linux/regmap.h>
17 #include <linux/bitfield.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
47 #define HTS221_AVG_DEPTH 8
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
[] = {
91 static const struct iio_chan_spec hts221_channels
[] = {
93 .type
= IIO_HUMIDITYRELATIVE
,
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
),
105 .endianness
= IIO_LE
,
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
),
121 .endianness
= IIO_LE
,
124 IIO_CHAN_SOFT_TIMESTAMP(2),
127 static int hts221_check_whoami(struct hts221_hw
*hw
)
131 err
= regmap_read(hw
->regmap
, HTS221_REG_WHOAMI_ADDR
, &data
);
133 dev_err(hw
->dev
, "failed to read whoami register\n");
137 if (data
!= HTS221_REG_WHOAMI_VAL
) {
138 dev_err(hw
->dev
, "wrong whoami {%02x vs %02x}\n",
139 data
, HTS221_REG_WHOAMI_VAL
);
146 static int hts221_update_odr(struct hts221_hw
*hw
, u8 odr
)
150 for (i
= 0; i
< ARRAY_SIZE(hts221_odr_table
); i
++)
151 if (hts221_odr_table
[i
].hz
== odr
)
154 if (i
== ARRAY_SIZE(hts221_odr_table
))
157 err
= regmap_update_bits(hw
->regmap
, HTS221_REG_CNTRL1_ADDR
,
159 FIELD_PREP(HTS221_ODR_MASK
,
160 hts221_odr_table
[i
].val
));
169 static int hts221_update_avg(struct hts221_hw
*hw
,
170 enum hts221_sensor_type type
,
173 const struct hts221_avg
*avg
= &hts221_avg_list
[type
];
176 for (i
= 0; i
< HTS221_AVG_DEPTH
; i
++)
177 if (avg
->avg_avl
[i
] == val
)
180 if (i
== HTS221_AVG_DEPTH
)
183 data
= ((i
<< __ffs(avg
->mask
)) & avg
->mask
);
184 err
= regmap_update_bits(hw
->regmap
, avg
->addr
,
189 hw
->sensors
[type
].cur_avg_idx
= i
;
194 static ssize_t
hts221_sysfs_sampling_freq(struct device
*dev
,
195 struct device_attribute
*attr
,
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
);
210 hts221_sysfs_rh_oversampling_avail(struct device
*dev
,
211 struct device_attribute
*attr
,
214 const struct hts221_avg
*avg
= &hts221_avg_list
[HTS221_SENSOR_H
];
218 for (i
= 0; i
< ARRAY_SIZE(avg
->avg_avl
); i
++)
219 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
, "%d ",
227 hts221_sysfs_temp_oversampling_avail(struct device
*dev
,
228 struct device_attribute
*attr
,
231 const struct hts221_avg
*avg
= &hts221_avg_list
[HTS221_SENSOR_T
];
235 for (i
= 0; i
< ARRAY_SIZE(avg
->avg_avl
); i
++)
236 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
, "%d ",
243 int hts221_set_enable(struct hts221_hw
*hw
, bool enable
)
247 err
= regmap_update_bits(hw
->regmap
, HTS221_REG_CNTRL1_ADDR
,
249 FIELD_PREP(HTS221_ENABLE_MASK
, enable
));
253 hw
->enabled
= enable
;
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
;
264 err
= regmap_read(hw
->regmap
, HTS221_REG_0T_CAL_Y_H
, &cal0
);
268 err
= regmap_read(hw
->regmap
, HTS221_REG_T1_T0_CAL_Y_H
, &cal1
);
271 cal_y0
= ((cal1
& 0x3) << 8) | cal0
;
273 err
= regmap_read(hw
->regmap
, HTS221_REG_1T_CAL_Y_H
, &cal0
);
276 cal_y1
= (((cal1
& 0xc) >> 2) << 8) | cal0
;
278 err
= regmap_bulk_read(hw
->regmap
, HTS221_REG_0T_CAL_X_L
,
282 cal_x0
= le16_to_cpu(val
);
284 err
= regmap_bulk_read(hw
->regmap
, HTS221_REG_1T_CAL_X_L
,
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) /
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
;
307 err
= regmap_read(hw
->regmap
, HTS221_REG_0RH_CAL_Y_H
, &data
);
312 err
= regmap_read(hw
->regmap
, HTS221_REG_1RH_CAL_Y_H
, &data
);
317 err
= regmap_bulk_read(hw
->regmap
, HTS221_REG_0RH_CAL_X_H
,
321 cal_x0
= le16_to_cpu(val
);
323 err
= regmap_bulk_read(hw
->regmap
, HTS221_REG_1RH_CAL_X_H
,
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) /
340 static int hts221_get_sensor_scale(struct hts221_hw
*hw
,
341 enum iio_chan_type ch_type
,
348 case IIO_HUMIDITYRELATIVE
:
349 data
= hw
->sensors
[HTS221_SENSOR_H
].slope
;
350 div
= (1 << 4) * 1000;
353 data
= hw
->sensors
[HTS221_SENSOR_T
].slope
;
354 div
= (1 << 6) * 1000;
360 tmp
= div_s64(data
* 1000000000LL, div
);
361 tmp
= div_s64_rem(tmp
, 1000000000LL, &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
,
377 case IIO_HUMIDITYRELATIVE
:
378 data
= hw
->sensors
[HTS221_SENSOR_H
].b_gen
;
379 div
= hw
->sensors
[HTS221_SENSOR_H
].slope
;
382 data
= hw
->sensors
[HTS221_SENSOR_T
].b_gen
;
383 div
= hw
->sensors
[HTS221_SENSOR_T
].slope
;
389 tmp
= div_s64(data
* 1000000000LL, div
);
390 tmp
= div_s64_rem(tmp
, 1000000000LL, &rem
);
395 return IIO_VAL_INT_PLUS_NANO
;
398 static int hts221_read_oneshot(struct hts221_hw
*hw
, u8 addr
, int *val
)
403 err
= hts221_set_enable(hw
, true);
409 err
= regmap_bulk_read(hw
->regmap
, addr
, &data
, sizeof(data
));
413 hts221_set_enable(hw
, false);
415 *val
= (s16
)le16_to_cpu(data
);
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
);
427 ret
= iio_device_claim_direct_mode(iio_dev
);
432 case IIO_CHAN_INFO_RAW
:
433 ret
= hts221_read_oneshot(hw
, ch
->address
, val
);
435 case IIO_CHAN_INFO_SCALE
:
436 ret
= hts221_get_sensor_scale(hw
, ch
->type
, val
, val2
);
438 case IIO_CHAN_INFO_OFFSET
:
439 ret
= hts221_get_sensor_offset(hw
, ch
->type
, val
, val2
);
441 case IIO_CHAN_INFO_SAMP_FREQ
:
445 case IIO_CHAN_INFO_OVERSAMPLING_RATIO
: {
447 const struct hts221_avg
*avg
;
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
];
457 avg
= &hts221_avg_list
[HTS221_SENSOR_T
];
458 idx
= hw
->sensors
[HTS221_SENSOR_T
].cur_avg_idx
;
459 *val
= avg
->avg_avl
[idx
];
473 iio_device_release_direct_mode(iio_dev
);
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
);
485 ret
= iio_device_claim_direct_mode(iio_dev
);
490 case IIO_CHAN_INFO_SAMP_FREQ
:
491 ret
= hts221_update_odr(hw
, val
);
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
);
499 ret
= hts221_update_avg(hw
, HTS221_SENSOR_T
, val
);
511 iio_device_release_direct_mode(iio_dev
);
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
,
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
);
556 hw
->vdd
= devm_regulator_get(dev
, "vdd");
558 return dev_err_probe(dev
, PTR_ERR(hw
->vdd
),
559 "failed to get vdd regulator\n");
561 err
= regulator_enable(hw
->vdd
);
563 dev_err(dev
, "failed to enable vdd regulator: %d\n", err
);
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
;
587 iio_dev
= devm_iio_device_alloc(dev
, sizeof(*hw
));
591 dev_set_drvdata(dev
, (void *)iio_dev
);
593 hw
= iio_priv(iio_dev
);
599 err
= hts221_init_regulators(dev
);
603 err
= devm_add_action_or_reset(dev
, hts221_chip_uninit
, hw
);
607 err
= hts221_check_whoami(hw
);
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
,
621 FIELD_PREP(HTS221_BDU_MASK
, 1));
625 err
= hts221_update_odr(hw
, hts221_odr_table
[0].hz
);
629 /* configure humidity sensor */
630 err
= hts221_parse_rh_caldata(hw
);
632 dev_err(hw
->dev
, "failed to get rh calibration data\n");
636 data
= hts221_avg_list
[HTS221_SENSOR_H
].avg_avl
[3];
637 err
= hts221_update_avg(hw
, HTS221_SENSOR_H
, data
);
639 dev_err(hw
->dev
, "failed to set rh oversampling ratio\n");
643 /* configure temperature sensor */
644 err
= hts221_parse_temp_caldata(hw
);
647 "failed to get temperature calibration data\n");
651 data
= hts221_avg_list
[HTS221_SENSOR_T
].avg_avl
[3];
652 err
= hts221_update_avg(hw
, HTS221_SENSOR_T
, data
);
655 "failed to set temperature oversampling ratio\n");
660 err
= hts221_allocate_buffers(iio_dev
);
664 err
= hts221_allocate_trigger(iio_dev
);
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
,
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
);
690 err
= regmap_update_bits(hw
->regmap
, HTS221_REG_CNTRL1_ADDR
,
692 FIELD_PREP(HTS221_ENABLE_MASK
,
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");