2 * STMicroelectronics hts221 sensor driver
4 * Copyright 2016 STMicroelectronics Inc.
6 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
8 * Licensed under the GPL-2.
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/device.h>
14 #include <linux/iio/sysfs.h>
15 #include <linux/delay.h>
16 #include <asm/unaligned.h>
20 #define HTS221_REG_WHOAMI_ADDR 0x0f
21 #define HTS221_REG_WHOAMI_VAL 0xbc
23 #define HTS221_REG_CNTRL1_ADDR 0x20
24 #define HTS221_REG_CNTRL2_ADDR 0x21
25 #define HTS221_REG_CNTRL3_ADDR 0x22
27 #define HTS221_REG_AVG_ADDR 0x10
28 #define HTS221_REG_H_OUT_L 0x28
29 #define HTS221_REG_T_OUT_L 0x2a
31 #define HTS221_HUMIDITY_AVG_MASK 0x07
32 #define HTS221_TEMP_AVG_MASK 0x38
34 #define HTS221_ODR_MASK 0x87
35 #define HTS221_BDU_MASK BIT(2)
37 #define HTS221_DRDY_MASK BIT(2)
39 #define HTS221_ENABLE_SENSOR BIT(7)
41 #define HTS221_HUMIDITY_AVG_4 0x00 /* 0.4 %RH */
42 #define HTS221_HUMIDITY_AVG_8 0x01 /* 0.3 %RH */
43 #define HTS221_HUMIDITY_AVG_16 0x02 /* 0.2 %RH */
44 #define HTS221_HUMIDITY_AVG_32 0x03 /* 0.15 %RH */
45 #define HTS221_HUMIDITY_AVG_64 0x04 /* 0.1 %RH */
46 #define HTS221_HUMIDITY_AVG_128 0x05 /* 0.07 %RH */
47 #define HTS221_HUMIDITY_AVG_256 0x06 /* 0.05 %RH */
48 #define HTS221_HUMIDITY_AVG_512 0x07 /* 0.03 %RH */
50 #define HTS221_TEMP_AVG_2 0x00 /* 0.08 degC */
51 #define HTS221_TEMP_AVG_4 0x08 /* 0.05 degC */
52 #define HTS221_TEMP_AVG_8 0x10 /* 0.04 degC */
53 #define HTS221_TEMP_AVG_16 0x18 /* 0.03 degC */
54 #define HTS221_TEMP_AVG_32 0x20 /* 0.02 degC */
55 #define HTS221_TEMP_AVG_64 0x28 /* 0.015 degC */
56 #define HTS221_TEMP_AVG_128 0x30 /* 0.01 degC */
57 #define HTS221_TEMP_AVG_256 0x38 /* 0.007 degC */
59 /* calibration registers */
60 #define HTS221_REG_0RH_CAL_X_H 0x36
61 #define HTS221_REG_1RH_CAL_X_H 0x3a
62 #define HTS221_REG_0RH_CAL_Y_H 0x30
63 #define HTS221_REG_1RH_CAL_Y_H 0x31
64 #define HTS221_REG_0T_CAL_X_L 0x3c
65 #define HTS221_REG_1T_CAL_X_L 0x3e
66 #define HTS221_REG_0T_CAL_Y_H 0x32
67 #define HTS221_REG_1T_CAL_Y_H 0x33
68 #define HTS221_REG_T1_T0_CAL_Y_H 0x35
78 struct hts221_avg_avl avg_avl
[HTS221_AVG_DEPTH
];
81 static const struct hts221_odr hts221_odr_table
[] = {
82 { 1, 0x01 }, /* 1Hz */
83 { 7, 0x02 }, /* 7Hz */
84 { 13, 0x03 }, /* 12.5Hz */
87 static const struct hts221_avg hts221_avg_list
[] = {
89 .addr
= HTS221_REG_AVG_ADDR
,
90 .mask
= HTS221_HUMIDITY_AVG_MASK
,
92 { 4, HTS221_HUMIDITY_AVG_4
},
93 { 8, HTS221_HUMIDITY_AVG_8
},
94 { 16, HTS221_HUMIDITY_AVG_16
},
95 { 32, HTS221_HUMIDITY_AVG_32
},
96 { 64, HTS221_HUMIDITY_AVG_64
},
97 { 128, HTS221_HUMIDITY_AVG_128
},
98 { 256, HTS221_HUMIDITY_AVG_256
},
99 { 512, HTS221_HUMIDITY_AVG_512
},
103 .addr
= HTS221_REG_AVG_ADDR
,
104 .mask
= HTS221_TEMP_AVG_MASK
,
106 { 2, HTS221_TEMP_AVG_2
},
107 { 4, HTS221_TEMP_AVG_4
},
108 { 8, HTS221_TEMP_AVG_8
},
109 { 16, HTS221_TEMP_AVG_16
},
110 { 32, HTS221_TEMP_AVG_32
},
111 { 64, HTS221_TEMP_AVG_64
},
112 { 128, HTS221_TEMP_AVG_128
},
113 { 256, HTS221_TEMP_AVG_256
},
118 static const struct iio_chan_spec hts221_channels
[] = {
120 .type
= IIO_HUMIDITYRELATIVE
,
121 .address
= HTS221_REG_H_OUT_L
,
122 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
123 BIT(IIO_CHAN_INFO_OFFSET
) |
124 BIT(IIO_CHAN_INFO_SCALE
) |
125 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO
),
126 .info_mask_shared_by_all
= BIT(IIO_CHAN_INFO_SAMP_FREQ
),
132 .endianness
= IIO_LE
,
137 .address
= HTS221_REG_T_OUT_L
,
138 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
139 BIT(IIO_CHAN_INFO_OFFSET
) |
140 BIT(IIO_CHAN_INFO_SCALE
) |
141 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO
),
142 .info_mask_shared_by_all
= BIT(IIO_CHAN_INFO_SAMP_FREQ
),
148 .endianness
= IIO_LE
,
151 IIO_CHAN_SOFT_TIMESTAMP(2),
154 static int hts221_write_with_mask(struct hts221_hw
*hw
, u8 addr
, u8 mask
,
160 mutex_lock(&hw
->lock
);
162 err
= hw
->tf
->read(hw
->dev
, addr
, sizeof(data
), &data
);
164 dev_err(hw
->dev
, "failed to read %02x register\n", addr
);
168 data
= (data
& ~mask
) | (val
& mask
);
170 err
= hw
->tf
->write(hw
->dev
, addr
, sizeof(data
), &data
);
172 dev_err(hw
->dev
, "failed to write %02x register\n", addr
);
175 mutex_unlock(&hw
->lock
);
180 static int hts221_check_whoami(struct hts221_hw
*hw
)
185 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_WHOAMI_ADDR
, sizeof(data
),
188 dev_err(hw
->dev
, "failed to read whoami register\n");
192 if (data
!= HTS221_REG_WHOAMI_VAL
) {
193 dev_err(hw
->dev
, "wrong whoami {%02x vs %02x}\n",
194 data
, HTS221_REG_WHOAMI_VAL
);
201 int hts221_config_drdy(struct hts221_hw
*hw
, bool enable
)
203 u8 val
= enable
? BIT(2) : 0;
206 err
= hts221_write_with_mask(hw
, HTS221_REG_CNTRL3_ADDR
,
207 HTS221_DRDY_MASK
, val
);
209 return err
< 0 ? err
: 0;
212 static int hts221_update_odr(struct hts221_hw
*hw
, u8 odr
)
217 for (i
= 0; i
< ARRAY_SIZE(hts221_odr_table
); i
++)
218 if (hts221_odr_table
[i
].hz
== odr
)
221 if (i
== ARRAY_SIZE(hts221_odr_table
))
224 val
= HTS221_ENABLE_SENSOR
| HTS221_BDU_MASK
| hts221_odr_table
[i
].val
;
225 err
= hts221_write_with_mask(hw
, HTS221_REG_CNTRL1_ADDR
,
226 HTS221_ODR_MASK
, val
);
235 static int hts221_update_avg(struct hts221_hw
*hw
,
236 enum hts221_sensor_type type
,
240 const struct hts221_avg
*avg
= &hts221_avg_list
[type
];
242 for (i
= 0; i
< HTS221_AVG_DEPTH
; i
++)
243 if (avg
->avg_avl
[i
].avg
== val
)
246 if (i
== HTS221_AVG_DEPTH
)
249 err
= hts221_write_with_mask(hw
, avg
->addr
, avg
->mask
,
250 avg
->avg_avl
[i
].val
);
254 hw
->sensors
[type
].cur_avg_idx
= i
;
259 static ssize_t
hts221_sysfs_sampling_freq(struct device
*dev
,
260 struct device_attribute
*attr
,
266 for (i
= 0; i
< ARRAY_SIZE(hts221_odr_table
); i
++)
267 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
, "%d ",
268 hts221_odr_table
[i
].hz
);
275 hts221_sysfs_rh_oversampling_avail(struct device
*dev
,
276 struct device_attribute
*attr
,
279 const struct hts221_avg
*avg
= &hts221_avg_list
[HTS221_SENSOR_H
];
283 for (i
= 0; i
< ARRAY_SIZE(avg
->avg_avl
); i
++)
284 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
, "%d ",
285 avg
->avg_avl
[i
].avg
);
292 hts221_sysfs_temp_oversampling_avail(struct device
*dev
,
293 struct device_attribute
*attr
,
296 const struct hts221_avg
*avg
= &hts221_avg_list
[HTS221_SENSOR_T
];
300 for (i
= 0; i
< ARRAY_SIZE(avg
->avg_avl
); i
++)
301 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
, "%d ",
302 avg
->avg_avl
[i
].avg
);
308 int hts221_power_on(struct hts221_hw
*hw
)
310 return hts221_update_odr(hw
, hw
->odr
);
313 int hts221_power_off(struct hts221_hw
*hw
)
315 u8 data
[] = {0x00, 0x00};
317 return hw
->tf
->write(hw
->dev
, HTS221_REG_CNTRL1_ADDR
, sizeof(data
),
321 static int hts221_parse_temp_caldata(struct hts221_hw
*hw
)
323 int err
, *slope
, *b_gen
;
324 s16 cal_x0
, cal_x1
, cal_y0
, cal_y1
;
327 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_0T_CAL_Y_H
,
328 sizeof(cal0
), &cal0
);
332 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_T1_T0_CAL_Y_H
,
333 sizeof(cal1
), &cal1
);
336 cal_y0
= (le16_to_cpu(cal1
& 0x3) << 8) | cal0
;
338 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_1T_CAL_Y_H
,
339 sizeof(cal0
), &cal0
);
342 cal_y1
= (((cal1
& 0xc) >> 2) << 8) | cal0
;
344 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_0T_CAL_X_L
, sizeof(cal_x0
),
348 cal_x0
= le16_to_cpu(cal_x0
);
350 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_1T_CAL_X_L
, sizeof(cal_x1
),
354 cal_x1
= le16_to_cpu(cal_x1
);
356 slope
= &hw
->sensors
[HTS221_SENSOR_T
].slope
;
357 b_gen
= &hw
->sensors
[HTS221_SENSOR_T
].b_gen
;
359 *slope
= ((cal_y1
- cal_y0
) * 8000) / (cal_x1
- cal_x0
);
360 *b_gen
= (((s32
)cal_x1
* cal_y0
- (s32
)cal_x0
* cal_y1
) * 1000) /
367 static int hts221_parse_rh_caldata(struct hts221_hw
*hw
)
369 int err
, *slope
, *b_gen
;
370 s16 cal_x0
, cal_x1
, cal_y0
, cal_y1
;
373 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_0RH_CAL_Y_H
, sizeof(data
),
379 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_1RH_CAL_Y_H
, sizeof(data
),
385 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_0RH_CAL_X_H
, sizeof(cal_x0
),
389 cal_x0
= le16_to_cpu(cal_x0
);
391 err
= hw
->tf
->read(hw
->dev
, HTS221_REG_1RH_CAL_X_H
, sizeof(cal_x1
),
395 cal_x1
= le16_to_cpu(cal_x1
);
397 slope
= &hw
->sensors
[HTS221_SENSOR_H
].slope
;
398 b_gen
= &hw
->sensors
[HTS221_SENSOR_H
].b_gen
;
400 *slope
= ((cal_y1
- cal_y0
) * 8000) / (cal_x1
- cal_x0
);
401 *b_gen
= (((s32
)cal_x1
* cal_y0
- (s32
)cal_x0
* cal_y1
) * 1000) /
408 static int hts221_get_sensor_scale(struct hts221_hw
*hw
,
409 enum iio_chan_type ch_type
,
416 case IIO_HUMIDITYRELATIVE
:
417 data
= hw
->sensors
[HTS221_SENSOR_H
].slope
;
418 div
= (1 << 4) * 1000;
421 data
= hw
->sensors
[HTS221_SENSOR_T
].slope
;
422 div
= (1 << 6) * 1000;
428 tmp
= div_s64(data
* 1000000000LL, div
);
429 tmp
= div_s64_rem(tmp
, 1000000000LL, &rem
);
434 return IIO_VAL_INT_PLUS_NANO
;
437 static int hts221_get_sensor_offset(struct hts221_hw
*hw
,
438 enum iio_chan_type ch_type
,
445 case IIO_HUMIDITYRELATIVE
:
446 data
= hw
->sensors
[HTS221_SENSOR_H
].b_gen
;
447 div
= hw
->sensors
[HTS221_SENSOR_H
].slope
;
450 data
= hw
->sensors
[HTS221_SENSOR_T
].b_gen
;
451 div
= hw
->sensors
[HTS221_SENSOR_T
].slope
;
457 tmp
= div_s64(data
* 1000000000LL, div
);
458 tmp
= div_s64_rem(tmp
, 1000000000LL, &rem
);
463 return IIO_VAL_INT_PLUS_NANO
;
466 static int hts221_read_oneshot(struct hts221_hw
*hw
, u8 addr
, int *val
)
468 u8 data
[HTS221_DATA_SIZE
];
471 err
= hts221_power_on(hw
);
477 err
= hw
->tf
->read(hw
->dev
, addr
, sizeof(data
), data
);
481 hts221_power_off(hw
);
483 *val
= (s16
)get_unaligned_le16(data
);
488 static int hts221_read_raw(struct iio_dev
*iio_dev
,
489 struct iio_chan_spec
const *ch
,
490 int *val
, int *val2
, long mask
)
492 struct hts221_hw
*hw
= iio_priv(iio_dev
);
495 ret
= iio_device_claim_direct_mode(iio_dev
);
500 case IIO_CHAN_INFO_RAW
:
501 ret
= hts221_read_oneshot(hw
, ch
->address
, val
);
503 case IIO_CHAN_INFO_SCALE
:
504 ret
= hts221_get_sensor_scale(hw
, ch
->type
, val
, val2
);
506 case IIO_CHAN_INFO_OFFSET
:
507 ret
= hts221_get_sensor_offset(hw
, ch
->type
, val
, val2
);
509 case IIO_CHAN_INFO_SAMP_FREQ
:
513 case IIO_CHAN_INFO_OVERSAMPLING_RATIO
: {
515 const struct hts221_avg
*avg
;
518 case IIO_HUMIDITYRELATIVE
:
519 avg
= &hts221_avg_list
[HTS221_SENSOR_H
];
520 idx
= hw
->sensors
[HTS221_SENSOR_H
].cur_avg_idx
;
521 *val
= avg
->avg_avl
[idx
].avg
;
525 avg
= &hts221_avg_list
[HTS221_SENSOR_T
];
526 idx
= hw
->sensors
[HTS221_SENSOR_T
].cur_avg_idx
;
527 *val
= avg
->avg_avl
[idx
].avg
;
541 iio_device_release_direct_mode(iio_dev
);
546 static int hts221_write_raw(struct iio_dev
*iio_dev
,
547 struct iio_chan_spec
const *chan
,
548 int val
, int val2
, long mask
)
550 struct hts221_hw
*hw
= iio_priv(iio_dev
);
553 ret
= iio_device_claim_direct_mode(iio_dev
);
558 case IIO_CHAN_INFO_SAMP_FREQ
:
559 ret
= hts221_update_odr(hw
, val
);
561 case IIO_CHAN_INFO_OVERSAMPLING_RATIO
:
562 switch (chan
->type
) {
563 case IIO_HUMIDITYRELATIVE
:
564 ret
= hts221_update_avg(hw
, HTS221_SENSOR_H
, val
);
567 ret
= hts221_update_avg(hw
, HTS221_SENSOR_T
, val
);
579 iio_device_release_direct_mode(iio_dev
);
584 static int hts221_validate_trigger(struct iio_dev
*iio_dev
,
585 struct iio_trigger
*trig
)
587 struct hts221_hw
*hw
= iio_priv(iio_dev
);
589 return hw
->trig
== trig
? 0 : -EINVAL
;
592 static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available
, S_IRUGO
,
593 hts221_sysfs_rh_oversampling_avail
, NULL
, 0);
594 static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available
, S_IRUGO
,
595 hts221_sysfs_temp_oversampling_avail
, NULL
, 0);
596 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq
);
598 static struct attribute
*hts221_attributes
[] = {
599 &iio_dev_attr_sampling_frequency_available
.dev_attr
.attr
,
600 &iio_dev_attr_in_humidity_oversampling_ratio_available
.dev_attr
.attr
,
601 &iio_dev_attr_in_temp_oversampling_ratio_available
.dev_attr
.attr
,
605 static const struct attribute_group hts221_attribute_group
= {
606 .attrs
= hts221_attributes
,
609 static const struct iio_info hts221_info
= {
610 .driver_module
= THIS_MODULE
,
611 .attrs
= &hts221_attribute_group
,
612 .read_raw
= hts221_read_raw
,
613 .write_raw
= hts221_write_raw
,
614 .validate_trigger
= hts221_validate_trigger
,
617 static const unsigned long hts221_scan_masks
[] = {0x3, 0x0};
619 int hts221_probe(struct iio_dev
*iio_dev
)
621 struct hts221_hw
*hw
= iio_priv(iio_dev
);
625 mutex_init(&hw
->lock
);
627 err
= hts221_check_whoami(hw
);
631 hw
->odr
= hts221_odr_table
[0].hz
;
633 iio_dev
->modes
= INDIO_DIRECT_MODE
;
634 iio_dev
->dev
.parent
= hw
->dev
;
635 iio_dev
->available_scan_masks
= hts221_scan_masks
;
636 iio_dev
->channels
= hts221_channels
;
637 iio_dev
->num_channels
= ARRAY_SIZE(hts221_channels
);
638 iio_dev
->name
= HTS221_DEV_NAME
;
639 iio_dev
->info
= &hts221_info
;
641 /* configure humidity sensor */
642 err
= hts221_parse_rh_caldata(hw
);
644 dev_err(hw
->dev
, "failed to get rh calibration data\n");
648 data
= hts221_avg_list
[HTS221_SENSOR_H
].avg_avl
[3].avg
;
649 err
= hts221_update_avg(hw
, HTS221_SENSOR_H
, data
);
651 dev_err(hw
->dev
, "failed to set rh oversampling ratio\n");
655 /* configure temperature sensor */
656 err
= hts221_parse_temp_caldata(hw
);
659 "failed to get temperature calibration data\n");
663 data
= hts221_avg_list
[HTS221_SENSOR_T
].avg_avl
[3].avg
;
664 err
= hts221_update_avg(hw
, HTS221_SENSOR_T
, data
);
667 "failed to set temperature oversampling ratio\n");
672 err
= hts221_allocate_buffers(hw
);
676 err
= hts221_allocate_trigger(hw
);
681 return devm_iio_device_register(hw
->dev
, iio_dev
);
683 EXPORT_SYMBOL(hts221_probe
);
685 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
686 MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
687 MODULE_LICENSE("GPL v2");