linux/drivers/iio/magnetometer/mag3110.c
<<
>>
Prefs
   1/*
   2 * mag3110.c - Support for Freescale MAG3110 magnetometer sensor
   3 *
   4 * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
   5 *
   6 * This file is subject to the terms and conditions of version 2 of
   7 * the GNU General Public License.  See the file COPYING in the main
   8 * directory of this archive for more details.
   9 *
  10 * (7-bit I2C slave address 0x0e)
  11 *
  12 * TODO: irq, user offset, oversampling, continuous mode
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/i2c.h>
  17#include <linux/iio/iio.h>
  18#include <linux/iio/sysfs.h>
  19#include <linux/iio/trigger_consumer.h>
  20#include <linux/iio/buffer.h>
  21#include <linux/iio/triggered_buffer.h>
  22#include <linux/delay.h>
  23
  24#define MAG3110_STATUS 0x00
  25#define MAG3110_OUT_X 0x01 /* MSB first */
  26#define MAG3110_OUT_Y 0x03
  27#define MAG3110_OUT_Z 0x05
  28#define MAG3110_WHO_AM_I 0x07
  29#define MAG3110_SYSMOD 0x08
  30#define MAG3110_OFF_X 0x09 /* MSB first */
  31#define MAG3110_OFF_Y 0x0b
  32#define MAG3110_OFF_Z 0x0d
  33#define MAG3110_DIE_TEMP 0x0f
  34#define MAG3110_CTRL_REG1 0x10
  35#define MAG3110_CTRL_REG2 0x11
  36
  37#define MAG3110_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
  38
  39#define MAG3110_CTRL_DR_MASK (BIT(7) | BIT(6) | BIT(5))
  40#define MAG3110_CTRL_DR_SHIFT 5
  41#define MAG3110_CTRL_DR_DEFAULT 0
  42
  43#define MAG3110_SYSMOD_MODE_MASK GENMASK(1, 0)
  44
  45#define MAG3110_CTRL_TM BIT(1) /* trigger single measurement */
  46#define MAG3110_CTRL_AC BIT(0) /* continuous measurements */
  47
  48#define MAG3110_CTRL_AUTO_MRST_EN BIT(7) /* magnetic auto-reset */
  49#define MAG3110_CTRL_RAW BIT(5) /* measurements not user-offset corrected */
  50
  51#define MAG3110_DEVICE_ID 0xc4
  52
  53/* Each client has this additional data */
  54struct mag3110_data {
  55        struct i2c_client *client;
  56        struct mutex lock;
  57        u8 ctrl_reg1;
  58        int sleep_val;
  59};
  60
  61static int mag3110_request(struct mag3110_data *data)
  62{
  63        int ret, tries = 150;
  64
  65        if ((data->ctrl_reg1 & MAG3110_CTRL_AC) == 0) {
  66                /* trigger measurement */
  67                ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
  68                        data->ctrl_reg1 | MAG3110_CTRL_TM);
  69                if (ret < 0)
  70                        return ret;
  71        }
  72
  73        while (tries-- > 0) {
  74                ret = i2c_smbus_read_byte_data(data->client, MAG3110_STATUS);
  75                if (ret < 0)
  76                        return ret;
  77                /* wait for data ready */
  78                if ((ret & MAG3110_STATUS_DRDY) == MAG3110_STATUS_DRDY)
  79                        break;
  80
  81                if (data->sleep_val <= 20)
  82                        usleep_range(data->sleep_val * 250, data->sleep_val * 500);
  83                else
  84                        msleep(20);
  85        }
  86
  87        if (tries < 0) {
  88                dev_err(&data->client->dev, "data not ready\n");
  89                return -EIO;
  90        }
  91
  92        return 0;
  93}
  94
  95static int mag3110_read(struct mag3110_data *data, __be16 buf[3])
  96{
  97        int ret;
  98
  99        mutex_lock(&data->lock);
 100        ret = mag3110_request(data);
 101        if (ret < 0) {
 102                mutex_unlock(&data->lock);
 103                return ret;
 104        }
 105        ret = i2c_smbus_read_i2c_block_data(data->client,
 106                MAG3110_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
 107        mutex_unlock(&data->lock);
 108
 109        return ret;
 110}
 111
 112static ssize_t mag3110_show_int_plus_micros(char *buf,
 113        const int (*vals)[2], int n)
 114{
 115        size_t len = 0;
 116
 117        while (n-- > 0)
 118                len += scnprintf(buf + len, PAGE_SIZE - len,
 119                        "%d.%06d ", vals[n][0], vals[n][1]);
 120
 121        /* replace trailing space by newline */
 122        buf[len - 1] = '\n';
 123
 124        return len;
 125}
 126
 127static int mag3110_get_int_plus_micros_index(const int (*vals)[2], int n,
 128                                        int val, int val2)
 129{
 130        while (n-- > 0)
 131                if (val == vals[n][0] && val2 == vals[n][1])
 132                        return n;
 133
 134        return -EINVAL;
 135}
 136
 137static const int mag3110_samp_freq[8][2] = {
 138        {80, 0}, {40, 0}, {20, 0}, {10, 0}, {5, 0}, {2, 500000},
 139        {1, 250000}, {0, 625000}
 140};
 141
 142static ssize_t mag3110_show_samp_freq_avail(struct device *dev,
 143                                struct device_attribute *attr, char *buf)
 144{
 145        return mag3110_show_int_plus_micros(buf, mag3110_samp_freq, 8);
 146}
 147
 148static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mag3110_show_samp_freq_avail);
 149
 150static int mag3110_get_samp_freq_index(struct mag3110_data *data,
 151        int val, int val2)
 152{
 153        return mag3110_get_int_plus_micros_index(mag3110_samp_freq, 8, val,
 154                val2);
 155}
 156
 157static int mag3110_calculate_sleep(struct mag3110_data *data)
 158{
 159        int ret, i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT;
 160
 161        if (mag3110_samp_freq[i][0] > 0)
 162                ret = 1000 / mag3110_samp_freq[i][0];
 163        else
 164                ret = 1000;
 165
 166        return ret == 0 ? 1 : ret;
 167}
 168
 169static int mag3110_standby(struct mag3110_data *data)
 170{
 171        return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
 172                data->ctrl_reg1 & ~MAG3110_CTRL_AC);
 173}
 174
 175static int mag3110_wait_standby(struct mag3110_data *data)
 176{
 177        int ret, tries = 30;
 178
 179        /*
 180         * Takes up to 1/ODR to come out of active mode into stby
 181         * Longest expected period is 12.5seconds.
 182         * We'll sleep for 500ms between checks
 183         */
 184        while (tries-- > 0) {
 185                ret = i2c_smbus_read_byte_data(data->client, MAG3110_SYSMOD);
 186                if (ret < 0) {
 187                        dev_err(&data->client->dev, "i2c error\n");
 188                        return ret;
 189                }
 190                /* wait for standby */
 191                if ((ret & MAG3110_SYSMOD_MODE_MASK) == 0)
 192                        break;
 193
 194                msleep_interruptible(500);
 195        }
 196
 197        if (tries < 0) {
 198                dev_err(&data->client->dev, "device not entering standby mode\n");
 199                return -EIO;
 200        }
 201
 202        return 0;
 203}
 204
 205static int mag3110_active(struct mag3110_data *data)
 206{
 207        return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
 208                                         data->ctrl_reg1);
 209}
 210
 211/* returns >0 if active, 0 if in standby and <0 on error */
 212static int mag3110_is_active(struct mag3110_data *data)
 213{
 214        int reg;
 215
 216        reg = i2c_smbus_read_byte_data(data->client, MAG3110_CTRL_REG1);
 217        if (reg < 0)
 218                return reg;
 219
 220        return reg & MAG3110_CTRL_AC;
 221}
 222
 223static int mag3110_change_config(struct mag3110_data *data, u8 reg, u8 val)
 224{
 225        int ret;
 226        int is_active;
 227
 228        mutex_lock(&data->lock);
 229
 230        is_active = mag3110_is_active(data);
 231        if (is_active < 0) {
 232                ret = is_active;
 233                goto fail;
 234        }
 235
 236        /* config can only be changed when in standby */
 237        if (is_active > 0) {
 238                ret = mag3110_standby(data);
 239                if (ret < 0)
 240                        goto fail;
 241        }
 242
 243        /*
 244         * After coming out of active we must wait for the part
 245         * to transition to STBY. This can take up to 1 /ODR to occur
 246         */
 247        ret = mag3110_wait_standby(data);
 248        if (ret < 0)
 249                goto fail;
 250
 251        ret = i2c_smbus_write_byte_data(data->client, reg, val);
 252        if (ret < 0)
 253                goto fail;
 254
 255        if (is_active > 0) {
 256                ret = mag3110_active(data);
 257                if (ret < 0)
 258                        goto fail;
 259        }
 260
 261        ret = 0;
 262fail:
 263        mutex_unlock(&data->lock);
 264
 265        return ret;
 266}
 267
 268static int mag3110_read_raw(struct iio_dev *indio_dev,
 269                            struct iio_chan_spec const *chan,
 270                            int *val, int *val2, long mask)
 271{
 272        struct mag3110_data *data = iio_priv(indio_dev);
 273        __be16 buffer[3];
 274        int i, ret;
 275
 276        switch (mask) {
 277        case IIO_CHAN_INFO_RAW:
 278                ret = iio_device_claim_direct_mode(indio_dev);
 279                if (ret)
 280                        return ret;
 281
 282                switch (chan->type) {
 283                case IIO_MAGN: /* in 0.1 uT / LSB */
 284                        ret = mag3110_read(data, buffer);
 285                        if (ret < 0)
 286                                goto release;
 287                        *val = sign_extend32(
 288                                be16_to_cpu(buffer[chan->scan_index]), 15);
 289                        ret = IIO_VAL_INT;
 290                        break;
 291                case IIO_TEMP: /* in 1 C / LSB */
 292                        mutex_lock(&data->lock);
 293                        ret = mag3110_request(data);
 294                        if (ret < 0) {
 295                                mutex_unlock(&data->lock);
 296                                goto release;
 297                        }
 298                        ret = i2c_smbus_read_byte_data(data->client,
 299                                MAG3110_DIE_TEMP);
 300                        mutex_unlock(&data->lock);
 301                        if (ret < 0)
 302                                goto release;
 303                        *val = sign_extend32(ret, 7);
 304                        ret = IIO_VAL_INT;
 305                        break;
 306                default:
 307                        ret = -EINVAL;
 308                }
 309release:
 310                iio_device_release_direct_mode(indio_dev);
 311                return ret;
 312
 313        case IIO_CHAN_INFO_SCALE:
 314                switch (chan->type) {
 315                case IIO_MAGN:
 316                        *val = 0;
 317                        *val2 = 1000;
 318                        return IIO_VAL_INT_PLUS_MICRO;
 319                case IIO_TEMP:
 320                        *val = 1000;
 321                        return IIO_VAL_INT;
 322                default:
 323                        return -EINVAL;
 324                }
 325        case IIO_CHAN_INFO_SAMP_FREQ:
 326                i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT;
 327                *val = mag3110_samp_freq[i][0];
 328                *val2 = mag3110_samp_freq[i][1];
 329                return IIO_VAL_INT_PLUS_MICRO;
 330        case IIO_CHAN_INFO_CALIBBIAS:
 331                ret = i2c_smbus_read_word_swapped(data->client,
 332                        MAG3110_OFF_X + 2 * chan->scan_index);
 333                if (ret < 0)
 334                        return ret;
 335                *val = sign_extend32(ret >> 1, 14);
 336                return IIO_VAL_INT;
 337        }
 338        return -EINVAL;
 339}
 340
 341static int mag3110_write_raw(struct iio_dev *indio_dev,
 342                             struct iio_chan_spec const *chan,
 343                             int val, int val2, long mask)
 344{
 345        struct mag3110_data *data = iio_priv(indio_dev);
 346        int rate, ret;
 347
 348        ret = iio_device_claim_direct_mode(indio_dev);
 349        if (ret)
 350                return ret;
 351
 352        switch (mask) {
 353        case IIO_CHAN_INFO_SAMP_FREQ:
 354                rate = mag3110_get_samp_freq_index(data, val, val2);
 355                if (rate < 0) {
 356                        ret = -EINVAL;
 357                        break;
 358                }
 359                data->ctrl_reg1 &= 0xff & ~MAG3110_CTRL_DR_MASK
 360                                        & ~MAG3110_CTRL_AC;
 361                data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT;
 362                data->sleep_val = mag3110_calculate_sleep(data);
 363                if (data->sleep_val < 40)
 364                        data->ctrl_reg1 |= MAG3110_CTRL_AC;
 365
 366                ret = mag3110_change_config(data, MAG3110_CTRL_REG1,
 367                                            data->ctrl_reg1);
 368                break;
 369        case IIO_CHAN_INFO_CALIBBIAS:
 370                if (val < -10000 || val > 10000) {
 371                        ret = -EINVAL;
 372                        break;
 373                }
 374                ret = i2c_smbus_write_word_swapped(data->client,
 375                        MAG3110_OFF_X + 2 * chan->scan_index, val << 1);
 376                break;
 377        default:
 378                ret = -EINVAL;
 379                break;
 380        }
 381        iio_device_release_direct_mode(indio_dev);
 382        return ret;
 383}
 384
 385static irqreturn_t mag3110_trigger_handler(int irq, void *p)
 386{
 387        struct iio_poll_func *pf = p;
 388        struct iio_dev *indio_dev = pf->indio_dev;
 389        struct mag3110_data *data = iio_priv(indio_dev);
 390        u8 buffer[16]; /* 3 16-bit channels + 1 byte temp + padding + ts */
 391        int ret;
 392
 393        ret = mag3110_read(data, (__be16 *) buffer);
 394        if (ret < 0)
 395                goto done;
 396
 397        if (test_bit(3, indio_dev->active_scan_mask)) {
 398                ret = i2c_smbus_read_byte_data(data->client,
 399                        MAG3110_DIE_TEMP);
 400                if (ret < 0)
 401                        goto done;
 402                buffer[6] = ret;
 403        }
 404
 405        iio_push_to_buffers_with_timestamp(indio_dev, buffer,
 406                iio_get_time_ns(indio_dev));
 407
 408done:
 409        iio_trigger_notify_done(indio_dev->trig);
 410        return IRQ_HANDLED;
 411}
 412
 413#define MAG3110_CHANNEL(axis, idx) { \
 414        .type = IIO_MAGN, \
 415        .modified = 1, \
 416        .channel2 = IIO_MOD_##axis, \
 417        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 418                BIT(IIO_CHAN_INFO_CALIBBIAS), \
 419        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
 420                BIT(IIO_CHAN_INFO_SCALE), \
 421        .scan_index = idx, \
 422        .scan_type = { \
 423                .sign = 's', \
 424                .realbits = 16, \
 425                .storagebits = 16, \
 426                .endianness = IIO_BE, \
 427        }, \
 428}
 429
 430static const struct iio_chan_spec mag3110_channels[] = {
 431        MAG3110_CHANNEL(X, 0),
 432        MAG3110_CHANNEL(Y, 1),
 433        MAG3110_CHANNEL(Z, 2),
 434        {
 435                .type = IIO_TEMP,
 436                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 437                        BIT(IIO_CHAN_INFO_SCALE),
 438                .scan_index = 3,
 439                .scan_type = {
 440                        .sign = 's',
 441                        .realbits = 8,
 442                        .storagebits = 8,
 443                        },
 444        },
 445        IIO_CHAN_SOFT_TIMESTAMP(4),
 446};
 447
 448static struct attribute *mag3110_attributes[] = {
 449        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 450        NULL
 451};
 452
 453static const struct attribute_group mag3110_group = {
 454        .attrs = mag3110_attributes,
 455};
 456
 457static const struct iio_info mag3110_info = {
 458        .attrs = &mag3110_group,
 459        .read_raw = &mag3110_read_raw,
 460        .write_raw = &mag3110_write_raw,
 461};
 462
 463static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0};
 464
 465static int mag3110_probe(struct i2c_client *client,
 466                         const struct i2c_device_id *id)
 467{
 468        struct mag3110_data *data;
 469        struct iio_dev *indio_dev;
 470        int ret;
 471
 472        ret = i2c_smbus_read_byte_data(client, MAG3110_WHO_AM_I);
 473        if (ret < 0)
 474                return ret;
 475        if (ret != MAG3110_DEVICE_ID)
 476                return -ENODEV;
 477
 478        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 479        if (!indio_dev)
 480                return -ENOMEM;
 481
 482        data = iio_priv(indio_dev);
 483        data->client = client;
 484        mutex_init(&data->lock);
 485
 486        i2c_set_clientdata(client, indio_dev);
 487        indio_dev->info = &mag3110_info;
 488        indio_dev->name = id->name;
 489        indio_dev->dev.parent = &client->dev;
 490        indio_dev->modes = INDIO_DIRECT_MODE;
 491        indio_dev->channels = mag3110_channels;
 492        indio_dev->num_channels = ARRAY_SIZE(mag3110_channels);
 493        indio_dev->available_scan_masks = mag3110_scan_masks;
 494
 495        data->ctrl_reg1 = MAG3110_CTRL_DR_DEFAULT << MAG3110_CTRL_DR_SHIFT;
 496        data->sleep_val = mag3110_calculate_sleep(data);
 497        if (data->sleep_val < 40)
 498                data->ctrl_reg1 |= MAG3110_CTRL_AC;
 499
 500        ret = mag3110_change_config(data, MAG3110_CTRL_REG1, data->ctrl_reg1);
 501        if (ret < 0)
 502                return ret;
 503
 504        ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG2,
 505                MAG3110_CTRL_AUTO_MRST_EN);
 506        if (ret < 0)
 507                goto standby_on_error;
 508
 509        ret = iio_triggered_buffer_setup(indio_dev, NULL,
 510                mag3110_trigger_handler, NULL);
 511        if (ret < 0)
 512                goto standby_on_error;
 513
 514        ret = iio_device_register(indio_dev);
 515        if (ret < 0)
 516                goto buffer_cleanup;
 517        return 0;
 518
 519buffer_cleanup:
 520        iio_triggered_buffer_cleanup(indio_dev);
 521standby_on_error:
 522        mag3110_standby(iio_priv(indio_dev));
 523        return ret;
 524}
 525
 526static int mag3110_remove(struct i2c_client *client)
 527{
 528        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 529
 530        iio_device_unregister(indio_dev);
 531        iio_triggered_buffer_cleanup(indio_dev);
 532        mag3110_standby(iio_priv(indio_dev));
 533
 534        return 0;
 535}
 536
 537#ifdef CONFIG_PM_SLEEP
 538static int mag3110_suspend(struct device *dev)
 539{
 540        return mag3110_standby(iio_priv(i2c_get_clientdata(
 541                to_i2c_client(dev))));
 542}
 543
 544static int mag3110_resume(struct device *dev)
 545{
 546        struct mag3110_data *data = iio_priv(i2c_get_clientdata(
 547                to_i2c_client(dev)));
 548
 549        return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
 550                data->ctrl_reg1);
 551}
 552
 553static SIMPLE_DEV_PM_OPS(mag3110_pm_ops, mag3110_suspend, mag3110_resume);
 554#define MAG3110_PM_OPS (&mag3110_pm_ops)
 555#else
 556#define MAG3110_PM_OPS NULL
 557#endif
 558
 559static const struct i2c_device_id mag3110_id[] = {
 560        { "mag3110", 0 },
 561        { }
 562};
 563MODULE_DEVICE_TABLE(i2c, mag3110_id);
 564
 565static const struct of_device_id mag3110_of_match[] = {
 566        { .compatible = "fsl,mag3110" },
 567        { }
 568};
 569MODULE_DEVICE_TABLE(of, mag3110_of_match);
 570
 571static struct i2c_driver mag3110_driver = {
 572        .driver = {
 573                .name   = "mag3110",
 574                .of_match_table = mag3110_of_match,
 575                .pm     = MAG3110_PM_OPS,
 576        },
 577        .probe = mag3110_probe,
 578        .remove = mag3110_remove,
 579        .id_table = mag3110_id,
 580};
 581module_i2c_driver(mag3110_driver);
 582
 583MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
 584MODULE_DESCRIPTION("Freescale MAG3110 magnetometer driver");
 585MODULE_LICENSE("GPL");
 586