linux/drivers/iio/humidity/hts221_core.c
<<
>>
Prefs
   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
  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 },   /* 1Hz */
  63        {  7, 0x02 },   /* 7Hz */
  64        { 13, 0x03 },   /* 12.5Hz */
  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, /* 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
  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        /* 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}
 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