linux/drivers/iio/magnetometer/hmc5843_core.c
<<
>>
Prefs
   1/*
   2 * Device driver for the the HMC5843 multi-chip module designed
   3 * for low field magnetic sensing.
   4 *
   5 * Copyright (C) 2010 Texas Instruments
   6 *
   7 * Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
   8 * Acknowledgment: Jonathan Cameron <jic23@kernel.org> for valuable inputs.
   9 * Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
  10 * Split to multiple files by Josef Gajdusek <atx@atx.name> - 2014
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/regmap.h>
  25#include <linux/iio/iio.h>
  26#include <linux/iio/sysfs.h>
  27#include <linux/iio/trigger_consumer.h>
  28#include <linux/iio/buffer.h>
  29#include <linux/iio/triggered_buffer.h>
  30#include <linux/delay.h>
  31
  32#include "hmc5843.h"
  33
  34/*
  35 * Range gain settings in (+-)Ga
  36 * Beware: HMC5843 and HMC5883 have different recommended sensor field
  37 * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
  38 */
  39#define HMC5843_RANGE_GAIN_OFFSET               0x05
  40#define HMC5843_RANGE_GAIN_DEFAULT              0x01
  41#define HMC5843_RANGE_GAIN_MASK         0xe0
  42
  43/* Device status */
  44#define HMC5843_DATA_READY                      0x01
  45#define HMC5843_DATA_OUTPUT_LOCK                0x02
  46
  47/* Mode register configuration */
  48#define HMC5843_MODE_CONVERSION_CONTINUOUS      0x00
  49#define HMC5843_MODE_CONVERSION_SINGLE          0x01
  50#define HMC5843_MODE_IDLE                       0x02
  51#define HMC5843_MODE_SLEEP                      0x03
  52#define HMC5843_MODE_MASK                       0x03
  53
  54/*
  55 * HMC5843: Minimum data output rate
  56 * HMC5883: Typical data output rate
  57 */
  58#define HMC5843_RATE_OFFSET                     0x02
  59#define HMC5843_RATE_DEFAULT                    0x04
  60#define HMC5843_RATE_MASK               0x1c
  61
  62/* Device measurement configuration */
  63#define HMC5843_MEAS_CONF_NORMAL                0x00
  64#define HMC5843_MEAS_CONF_POSITIVE_BIAS         0x01
  65#define HMC5843_MEAS_CONF_NEGATIVE_BIAS         0x02
  66#define HMC5843_MEAS_CONF_MASK                  0x03
  67
  68/*
  69 * API for setting the measurement configuration to
  70 * Normal, Positive bias and Negative bias
  71 *
  72 * From the datasheet:
  73 * 0 - Normal measurement configuration (default): In normal measurement
  74 *     configuration the device follows normal measurement flow. Pins BP
  75 *     and BN are left floating and high impedance.
  76 *
  77 * 1 - Positive bias configuration: In positive bias configuration, a
  78 *     positive current is forced across the resistive load on pins BP
  79 *     and BN.
  80 *
  81 * 2 - Negative bias configuration. In negative bias configuration, a
  82 *     negative current is forced across the resistive load on pins BP
  83 *     and BN.
  84 *
  85 * 3 - Only available on HMC5983. Magnetic sensor is disabled.
  86 *     Temperature sensor is enabled.
  87 */
  88
  89static const char *const hmc5843_meas_conf_modes[] = {"normal", "positivebias",
  90                                                      "negativebias"};
  91
  92static const char *const hmc5983_meas_conf_modes[] = {"normal", "positivebias",
  93                                                      "negativebias",
  94                                                      "disabled"};
  95/* Scaling factors: 10000000/Gain */
  96static const int hmc5843_regval_to_nanoscale[] = {
  97        6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
  98};
  99
 100static const int hmc5883_regval_to_nanoscale[] = {
 101        7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
 102};
 103
 104static const int hmc5883l_regval_to_nanoscale[] = {
 105        7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
 106};
 107
 108/*
 109 * From the datasheet:
 110 * Value        | HMC5843               | HMC5883/HMC5883L
 111 *              | Data output rate (Hz) | Data output rate (Hz)
 112 * 0            | 0.5                   | 0.75
 113 * 1            | 1                     | 1.5
 114 * 2            | 2                     | 3
 115 * 3            | 5                     | 7.5
 116 * 4            | 10 (default)          | 15
 117 * 5            | 20                    | 30
 118 * 6            | 50                    | 75
 119 * 7            | Not used              | Not used
 120 */
 121static const int hmc5843_regval_to_samp_freq[][2] = {
 122        {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
 123};
 124
 125static const int hmc5883_regval_to_samp_freq[][2] = {
 126        {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
 127        {75, 0}
 128};
 129
 130static const int hmc5983_regval_to_samp_freq[][2] = {
 131        {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
 132        {75, 0}, {220, 0}
 133};
 134
 135/* Describe chip variants */
 136struct hmc5843_chip_info {
 137        const struct iio_chan_spec *channels;
 138        const int (*regval_to_samp_freq)[2];
 139        const int n_regval_to_samp_freq;
 140        const int *regval_to_nanoscale;
 141        const int n_regval_to_nanoscale;
 142};
 143
 144/* The lower two bits contain the current conversion mode */
 145static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
 146{
 147        int ret;
 148
 149        mutex_lock(&data->lock);
 150        ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
 151                                 HMC5843_MODE_MASK, operating_mode);
 152        mutex_unlock(&data->lock);
 153
 154        return ret;
 155}
 156
 157static int hmc5843_wait_measurement(struct hmc5843_data *data)
 158{
 159        int tries = 150;
 160        unsigned int val;
 161        int ret;
 162
 163        while (tries-- > 0) {
 164                ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);
 165                if (ret < 0)
 166                        return ret;
 167                if (val & HMC5843_DATA_READY)
 168                        break;
 169                msleep(20);
 170        }
 171
 172        if (tries < 0) {
 173                dev_err(data->dev, "data not ready\n");
 174                return -EIO;
 175        }
 176
 177        return 0;
 178}
 179
 180/* Return the measurement value from the specified channel */
 181static int hmc5843_read_measurement(struct hmc5843_data *data,
 182                                    int idx, int *val)
 183{
 184        __be16 values[3];
 185        int ret;
 186
 187        mutex_lock(&data->lock);
 188        ret = hmc5843_wait_measurement(data);
 189        if (ret < 0) {
 190                mutex_unlock(&data->lock);
 191                return ret;
 192        }
 193        ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
 194                               values, sizeof(values));
 195        mutex_unlock(&data->lock);
 196        if (ret < 0)
 197                return ret;
 198
 199        *val = sign_extend32(be16_to_cpu(values[idx]), 15);
 200        return IIO_VAL_INT;
 201}
 202
 203static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
 204{
 205        int ret;
 206
 207        mutex_lock(&data->lock);
 208        ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
 209                                 HMC5843_MEAS_CONF_MASK, meas_conf);
 210        mutex_unlock(&data->lock);
 211
 212        return ret;
 213}
 214
 215static
 216int hmc5843_show_measurement_configuration(struct iio_dev *indio_dev,
 217                                           const struct iio_chan_spec *chan)
 218{
 219        struct hmc5843_data *data = iio_priv(indio_dev);
 220        unsigned int val;
 221        int ret;
 222
 223        ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);
 224        if (ret)
 225                return ret;
 226
 227        return val & HMC5843_MEAS_CONF_MASK;
 228}
 229
 230static
 231int hmc5843_set_measurement_configuration(struct iio_dev *indio_dev,
 232                                          const struct iio_chan_spec *chan,
 233                                          unsigned int meas_conf)
 234{
 235        struct hmc5843_data *data = iio_priv(indio_dev);
 236
 237        return hmc5843_set_meas_conf(data, meas_conf);
 238}
 239
 240static const struct iio_enum hmc5843_meas_conf_enum = {
 241        .items = hmc5843_meas_conf_modes,
 242        .num_items = ARRAY_SIZE(hmc5843_meas_conf_modes),
 243        .get = hmc5843_show_measurement_configuration,
 244        .set = hmc5843_set_measurement_configuration,
 245};
 246
 247static const struct iio_chan_spec_ext_info hmc5843_ext_info[] = {
 248        IIO_ENUM("meas_conf", true, &hmc5843_meas_conf_enum),
 249        IIO_ENUM_AVAILABLE("meas_conf", &hmc5843_meas_conf_enum),
 250        { },
 251};
 252
 253static const struct iio_enum hmc5983_meas_conf_enum = {
 254        .items = hmc5983_meas_conf_modes,
 255        .num_items = ARRAY_SIZE(hmc5983_meas_conf_modes),
 256        .get = hmc5843_show_measurement_configuration,
 257        .set = hmc5843_set_measurement_configuration,
 258};
 259
 260static const struct iio_chan_spec_ext_info hmc5983_ext_info[] = {
 261        IIO_ENUM("meas_conf", true, &hmc5983_meas_conf_enum),
 262        IIO_ENUM_AVAILABLE("meas_conf", &hmc5983_meas_conf_enum),
 263        { },
 264};
 265
 266static
 267ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
 268                                     struct device_attribute *attr, char *buf)
 269{
 270        struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
 271        size_t len = 0;
 272        int i;
 273
 274        for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
 275                len += scnprintf(buf + len, PAGE_SIZE - len,
 276                        "%d.%d ", data->variant->regval_to_samp_freq[i][0],
 277                        data->variant->regval_to_samp_freq[i][1]);
 278
 279        /* replace trailing space by newline */
 280        buf[len - 1] = '\n';
 281
 282        return len;
 283}
 284
 285static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
 286
 287static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
 288{
 289        int ret;
 290
 291        mutex_lock(&data->lock);
 292        ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
 293                                 HMC5843_RATE_MASK,
 294                                 rate << HMC5843_RATE_OFFSET);
 295        mutex_unlock(&data->lock);
 296
 297        return ret;
 298}
 299
 300static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
 301                                       int val, int val2)
 302{
 303        int i;
 304
 305        for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
 306                if (val == data->variant->regval_to_samp_freq[i][0] &&
 307                    val2 == data->variant->regval_to_samp_freq[i][1])
 308                        return i;
 309
 310        return -EINVAL;
 311}
 312
 313static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
 314{
 315        int ret;
 316
 317        mutex_lock(&data->lock);
 318        ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
 319                                 HMC5843_RANGE_GAIN_MASK,
 320                                 range << HMC5843_RANGE_GAIN_OFFSET);
 321        mutex_unlock(&data->lock);
 322
 323        return ret;
 324}
 325
 326static ssize_t hmc5843_show_scale_avail(struct device *dev,
 327                                        struct device_attribute *attr,
 328                                        char *buf)
 329{
 330        struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
 331
 332        size_t len = 0;
 333        int i;
 334
 335        for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
 336                len += scnprintf(buf + len, PAGE_SIZE - len,
 337                        "0.%09d ", data->variant->regval_to_nanoscale[i]);
 338
 339        /* replace trailing space by newline */
 340        buf[len - 1] = '\n';
 341
 342        return len;
 343}
 344
 345static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
 346        hmc5843_show_scale_avail, NULL, 0);
 347
 348static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
 349{
 350        int i;
 351
 352        if (val)
 353                return -EINVAL;
 354
 355        for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
 356                if (val2 == data->variant->regval_to_nanoscale[i])
 357                        return i;
 358
 359        return -EINVAL;
 360}
 361
 362static int hmc5843_read_raw(struct iio_dev *indio_dev,
 363                            struct iio_chan_spec const *chan,
 364                            int *val, int *val2, long mask)
 365{
 366        struct hmc5843_data *data = iio_priv(indio_dev);
 367        unsigned int rval;
 368        int ret;
 369
 370        switch (mask) {
 371        case IIO_CHAN_INFO_RAW:
 372                return hmc5843_read_measurement(data, chan->scan_index, val);
 373        case IIO_CHAN_INFO_SCALE:
 374                ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);
 375                if (ret < 0)
 376                        return ret;
 377                rval >>= HMC5843_RANGE_GAIN_OFFSET;
 378                *val = 0;
 379                *val2 = data->variant->regval_to_nanoscale[rval];
 380                return IIO_VAL_INT_PLUS_NANO;
 381        case IIO_CHAN_INFO_SAMP_FREQ:
 382                ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);
 383                if (ret < 0)
 384                        return ret;
 385                rval >>= HMC5843_RATE_OFFSET;
 386                *val = data->variant->regval_to_samp_freq[rval][0];
 387                *val2 = data->variant->regval_to_samp_freq[rval][1];
 388                return IIO_VAL_INT_PLUS_MICRO;
 389        }
 390        return -EINVAL;
 391}
 392
 393static int hmc5843_write_raw(struct iio_dev *indio_dev,
 394                             struct iio_chan_spec const *chan,
 395                             int val, int val2, long mask)
 396{
 397        struct hmc5843_data *data = iio_priv(indio_dev);
 398        int rate, range;
 399
 400        switch (mask) {
 401        case IIO_CHAN_INFO_SAMP_FREQ:
 402                rate = hmc5843_get_samp_freq_index(data, val, val2);
 403                if (rate < 0)
 404                        return -EINVAL;
 405
 406                return hmc5843_set_samp_freq(data, rate);
 407        case IIO_CHAN_INFO_SCALE:
 408                range = hmc5843_get_scale_index(data, val, val2);
 409                if (range < 0)
 410                        return -EINVAL;
 411
 412                return hmc5843_set_range_gain(data, range);
 413        default:
 414                return -EINVAL;
 415        }
 416}
 417
 418static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
 419                                     struct iio_chan_spec const *chan,
 420                                     long mask)
 421{
 422        switch (mask) {
 423        case IIO_CHAN_INFO_SAMP_FREQ:
 424                return IIO_VAL_INT_PLUS_MICRO;
 425        case IIO_CHAN_INFO_SCALE:
 426                return IIO_VAL_INT_PLUS_NANO;
 427        default:
 428                return -EINVAL;
 429        }
 430}
 431
 432static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
 433{
 434        struct iio_poll_func *pf = p;
 435        struct iio_dev *indio_dev = pf->indio_dev;
 436        struct hmc5843_data *data = iio_priv(indio_dev);
 437        int ret;
 438
 439        mutex_lock(&data->lock);
 440        ret = hmc5843_wait_measurement(data);
 441        if (ret < 0) {
 442                mutex_unlock(&data->lock);
 443                goto done;
 444        }
 445
 446        ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
 447                               data->buffer, 3 * sizeof(__be16));
 448
 449        mutex_unlock(&data->lock);
 450        if (ret < 0)
 451                goto done;
 452
 453        iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
 454                                           iio_get_time_ns(indio_dev));
 455
 456done:
 457        iio_trigger_notify_done(indio_dev->trig);
 458
 459        return IRQ_HANDLED;
 460}
 461
 462#define HMC5843_CHANNEL(axis, idx)                                      \
 463        {                                                               \
 464                .type = IIO_MAGN,                                       \
 465                .modified = 1,                                          \
 466                .channel2 = IIO_MOD_##axis,                             \
 467                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
 468                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
 469                        BIT(IIO_CHAN_INFO_SAMP_FREQ),                   \
 470                .scan_index = idx,                                      \
 471                .scan_type = {                                          \
 472                        .sign = 's',                                    \
 473                        .realbits = 16,                                 \
 474                        .storagebits = 16,                              \
 475                        .endianness = IIO_BE,                           \
 476                },                                                      \
 477                .ext_info = hmc5843_ext_info,   \
 478        }
 479
 480#define HMC5983_CHANNEL(axis, idx)                                      \
 481        {                                                               \
 482                .type = IIO_MAGN,                                       \
 483                .modified = 1,                                          \
 484                .channel2 = IIO_MOD_##axis,                             \
 485                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
 486                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
 487                        BIT(IIO_CHAN_INFO_SAMP_FREQ),                   \
 488                .scan_index = idx,                                      \
 489                .scan_type = {                                          \
 490                        .sign = 's',                                    \
 491                        .realbits = 16,                                 \
 492                        .storagebits = 16,                              \
 493                        .endianness = IIO_BE,                           \
 494                },                                                      \
 495                .ext_info = hmc5983_ext_info,   \
 496        }
 497
 498static const struct iio_chan_spec hmc5843_channels[] = {
 499        HMC5843_CHANNEL(X, 0),
 500        HMC5843_CHANNEL(Y, 1),
 501        HMC5843_CHANNEL(Z, 2),
 502        IIO_CHAN_SOFT_TIMESTAMP(3),
 503};
 504
 505/* Beware: Y and Z are exchanged on HMC5883 and 5983 */
 506static const struct iio_chan_spec hmc5883_channels[] = {
 507        HMC5843_CHANNEL(X, 0),
 508        HMC5843_CHANNEL(Z, 1),
 509        HMC5843_CHANNEL(Y, 2),
 510        IIO_CHAN_SOFT_TIMESTAMP(3),
 511};
 512
 513static const struct iio_chan_spec hmc5983_channels[] = {
 514        HMC5983_CHANNEL(X, 0),
 515        HMC5983_CHANNEL(Z, 1),
 516        HMC5983_CHANNEL(Y, 2),
 517        IIO_CHAN_SOFT_TIMESTAMP(3),
 518};
 519
 520static struct attribute *hmc5843_attributes[] = {
 521        &iio_dev_attr_scale_available.dev_attr.attr,
 522        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 523        NULL
 524};
 525
 526static const struct attribute_group hmc5843_group = {
 527        .attrs = hmc5843_attributes,
 528};
 529
 530static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
 531        [HMC5843_ID] = {
 532                .channels = hmc5843_channels,
 533                .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
 534                .n_regval_to_samp_freq =
 535                                ARRAY_SIZE(hmc5843_regval_to_samp_freq),
 536                .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
 537                .n_regval_to_nanoscale =
 538                                ARRAY_SIZE(hmc5843_regval_to_nanoscale),
 539        },
 540        [HMC5883_ID] = {
 541                .channels = hmc5883_channels,
 542                .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
 543                .n_regval_to_samp_freq =
 544                                ARRAY_SIZE(hmc5883_regval_to_samp_freq),
 545                .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
 546                .n_regval_to_nanoscale =
 547                                ARRAY_SIZE(hmc5883_regval_to_nanoscale),
 548        },
 549        [HMC5883L_ID] = {
 550                .channels = hmc5883_channels,
 551                .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
 552                .n_regval_to_samp_freq =
 553                                ARRAY_SIZE(hmc5883_regval_to_samp_freq),
 554                .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
 555                .n_regval_to_nanoscale =
 556                                ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
 557        },
 558        [HMC5983_ID] = {
 559                .channels = hmc5983_channels,
 560                .regval_to_samp_freq = hmc5983_regval_to_samp_freq,
 561                .n_regval_to_samp_freq =
 562                                ARRAY_SIZE(hmc5983_regval_to_samp_freq),
 563                .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
 564                .n_regval_to_nanoscale =
 565                                ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
 566        }
 567};
 568
 569static int hmc5843_init(struct hmc5843_data *data)
 570{
 571        int ret;
 572        u8 id[3];
 573
 574        ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,
 575                               id, ARRAY_SIZE(id));
 576        if (ret < 0)
 577                return ret;
 578        if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
 579                dev_err(data->dev, "no HMC5843/5883/5883L/5983 sensor\n");
 580                return -ENODEV;
 581        }
 582
 583        ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
 584        if (ret < 0)
 585                return ret;
 586        ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
 587        if (ret < 0)
 588                return ret;
 589        ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
 590        if (ret < 0)
 591                return ret;
 592        return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
 593}
 594
 595static const struct iio_info hmc5843_info = {
 596        .attrs = &hmc5843_group,
 597        .read_raw = &hmc5843_read_raw,
 598        .write_raw = &hmc5843_write_raw,
 599        .write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
 600        .driver_module = THIS_MODULE,
 601};
 602
 603static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
 604
 605int hmc5843_common_suspend(struct device *dev)
 606{
 607        return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
 608                                HMC5843_MODE_SLEEP);
 609}
 610EXPORT_SYMBOL(hmc5843_common_suspend);
 611
 612int hmc5843_common_resume(struct device *dev)
 613{
 614        return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
 615                HMC5843_MODE_CONVERSION_CONTINUOUS);
 616}
 617EXPORT_SYMBOL(hmc5843_common_resume);
 618
 619int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
 620                         enum hmc5843_ids id, const char *name)
 621{
 622        struct hmc5843_data *data;
 623        struct iio_dev *indio_dev;
 624        int ret;
 625
 626        indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 627        if (!indio_dev)
 628                return -ENOMEM;
 629
 630        dev_set_drvdata(dev, indio_dev);
 631
 632        /* default settings at probe */
 633        data = iio_priv(indio_dev);
 634        data->dev = dev;
 635        data->regmap = regmap;
 636        data->variant = &hmc5843_chip_info_tbl[id];
 637        mutex_init(&data->lock);
 638
 639        indio_dev->dev.parent = dev;
 640        indio_dev->name = name;
 641        indio_dev->info = &hmc5843_info;
 642        indio_dev->modes = INDIO_DIRECT_MODE;
 643        indio_dev->channels = data->variant->channels;
 644        indio_dev->num_channels = 4;
 645        indio_dev->available_scan_masks = hmc5843_scan_masks;
 646
 647        ret = hmc5843_init(data);
 648        if (ret < 0)
 649                return ret;
 650
 651        ret = iio_triggered_buffer_setup(indio_dev, NULL,
 652                                         hmc5843_trigger_handler, NULL);
 653        if (ret < 0)
 654                goto buffer_setup_err;
 655
 656        ret = iio_device_register(indio_dev);
 657        if (ret < 0)
 658                goto buffer_cleanup;
 659
 660        return 0;
 661
 662buffer_cleanup:
 663        iio_triggered_buffer_cleanup(indio_dev);
 664buffer_setup_err:
 665        hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
 666        return ret;
 667}
 668EXPORT_SYMBOL(hmc5843_common_probe);
 669
 670int hmc5843_common_remove(struct device *dev)
 671{
 672        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 673
 674        iio_device_unregister(indio_dev);
 675        iio_triggered_buffer_cleanup(indio_dev);
 676
 677        /*  sleep mode to save power */
 678        hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
 679
 680        return 0;
 681}
 682EXPORT_SYMBOL(hmc5843_common_remove);
 683
 684MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
 685MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver");
 686MODULE_LICENSE("GPL");
 687