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_ODR_MASK 0x03
28#define HTS221_BDU_MASK BIT(2)
29#define HTS221_ENABLE_MASK BIT(7)
30
31
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
41
42struct hts221_odr {
43 u8 hz;
44 u8 val;
45};
46
47#define HTS221_AVG_DEPTH 8
48struct hts221_avg {
49 u8 addr;
50 u8 mask;
51 u16 avg_avl[HTS221_AVG_DEPTH];
52};
53
54static const struct hts221_odr hts221_odr_table[] = {
55 { 1, 0x01 },
56 { 7, 0x02 },
57 { 13, 0x03 },
58};
59
60static const struct hts221_avg hts221_avg_list[] = {
61 {
62 .addr = 0x10,
63 .mask = 0x07,
64 .avg_avl = {
65 4,
66 8,
67 16,
68 32,
69 64,
70 128,
71 256,
72 512,
73 },
74 },
75 {
76 .addr = 0x10,
77 .mask = 0x38,
78 .avg_avl = {
79 2,
80 4,
81 8,
82 16,
83 32,
84 64,
85 128,
86 256,
87 },
88 },
89};
90
91static const struct iio_chan_spec hts221_channels[] = {
92 {
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,
106 },
107 },
108 {
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,
122 },
123 },
124 IIO_CHAN_SOFT_TIMESTAMP(2),
125};
126
127static int hts221_check_whoami(struct hts221_hw *hw)
128{
129 int err, data;
130
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;
135 }
136
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;
141 }
142
143 return 0;
144}
145
146static int hts221_update_odr(struct hts221_hw *hw, u8 odr)
147{
148 int i, err;
149
150 for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
151 if (hts221_odr_table[i].hz == odr)
152 break;
153
154 if (i == ARRAY_SIZE(hts221_odr_table))
155 return -EINVAL;
156
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;
163
164 hw->odr = odr;
165
166 return 0;
167}
168
169static int hts221_update_avg(struct hts221_hw *hw,
170 enum hts221_sensor_type type,
171 u16 val)
172{
173 const struct hts221_avg *avg = &hts221_avg_list[type];
174 int i, err, data;
175
176 for (i = 0; i < HTS221_AVG_DEPTH; i++)
177 if (avg->avg_avl[i] == val)
178 break;
179
180 if (i == HTS221_AVG_DEPTH)
181 return -EINVAL;
182
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;
188
189 hw->sensors[type].cur_avg_idx = i;
190
191 return 0;
192}
193
194static ssize_t hts221_sysfs_sampling_freq(struct device *dev,
195 struct device_attribute *attr,
196 char *buf)
197{
198 int i;
199 ssize_t len = 0;
200
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';
205
206 return len;
207}
208
209static ssize_t
210hts221_sysfs_rh_oversampling_avail(struct device *dev,
211 struct device_attribute *attr,
212 char *buf)
213{
214 const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H];
215 ssize_t len = 0;
216 int i;
217
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';
222
223 return len;
224}
225
226static ssize_t
227hts221_sysfs_temp_oversampling_avail(struct device *dev,
228 struct device_attribute *attr,
229 char *buf)
230{
231 const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T];
232 ssize_t len = 0;
233 int i;
234
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';
239
240 return len;
241}
242
243int hts221_set_enable(struct hts221_hw *hw, bool enable)
244{
245 int err;
246
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;
252
253 hw->enabled = enable;
254
255 return 0;
256}
257
258static int hts221_parse_temp_caldata(struct hts221_hw *hw)
259{
260 int err, *slope, *b_gen, cal0, cal1;
261 s16 cal_x0, cal_x1, cal_y0, cal_y1;
262 __le16 val;
263
264 err = regmap_read(hw->regmap, HTS221_REG_0T_CAL_Y_H, &cal0);
265 if (err < 0)
266 return err;
267
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;
272
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;
277
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);
283
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);
289
290 slope = &hw->sensors[HTS221_SENSOR_T].slope;
291 b_gen = &hw->sensors[HTS221_SENSOR_T].b_gen;
292
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;
297
298 return 0;
299}
300
301static int hts221_parse_rh_caldata(struct hts221_hw *hw)
302{
303 int err, *slope, *b_gen, data;
304 s16 cal_x0, cal_x1, cal_y0, cal_y1;
305 __le16 val;
306
307 err = regmap_read(hw->regmap, HTS221_REG_0RH_CAL_Y_H, &data);
308 if (err < 0)
309 return err;
310 cal_y0 = data;
311
312 err = regmap_read(hw->regmap, HTS221_REG_1RH_CAL_Y_H, &data);
313 if (err < 0)
314 return err;
315 cal_y1 = data;
316
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);
322
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);
328
329 slope = &hw->sensors[HTS221_SENSOR_H].slope;
330 b_gen = &hw->sensors[HTS221_SENSOR_H].b_gen;
331
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;
336
337 return 0;
338}
339
340static int hts221_get_sensor_scale(struct hts221_hw *hw,
341 enum iio_chan_type ch_type,
342 int *val, int *val2)
343{
344 s64 tmp;
345 s32 rem, div, data;
346
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;
358 }
359
360 tmp = div_s64(data * 1000000000LL, div);
361 tmp = div_s64_rem(tmp, 1000000000LL, &rem);
362
363 *val = tmp;
364 *val2 = rem;
365
366 return IIO_VAL_INT_PLUS_NANO;
367}
368
369static int hts221_get_sensor_offset(struct hts221_hw *hw,
370 enum iio_chan_type ch_type,
371 int *val, int *val2)
372{
373 s64 tmp;
374 s32 rem, div, data;
375
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;
387 }
388
389 tmp = div_s64(data * 1000000000LL, div);
390 tmp = div_s64_rem(tmp, 1000000000LL, &rem);
391
392 *val = tmp;
393 *val2 = rem;
394
395 return IIO_VAL_INT_PLUS_NANO;
396}
397
398static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val)
399{
400 __le16 data;
401 int err;
402
403 err = hts221_set_enable(hw, true);
404 if (err < 0)
405 return err;
406
407 msleep(50);
408
409 err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data));
410 if (err < 0)
411 return err;
412
413 hts221_set_enable(hw, false);
414
415 *val = (s16)le16_to_cpu(data);
416
417 return IIO_VAL_INT;
418}
419
420static int hts221_read_raw(struct iio_dev *iio_dev,
421 struct iio_chan_spec const *ch,
422 int *val, int *val2, long mask)
423{
424 struct hts221_hw *hw = iio_priv(iio_dev);
425 int ret;
426
427 ret = iio_device_claim_direct_mode(iio_dev);
428 if (ret)
429 return ret;
430
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;
448
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;
465 }
466 break;
467 }
468 default:
469 ret = -EINVAL;
470 break;
471 }
472
473 iio_device_release_direct_mode(iio_dev);
474
475 return ret;
476}
477
478static int hts221_write_raw(struct iio_dev *iio_dev,
479 struct iio_chan_spec const *chan,
480 int val, int val2, long mask)
481{
482 struct hts221_hw *hw = iio_priv(iio_dev);
483 int ret;
484
485 ret = iio_device_claim_direct_mode(iio_dev);
486 if (ret)
487 return ret;
488
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;
504 }
505 break;
506 default:
507 ret = -EINVAL;
508 break;
509 }
510
511 iio_device_release_direct_mode(iio_dev);
512
513 return ret;
514}
515
516static int hts221_validate_trigger(struct iio_dev *iio_dev,
517 struct iio_trigger *trig)
518{
519 struct hts221_hw *hw = iio_priv(iio_dev);
520
521 return hw->trig == trig ? 0 : -EINVAL;
522}
523
524static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO,
525 hts221_sysfs_rh_oversampling_avail, NULL, 0);
526static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO,
527 hts221_sysfs_temp_oversampling_avail, NULL, 0);
528static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq);
529
530static 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,
535};
536
537static const struct attribute_group hts221_attribute_group = {
538 .attrs = hts221_attributes,
539};
540
541static 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,
546};
547
548static const unsigned long hts221_scan_masks[] = {0x3, 0x0};
549
550static int hts221_init_regulators(struct device *dev)
551{
552 struct iio_dev *iio_dev = dev_get_drvdata(dev);
553 struct hts221_hw *hw = iio_priv(iio_dev);
554 int err;
555
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");
560
561 err = regulator_enable(hw->vdd);
562 if (err) {
563 dev_err(dev, "failed to enable vdd regulator: %d\n", err);
564 return err;
565 }
566
567 msleep(50);
568
569 return 0;
570}
571
572static void hts221_chip_uninit(void *data)
573{
574 struct hts221_hw *hw = data;
575
576 regulator_disable(hw->vdd);
577}
578
579int hts221_probe(struct device *dev, int irq, const char *name,
580 struct regmap *regmap)
581{
582 struct iio_dev *iio_dev;
583 struct hts221_hw *hw;
584 int err;
585 u8 data;
586
587 iio_dev = devm_iio_device_alloc(dev, sizeof(*hw));
588 if (!iio_dev)
589 return -ENOMEM;
590
591 dev_set_drvdata(dev, (void *)iio_dev);
592
593 hw = iio_priv(iio_dev);
594 hw->name = name;
595 hw->dev = dev;
596 hw->irq = irq;
597 hw->regmap = regmap;
598
599 err = hts221_init_regulators(dev);
600 if (err)
601 return err;
602
603 err = devm_add_action_or_reset(dev, hts221_chip_uninit, hw);
604 if (err)
605 return err;
606
607 err = hts221_check_whoami(hw);
608 if (err < 0)
609 return err;
610
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;
617
618
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;
624
625 err = hts221_update_odr(hw, hts221_odr_table[0].hz);
626 if (err < 0)
627 return err;
628
629
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;
634 }
635
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;
641 }
642
643
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;
649 }
650
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;
657 }
658
659 if (hw->irq > 0) {
660 err = hts221_allocate_buffers(iio_dev);
661 if (err < 0)
662 return err;
663
664 err = hts221_allocate_trigger(iio_dev);
665 if (err)
666 return err;
667 }
668
669 return devm_iio_device_register(hw->dev, iio_dev);
670}
671EXPORT_SYMBOL(hts221_probe);
672
673static int __maybe_unused hts221_suspend(struct device *dev)
674{
675 struct iio_dev *iio_dev = dev_get_drvdata(dev);
676 struct hts221_hw *hw = iio_priv(iio_dev);
677
678 return regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR,
679 HTS221_ENABLE_MASK,
680 FIELD_PREP(HTS221_ENABLE_MASK, false));
681}
682
683static int __maybe_unused hts221_resume(struct device *dev)
684{
685 struct iio_dev *iio_dev = dev_get_drvdata(dev);
686 struct hts221_hw *hw = iio_priv(iio_dev);
687 int err = 0;
688
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;
695}
696
697const struct dev_pm_ops hts221_pm_ops = {
698 SET_SYSTEM_SLEEP_PM_OPS(hts221_suspend, hts221_resume)
699};
700EXPORT_SYMBOL(hts221_pm_ops);
701
702MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
703MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
704MODULE_LICENSE("GPL v2");
705