1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * STMicroelectronics hts221 sensor driver
4  *
5  * Copyright 2016 STMicroelectronics Inc.
6  *
7  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
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 /* calibration registers */
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 
49 struct hts221_odr {
50 	u8 hz;
51 	u8 val;
52 };
53 
54 #define HTS221_AVG_DEPTH		8
55 struct hts221_avg {
56 	u8 addr;
57 	u8 mask;
58 	u16 avg_avl[HTS221_AVG_DEPTH];
59 };
60 
61 static const struct hts221_odr hts221_odr_table[] = {
62 	{  1, 0x01 },	/* 1Hz */
63 	{  7, 0x02 },	/* 7Hz */
64 	{ 13, 0x03 },	/* 12.5Hz */
65 };
66 
67 static 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, /* 0.4 %RH */
73 			8, /* 0.3 %RH */
74 			16, /* 0.2 %RH */
75 			32, /* 0.15 %RH */
76 			64, /* 0.1 %RH */
77 			128, /* 0.07 %RH */
78 			256, /* 0.05 %RH */
79 			512, /* 0.03 %RH */
80 		},
81 	},
82 	{
83 		.addr = HTS221_REG_AVG_ADDR,
84 		.mask = HTS221_TEMP_AVG_MASK,
85 		.avg_avl = {
86 			2, /* 0.08 degC */
87 			4, /* 0.05 degC */
88 			8, /* 0.04 degC */
89 			16, /* 0.03 degC */
90 			32, /* 0.02 degC */
91 			64, /* 0.015 degC */
92 			128, /* 0.01 degC */
93 			256, /* 0.007 degC */
94 		},
95 	},
96 };
97 
98 static 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 
134 static 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 
153 static 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 
176 static 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 
201 static 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 
216 static ssize_t
217 hts221_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 
233 static ssize_t
234 hts221_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 
250 int 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 
265 static 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 
308 static 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 
347 static 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 
376 static 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 
405 static 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 
427 static 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 
485 static 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 
523 static 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 
531 static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO,
532 		       hts221_sysfs_rh_oversampling_avail, NULL, 0);
533 static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO,
534 		       hts221_sysfs_temp_oversampling_avail, NULL, 0);
535 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq);
536 
537 static 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 
544 static const struct attribute_group hts221_attribute_group = {
545 	.attrs = hts221_attributes,
546 };
547 
548 static 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 
555 static const unsigned long hts221_scan_masks[] = {0x3, 0x0};
556 
557 int 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 	/* enable Block Data Update */
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 	/* configure humidity sensor */
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 	/* configure temperature sensor */
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 }
642 EXPORT_SYMBOL(hts221_probe);
643 
644 static 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 
654 static 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 
668 const struct dev_pm_ops hts221_pm_ops = {
669 	SET_SYSTEM_SLEEP_PM_OPS(hts221_suspend, hts221_resume)
670 };
671 EXPORT_SYMBOL(hts221_pm_ops);
672 
673 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
674 MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
675 MODULE_LICENSE("GPL v2");
676