1
2
3
4
5
6
7
8
9
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>
18
19#include "hts221.h"
20
21#define HTS221_REG_WHOAMI_ADDR 0x0f
22#define HTS221_REG_WHOAMI_VAL 0xbc
23
24#define HTS221_REG_CNTRL1_ADDR 0x20
25#define HTS221_REG_CNTRL2_ADDR 0x21
26
27#define HTS221_REG_AVG_ADDR 0x10
28#define HTS221_REG_H_OUT_L 0x28
29#define HTS221_REG_T_OUT_L 0x2a
30
31#define HTS221_HUMIDITY_AVG_MASK 0x07
32#define HTS221_TEMP_AVG_MASK 0x38
33
34#define HTS221_ODR_MASK 0x03
35#define HTS221_BDU_MASK BIT(2)
36#define HTS221_ENABLE_MASK BIT(7)
37
38
39#define HTS221_REG_0RH_CAL_X_H 0x36
40#define HTS221_REG_1RH_CAL_X_H 0x3a
41#define HTS221_REG_0RH_CAL_Y_H 0x30
42#define HTS221_REG_1RH_CAL_Y_H 0x31
43#define HTS221_REG_0T_CAL_X_L 0x3c
44#define HTS221_REG_1T_CAL_X_L 0x3e
45#define HTS221_REG_0T_CAL_Y_H 0x32
46#define HTS221_REG_1T_CAL_Y_H 0x33
47#define HTS221_REG_T1_T0_CAL_Y_H 0x35
48
49struct hts221_odr {
50 u8 hz;
51 u8 val;
52};
53
54#define HTS221_AVG_DEPTH 8
55struct hts221_avg {
56 u8 addr;
57 u8 mask;
58 u16 avg_avl[HTS221_AVG_DEPTH];
59};
60
61static const struct hts221_odr hts221_odr_table[] = {
62 { 1, 0x01 },
63 { 7, 0x02 },
64 { 13, 0x03 },
65};
66
67static const struct hts221_avg hts221_avg_list[] = {
68 {
69 .addr = HTS221_REG_AVG_ADDR,
70 .mask = HTS221_HUMIDITY_AVG_MASK,
71 .avg_avl = {
72 4,
73 8,
74 16,
75 32,
76 64,
77 128,
78 256,
79 512,
80 },
81 },
82 {
83 .addr = HTS221_REG_AVG_ADDR,
84 .mask = HTS221_TEMP_AVG_MASK,
85 .avg_avl = {
86 2,
87 4,
88 8,
89 16,
90 32,
91 64,
92 128,
93 256,
94 },
95 },
96};
97
98static const struct iio_chan_spec hts221_channels[] = {
99 {
100 .type = IIO_HUMIDITYRELATIVE,
101 .address = HTS221_REG_H_OUT_L,
102 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
103 BIT(IIO_CHAN_INFO_OFFSET) |
104 BIT(IIO_CHAN_INFO_SCALE) |
105 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
106 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
107 .scan_index = 0,
108 .scan_type = {
109 .sign = 's',
110 .realbits = 16,
111 .storagebits = 16,
112 .endianness = IIO_LE,
113 },
114 },
115 {
116 .type = IIO_TEMP,
117 .address = HTS221_REG_T_OUT_L,
118 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
119 BIT(IIO_CHAN_INFO_OFFSET) |
120 BIT(IIO_CHAN_INFO_SCALE) |
121 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
122 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
123 .scan_index = 1,
124 .scan_type = {
125 .sign = 's',
126 .realbits = 16,
127 .storagebits = 16,
128 .endianness = IIO_LE,
129 },
130 },
131 IIO_CHAN_SOFT_TIMESTAMP(2),
132};
133
134static int hts221_check_whoami(struct hts221_hw *hw)
135{
136 int err, data;
137
138 err = regmap_read(hw->regmap, HTS221_REG_WHOAMI_ADDR, &data);
139 if (err < 0) {
140 dev_err(hw->dev, "failed to read whoami register\n");
141 return err;
142 }
143
144 if (data != HTS221_REG_WHOAMI_VAL) {
145 dev_err(hw->dev, "wrong whoami {%02x vs %02x}\n",
146 data, HTS221_REG_WHOAMI_VAL);
147 return -ENODEV;
148 }
149
150 return 0;
151}
152
153static int hts221_update_odr(struct hts221_hw *hw, u8 odr)
154{
155 int i, err;
156
157 for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
158 if (hts221_odr_table[i].hz == odr)
159 break;
160
161 if (i == ARRAY_SIZE(hts221_odr_table))
162 return -EINVAL;
163
164 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
165 HTS221_ODR_MASK,
166 FIELD_PREP(HTS221_ODR_MASK,
167 hts221_odr_table[i].val));
168 if (err < 0)
169 return err;
170
171 hw->odr = odr;
172
173 return 0;
174}
175
176static int hts221_update_avg(struct hts221_hw *hw,
177 enum hts221_sensor_type type,
178 u16 val)
179{
180 const struct hts221_avg *avg = &hts221_avg_list[type];
181 int i, err, data;
182
183 for (i = 0; i < HTS221_AVG_DEPTH; i++)
184 if (avg->avg_avl[i] == val)
185 break;
186
187 if (i == HTS221_AVG_DEPTH)
188 return -EINVAL;
189
190 data = ((i << __ffs(avg->mask)) & avg->mask);
191 err = regmap_update_bits(hw->regmap, avg->addr,
192 avg->mask, data);
193 if (err < 0)
194 return err;
195
196 hw->sensors[type].cur_avg_idx = i;
197
198 return 0;
199}
200
201static ssize_t hts221_sysfs_sampling_freq(struct device *dev,
202 struct device_attribute *attr,
203 char *buf)
204{
205 int i;
206 ssize_t len = 0;
207
208 for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
209 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
210 hts221_odr_table[i].hz);
211 buf[len - 1] = '\n';
212
213 return len;
214}
215
216static ssize_t
217hts221_sysfs_rh_oversampling_avail(struct device *dev,
218 struct device_attribute *attr,
219 char *buf)
220{
221 const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H];
222 ssize_t len = 0;
223 int i;
224
225 for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
226 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
227 avg->avg_avl[i]);
228 buf[len - 1] = '\n';
229
230 return len;
231}
232
233static ssize_t
234hts221_sysfs_temp_oversampling_avail(struct device *dev,
235 struct device_attribute *attr,
236 char *buf)
237{
238 const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T];
239 ssize_t len = 0;
240 int i;
241
242 for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
243 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
244 avg->avg_avl[i]);
245 buf[len - 1] = '\n';
246
247 return len;
248}
249
250int hts221_set_enable(struct hts221_hw *hw, bool enable)
251{
252 int err;
253
254 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
255 HTS221_ENABLE_MASK,
256 FIELD_PREP(HTS221_ENABLE_MASK, enable));
257 if (err < 0)
258 return err;
259
260 hw->enabled = enable;
261
262 return 0;
263}
264
265static int hts221_parse_temp_caldata(struct hts221_hw *hw)
266{
267 int err, *slope, *b_gen, cal0, cal1;
268 s16 cal_x0, cal_x1, cal_y0, cal_y1;
269 __le16 val;
270
271 err = regmap_read(hw->regmap, HTS221_REG_0T_CAL_Y_H, &cal0);
272 if (err < 0)
273 return err;
274
275 err = regmap_read(hw->regmap, HTS221_REG_T1_T0_CAL_Y_H, &cal1);
276 if (err < 0)
277 return err;
278 cal_y0 = ((cal1 & 0x3) << 8) | cal0;
279
280 err = regmap_read(hw->regmap, HTS221_REG_1T_CAL_Y_H, &cal0);
281 if (err < 0)
282 return err;
283 cal_y1 = (((cal1 & 0xc) >> 2) << 8) | cal0;
284
285 err = regmap_bulk_read(hw->regmap, HTS221_REG_0T_CAL_X_L,
286 &val, sizeof(val));
287 if (err < 0)
288 return err;
289 cal_x0 = le16_to_cpu(val);
290
291 err = regmap_bulk_read(hw->regmap, HTS221_REG_1T_CAL_X_L,
292 &val, sizeof(val));
293 if (err < 0)
294 return err;
295 cal_x1 = le16_to_cpu(val);
296
297 slope = &hw->sensors[HTS221_SENSOR_T].slope;
298 b_gen = &hw->sensors[HTS221_SENSOR_T].b_gen;
299
300 *slope = ((cal_y1 - cal_y0) * 8000) / (cal_x1 - cal_x0);
301 *b_gen = (((s32)cal_x1 * cal_y0 - (s32)cal_x0 * cal_y1) * 1000) /
302 (cal_x1 - cal_x0);
303 *b_gen *= 8;
304
305 return 0;
306}
307
308static int hts221_parse_rh_caldata(struct hts221_hw *hw)
309{
310 int err, *slope, *b_gen, data;
311 s16 cal_x0, cal_x1, cal_y0, cal_y1;
312 __le16 val;
313
314 err = regmap_read(hw->regmap, HTS221_REG_0RH_CAL_Y_H, &data);
315 if (err < 0)
316 return err;
317 cal_y0 = data;
318
319 err = regmap_read(hw->regmap, HTS221_REG_1RH_CAL_Y_H, &data);
320 if (err < 0)
321 return err;
322 cal_y1 = data;
323
324 err = regmap_bulk_read(hw->regmap, HTS221_REG_0RH_CAL_X_H,
325 &val, sizeof(val));
326 if (err < 0)
327 return err;
328 cal_x0 = le16_to_cpu(val);
329
330 err = regmap_bulk_read(hw->regmap, HTS221_REG_1RH_CAL_X_H,
331 &val, sizeof(val));
332 if (err < 0)
333 return err;
334 cal_x1 = le16_to_cpu(val);
335
336 slope = &hw->sensors[HTS221_SENSOR_H].slope;
337 b_gen = &hw->sensors[HTS221_SENSOR_H].b_gen;
338
339 *slope = ((cal_y1 - cal_y0) * 8000) / (cal_x1 - cal_x0);
340 *b_gen = (((s32)cal_x1 * cal_y0 - (s32)cal_x0 * cal_y1) * 1000) /
341 (cal_x1 - cal_x0);
342 *b_gen *= 8;
343
344 return 0;
345}
346
347static int hts221_get_sensor_scale(struct hts221_hw *hw,
348 enum iio_chan_type ch_type,
349 int *val, int *val2)
350{
351 s64 tmp;
352 s32 rem, div, data;
353
354 switch (ch_type) {
355 case IIO_HUMIDITYRELATIVE:
356 data = hw->sensors[HTS221_SENSOR_H].slope;
357 div = (1 << 4) * 1000;
358 break;
359 case IIO_TEMP:
360 data = hw->sensors[HTS221_SENSOR_T].slope;
361 div = (1 << 6) * 1000;
362 break;
363 default:
364 return -EINVAL;
365 }
366
367 tmp = div_s64(data * 1000000000LL, div);
368 tmp = div_s64_rem(tmp, 1000000000LL, &rem);
369
370 *val = tmp;
371 *val2 = rem;
372
373 return IIO_VAL_INT_PLUS_NANO;
374}
375
376static int hts221_get_sensor_offset(struct hts221_hw *hw,
377 enum iio_chan_type ch_type,
378 int *val, int *val2)
379{
380 s64 tmp;
381 s32 rem, div, data;
382
383 switch (ch_type) {
384 case IIO_HUMIDITYRELATIVE:
385 data = hw->sensors[HTS221_SENSOR_H].b_gen;
386 div = hw->sensors[HTS221_SENSOR_H].slope;
387 break;
388 case IIO_TEMP:
389 data = hw->sensors[HTS221_SENSOR_T].b_gen;
390 div = hw->sensors[HTS221_SENSOR_T].slope;
391 break;
392 default:
393 return -EINVAL;
394 }
395
396 tmp = div_s64(data * 1000000000LL, div);
397 tmp = div_s64_rem(tmp, 1000000000LL, &rem);
398
399 *val = tmp;
400 *val2 = rem;
401
402 return IIO_VAL_INT_PLUS_NANO;
403}
404
405static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val)
406{
407 __le16 data;
408 int err;
409
410 err = hts221_set_enable(hw, true);
411 if (err < 0)
412 return err;
413
414 msleep(50);
415
416 err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data));
417 if (err < 0)
418 return err;
419
420 hts221_set_enable(hw, false);
421
422 *val = (s16)le16_to_cpu(data);
423
424 return IIO_VAL_INT;
425}
426
427static int hts221_read_raw(struct iio_dev *iio_dev,
428 struct iio_chan_spec const *ch,
429 int *val, int *val2, long mask)
430{
431 struct hts221_hw *hw = iio_priv(iio_dev);
432 int ret;
433
434 ret = iio_device_claim_direct_mode(iio_dev);
435 if (ret)
436 return ret;
437
438 switch (mask) {
439 case IIO_CHAN_INFO_RAW:
440 ret = hts221_read_oneshot(hw, ch->address, val);
441 break;
442 case IIO_CHAN_INFO_SCALE:
443 ret = hts221_get_sensor_scale(hw, ch->type, val, val2);
444 break;
445 case IIO_CHAN_INFO_OFFSET:
446 ret = hts221_get_sensor_offset(hw, ch->type, val, val2);
447 break;
448 case IIO_CHAN_INFO_SAMP_FREQ:
449 *val = hw->odr;
450 ret = IIO_VAL_INT;
451 break;
452 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: {
453 u8 idx;
454 const struct hts221_avg *avg;
455
456 switch (ch->type) {
457 case IIO_HUMIDITYRELATIVE:
458 avg = &hts221_avg_list[HTS221_SENSOR_H];
459 idx = hw->sensors[HTS221_SENSOR_H].cur_avg_idx;
460 *val = avg->avg_avl[idx];
461 ret = IIO_VAL_INT;
462 break;
463 case IIO_TEMP:
464 avg = &hts221_avg_list[HTS221_SENSOR_T];
465 idx = hw->sensors[HTS221_SENSOR_T].cur_avg_idx;
466 *val = avg->avg_avl[idx];
467 ret = IIO_VAL_INT;
468 break;
469 default:
470 ret = -EINVAL;
471 break;
472 }
473 break;
474 }
475 default:
476 ret = -EINVAL;
477 break;
478 }
479
480 iio_device_release_direct_mode(iio_dev);
481
482 return ret;
483}
484
485static int hts221_write_raw(struct iio_dev *iio_dev,
486 struct iio_chan_spec const *chan,
487 int val, int val2, long mask)
488{
489 struct hts221_hw *hw = iio_priv(iio_dev);
490 int ret;
491
492 ret = iio_device_claim_direct_mode(iio_dev);
493 if (ret)
494 return ret;
495
496 switch (mask) {
497 case IIO_CHAN_INFO_SAMP_FREQ:
498 ret = hts221_update_odr(hw, val);
499 break;
500 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
501 switch (chan->type) {
502 case IIO_HUMIDITYRELATIVE:
503 ret = hts221_update_avg(hw, HTS221_SENSOR_H, val);
504 break;
505 case IIO_TEMP:
506 ret = hts221_update_avg(hw, HTS221_SENSOR_T, val);
507 break;
508 default:
509 ret = -EINVAL;
510 break;
511 }
512 break;
513 default:
514 ret = -EINVAL;
515 break;
516 }
517
518 iio_device_release_direct_mode(iio_dev);
519
520 return ret;
521}
522
523static int hts221_validate_trigger(struct iio_dev *iio_dev,
524 struct iio_trigger *trig)
525{
526 struct hts221_hw *hw = iio_priv(iio_dev);
527
528 return hw->trig == trig ? 0 : -EINVAL;
529}
530
531static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO,
532 hts221_sysfs_rh_oversampling_avail, NULL, 0);
533static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO,
534 hts221_sysfs_temp_oversampling_avail, NULL, 0);
535static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq);
536
537static struct attribute *hts221_attributes[] = {
538 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
539 &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr,
540 &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
541 NULL,
542};
543
544static const struct attribute_group hts221_attribute_group = {
545 .attrs = hts221_attributes,
546};
547
548static const struct iio_info hts221_info = {
549 .attrs = &hts221_attribute_group,
550 .read_raw = hts221_read_raw,
551 .write_raw = hts221_write_raw,
552 .validate_trigger = hts221_validate_trigger,
553};
554
555static const unsigned long hts221_scan_masks[] = {0x3, 0x0};
556
557int hts221_probe(struct device *dev, int irq, const char *name,
558 struct regmap *regmap)
559{
560 struct iio_dev *iio_dev;
561 struct hts221_hw *hw;
562 int err;
563 u8 data;
564
565 iio_dev = devm_iio_device_alloc(dev, sizeof(*hw));
566 if (!iio_dev)
567 return -ENOMEM;
568
569 dev_set_drvdata(dev, (void *)iio_dev);
570
571 hw = iio_priv(iio_dev);
572 hw->name = name;
573 hw->dev = dev;
574 hw->irq = irq;
575 hw->regmap = regmap;
576
577 err = hts221_check_whoami(hw);
578 if (err < 0)
579 return err;
580
581 iio_dev->modes = INDIO_DIRECT_MODE;
582 iio_dev->dev.parent = hw->dev;
583 iio_dev->available_scan_masks = hts221_scan_masks;
584 iio_dev->channels = hts221_channels;
585 iio_dev->num_channels = ARRAY_SIZE(hts221_channels);
586 iio_dev->name = HTS221_DEV_NAME;
587 iio_dev->info = &hts221_info;
588
589
590 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
591 HTS221_BDU_MASK,
592 FIELD_PREP(HTS221_BDU_MASK, 1));
593 if (err < 0)
594 return err;
595
596 err = hts221_update_odr(hw, hts221_odr_table[0].hz);
597 if (err < 0)
598 return err;
599
600
601 err = hts221_parse_rh_caldata(hw);
602 if (err < 0) {
603 dev_err(hw->dev, "failed to get rh calibration data\n");
604 return err;
605 }
606
607 data = hts221_avg_list[HTS221_SENSOR_H].avg_avl[3];
608 err = hts221_update_avg(hw, HTS221_SENSOR_H, data);
609 if (err < 0) {
610 dev_err(hw->dev, "failed to set rh oversampling ratio\n");
611 return err;
612 }
613
614
615 err = hts221_parse_temp_caldata(hw);
616 if (err < 0) {
617 dev_err(hw->dev,
618 "failed to get temperature calibration data\n");
619 return err;
620 }
621
622 data = hts221_avg_list[HTS221_SENSOR_T].avg_avl[3];
623 err = hts221_update_avg(hw, HTS221_SENSOR_T, data);
624 if (err < 0) {
625 dev_err(hw->dev,
626 "failed to set temperature oversampling ratio\n");
627 return err;
628 }
629
630 if (hw->irq > 0) {
631 err = hts221_allocate_buffers(hw);
632 if (err < 0)
633 return err;
634
635 err = hts221_allocate_trigger(hw);
636 if (err)
637 return err;
638 }
639
640 return devm_iio_device_register(hw->dev, iio_dev);
641}
642EXPORT_SYMBOL(hts221_probe);
643
644static int __maybe_unused hts221_suspend(struct device *dev)
645{
646 struct iio_dev *iio_dev = dev_get_drvdata(dev);
647 struct hts221_hw *hw = iio_priv(iio_dev);
648
649 return regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
650 HTS221_ENABLE_MASK,
651 FIELD_PREP(HTS221_ENABLE_MASK, false));
652}
653
654static int __maybe_unused hts221_resume(struct device *dev)
655{
656 struct iio_dev *iio_dev = dev_get_drvdata(dev);
657 struct hts221_hw *hw = iio_priv(iio_dev);
658 int err = 0;
659
660 if (hw->enabled)
661 err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
662 HTS221_ENABLE_MASK,
663 FIELD_PREP(HTS221_ENABLE_MASK,
664 true));
665 return err;
666}
667
668const struct dev_pm_ops hts221_pm_ops = {
669 SET_SYSTEM_SLEEP_PM_OPS(hts221_suspend, hts221_resume)
670};
671EXPORT_SYMBOL(hts221_pm_ops);
672
673MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
674MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
675MODULE_LICENSE("GPL v2");
676