linux/drivers/iio/magnetometer/st_magn_core.c
<<
>>
Prefs
   1/*
   2 * STMicroelectronics magnetometers driver
   3 *
   4 * Copyright 2012-2013 STMicroelectronics Inc.
   5 *
   6 * Denis Ciocca <denis.ciocca@st.com>
   7 *
   8 * Licensed under the GPL-2.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/slab.h>
  14#include <linux/errno.h>
  15#include <linux/types.h>
  16#include <linux/mutex.h>
  17#include <linux/interrupt.h>
  18#include <linux/i2c.h>
  19#include <linux/gpio.h>
  20#include <linux/irq.h>
  21#include <linux/delay.h>
  22#include <linux/iio/iio.h>
  23#include <linux/iio/sysfs.h>
  24#include <linux/iio/buffer.h>
  25
  26#include <linux/iio/common/st_sensors.h>
  27#include "st_magn.h"
  28
  29#define ST_MAGN_NUMBER_DATA_CHANNELS            3
  30
  31/* DEFAULT VALUE FOR SENSORS */
  32#define ST_MAGN_DEFAULT_OUT_X_H_ADDR            0X03
  33#define ST_MAGN_DEFAULT_OUT_Y_H_ADDR            0X07
  34#define ST_MAGN_DEFAULT_OUT_Z_H_ADDR            0X05
  35
  36/* FULLSCALE */
  37#define ST_MAGN_FS_AVL_1300MG                   1300
  38#define ST_MAGN_FS_AVL_1900MG                   1900
  39#define ST_MAGN_FS_AVL_2500MG                   2500
  40#define ST_MAGN_FS_AVL_4000MG                   4000
  41#define ST_MAGN_FS_AVL_4700MG                   4700
  42#define ST_MAGN_FS_AVL_5600MG                   5600
  43#define ST_MAGN_FS_AVL_8000MG                   8000
  44#define ST_MAGN_FS_AVL_8100MG                   8100
  45#define ST_MAGN_FS_AVL_12000MG                  12000
  46#define ST_MAGN_FS_AVL_15000MG                  15000
  47#define ST_MAGN_FS_AVL_16000MG                  16000
  48
  49/* Special L addresses for Sensor 2 */
  50#define ST_MAGN_2_OUT_X_L_ADDR                  0x28
  51#define ST_MAGN_2_OUT_Y_L_ADDR                  0x2a
  52#define ST_MAGN_2_OUT_Z_L_ADDR                  0x2c
  53
  54/* Special L addresses for sensor 3 */
  55#define ST_MAGN_3_OUT_X_L_ADDR                  0x68
  56#define ST_MAGN_3_OUT_Y_L_ADDR                  0x6a
  57#define ST_MAGN_3_OUT_Z_L_ADDR                  0x6c
  58
  59static const struct iio_chan_spec st_magn_16bit_channels[] = {
  60        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  61                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  62                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_BE, 16, 16,
  63                        ST_MAGN_DEFAULT_OUT_X_H_ADDR),
  64        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  65                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  66                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_BE, 16, 16,
  67                        ST_MAGN_DEFAULT_OUT_Y_H_ADDR),
  68        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  69                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  70                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_BE, 16, 16,
  71                        ST_MAGN_DEFAULT_OUT_Z_H_ADDR),
  72        IIO_CHAN_SOFT_TIMESTAMP(3)
  73};
  74
  75static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
  76        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  77                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  78                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
  79                        ST_MAGN_2_OUT_X_L_ADDR),
  80        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  81                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  82                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
  83                        ST_MAGN_2_OUT_Y_L_ADDR),
  84        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  85                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  86                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
  87                        ST_MAGN_2_OUT_Z_L_ADDR),
  88        IIO_CHAN_SOFT_TIMESTAMP(3)
  89};
  90
  91static const struct iio_chan_spec st_magn_3_16bit_channels[] = {
  92        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  93                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  94                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
  95                        ST_MAGN_3_OUT_X_L_ADDR),
  96        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
  97                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  98                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
  99                        ST_MAGN_3_OUT_Y_L_ADDR),
 100        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
 101                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 102                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
 103                        ST_MAGN_3_OUT_Z_L_ADDR),
 104        IIO_CHAN_SOFT_TIMESTAMP(3)
 105};
 106
 107static const struct st_sensor_settings st_magn_sensors_settings[] = {
 108        {
 109                .wai = 0, /* This sensor has no valid WhoAmI report 0 */
 110                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 111                .sensors_supported = {
 112                        [0] = LSM303DLH_MAGN_DEV_NAME,
 113                },
 114                .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
 115                .odr = {
 116                        .addr = 0x00,
 117                        .mask = 0x1c,
 118                        .odr_avl = {
 119                                { .hz = 1, .value = 0x00 },
 120                                { .hz = 2, .value = 0x01 },
 121                                { .hz = 3, .value = 0x02 },
 122                                { .hz = 8, .value = 0x03 },
 123                                { .hz = 15, .value = 0x04 },
 124                                { .hz = 30, .value = 0x05 },
 125                                { .hz = 75, .value = 0x06 },
 126                                /* 220 Hz, 0x07 reportedly exist */
 127                        },
 128                },
 129                .pw = {
 130                        .addr = 0x02,
 131                        .mask = 0x03,
 132                        .value_on = 0x00,
 133                        .value_off = 0x03,
 134                },
 135                .fs = {
 136                        .addr = 0x01,
 137                        .mask = 0xe0,
 138                        .fs_avl = {
 139                                [0] = {
 140                                        .num = ST_MAGN_FS_AVL_1300MG,
 141                                        .value = 0x01,
 142                                        .gain = 1100,
 143                                        .gain2 = 980,
 144                                },
 145                                [1] = {
 146                                        .num = ST_MAGN_FS_AVL_1900MG,
 147                                        .value = 0x02,
 148                                        .gain = 855,
 149                                        .gain2 = 760,
 150                                },
 151                                [2] = {
 152                                        .num = ST_MAGN_FS_AVL_2500MG,
 153                                        .value = 0x03,
 154                                        .gain = 670,
 155                                        .gain2 = 600,
 156                                },
 157                                [3] = {
 158                                        .num = ST_MAGN_FS_AVL_4000MG,
 159                                        .value = 0x04,
 160                                        .gain = 450,
 161                                        .gain2 = 400,
 162                                },
 163                                [4] = {
 164                                        .num = ST_MAGN_FS_AVL_4700MG,
 165                                        .value = 0x05,
 166                                        .gain = 400,
 167                                        .gain2 = 355,
 168                                },
 169                                [5] = {
 170                                        .num = ST_MAGN_FS_AVL_5600MG,
 171                                        .value = 0x06,
 172                                        .gain = 330,
 173                                        .gain2 = 295,
 174                                },
 175                                [6] = {
 176                                        .num = ST_MAGN_FS_AVL_8100MG,
 177                                        .value = 0x07,
 178                                        .gain = 230,
 179                                        .gain2 = 205,
 180                                },
 181                        },
 182                },
 183                .multi_read_bit = false,
 184                .bootime = 2,
 185        },
 186        {
 187                .wai = 0x3c,
 188                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 189                .sensors_supported = {
 190                        [0] = LSM303DLHC_MAGN_DEV_NAME,
 191                        [1] = LSM303DLM_MAGN_DEV_NAME,
 192                },
 193                .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
 194                .odr = {
 195                        .addr = 0x00,
 196                        .mask = 0x1c,
 197                        .odr_avl = {
 198                                { .hz = 1, .value = 0x00 },
 199                                { .hz = 2, .value = 0x01 },
 200                                { .hz = 3, .value = 0x02 },
 201                                { .hz = 8, .value = 0x03 },
 202                                { .hz = 15, .value = 0x04 },
 203                                { .hz = 30, .value = 0x05 },
 204                                { .hz = 75, .value = 0x06 },
 205                                { .hz = 220, .value = 0x07 },
 206                        },
 207                },
 208                .pw = {
 209                        .addr = 0x02,
 210                        .mask = 0x03,
 211                        .value_on = 0x00,
 212                        .value_off = 0x03,
 213                },
 214                .fs = {
 215                        .addr = 0x01,
 216                        .mask = 0xe0,
 217                        .fs_avl = {
 218                                [0] = {
 219                                        .num = ST_MAGN_FS_AVL_1300MG,
 220                                        .value = 0x01,
 221                                        .gain = 909,
 222                                        .gain2 = 1020,
 223                                },
 224                                [1] = {
 225                                        .num = ST_MAGN_FS_AVL_1900MG,
 226                                        .value = 0x02,
 227                                        .gain = 1169,
 228                                        .gain2 = 1315,
 229                                },
 230                                [2] = {
 231                                        .num = ST_MAGN_FS_AVL_2500MG,
 232                                        .value = 0x03,
 233                                        .gain = 1492,
 234                                        .gain2 = 1666,
 235                                },
 236                                [3] = {
 237                                        .num = ST_MAGN_FS_AVL_4000MG,
 238                                        .value = 0x04,
 239                                        .gain = 2222,
 240                                        .gain2 = 2500,
 241                                },
 242                                [4] = {
 243                                        .num = ST_MAGN_FS_AVL_4700MG,
 244                                        .value = 0x05,
 245                                        .gain = 2500,
 246                                        .gain2 = 2816,
 247                                },
 248                                [5] = {
 249                                        .num = ST_MAGN_FS_AVL_5600MG,
 250                                        .value = 0x06,
 251                                        .gain = 3030,
 252                                        .gain2 = 3389,
 253                                },
 254                                [6] = {
 255                                        .num = ST_MAGN_FS_AVL_8100MG,
 256                                        .value = 0x07,
 257                                        .gain = 4347,
 258                                        .gain2 = 4878,
 259                                },
 260                        },
 261                },
 262                .multi_read_bit = false,
 263                .bootime = 2,
 264        },
 265        {
 266                .wai = 0x3d,
 267                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 268                .sensors_supported = {
 269                        [0] = LIS3MDL_MAGN_DEV_NAME,
 270                },
 271                .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels,
 272                .odr = {
 273                        .addr = 0x20,
 274                        .mask = 0x1c,
 275                        .odr_avl = {
 276                                { .hz = 1, .value = 0x00 },
 277                                { .hz = 2, .value = 0x01 },
 278                                { .hz = 3, .value = 0x02 },
 279                                { .hz = 5, .value = 0x03 },
 280                                { .hz = 10, .value = 0x04 },
 281                                { .hz = 20, .value = 0x05 },
 282                                { .hz = 40, .value = 0x06 },
 283                                { .hz = 80, .value = 0x07 },
 284                        },
 285                },
 286                .pw = {
 287                        .addr = 0x22,
 288                        .mask = 0x03,
 289                        .value_on = 0x00,
 290                        .value_off = 0x03,
 291                },
 292                .fs = {
 293                        .addr = 0x21,
 294                        .mask = 0x60,
 295                        .fs_avl = {
 296                                [0] = {
 297                                        .num = ST_MAGN_FS_AVL_4000MG,
 298                                        .value = 0x00,
 299                                        .gain = 146,
 300                                },
 301                                [1] = {
 302                                        .num = ST_MAGN_FS_AVL_8000MG,
 303                                        .value = 0x01,
 304                                        .gain = 292,
 305                                },
 306                                [2] = {
 307                                        .num = ST_MAGN_FS_AVL_12000MG,
 308                                        .value = 0x02,
 309                                        .gain = 438,
 310                                },
 311                                [3] = {
 312                                        .num = ST_MAGN_FS_AVL_16000MG,
 313                                        .value = 0x03,
 314                                        .gain = 584,
 315                                },
 316                        },
 317                },
 318                .multi_read_bit = false,
 319                .bootime = 2,
 320        },
 321        {
 322                .wai = 0x40,
 323                .wai_addr = 0x4f,
 324                .sensors_supported = {
 325                        [0] = LSM303AGR_MAGN_DEV_NAME,
 326                },
 327                .ch = (struct iio_chan_spec *)st_magn_3_16bit_channels,
 328                .odr = {
 329                        .addr = 0x60,
 330                        .mask = 0x0c,
 331                        .odr_avl = {
 332                                { .hz = 10, .value = 0x00 },
 333                                { .hz = 20, .value = 0x01 },
 334                                { .hz = 50, .value = 0x02 },
 335                                { .hz = 100, .value = 0x03 },
 336                        },
 337                },
 338                .pw = {
 339                        .addr = 0x60,
 340                        .mask = 0x03,
 341                        .value_on = 0x00,
 342                        .value_off = 0x03,
 343                },
 344                .fs = {
 345                        .fs_avl = {
 346                                [0] = {
 347                                        .num = ST_MAGN_FS_AVL_15000MG,
 348                                        .gain = 1500,
 349                                },
 350                        },
 351                },
 352                .bdu = {
 353                        .addr = 0x62,
 354                        .mask = 0x10,
 355                },
 356                .drdy_irq = {
 357                        .addr = 0x62,
 358                        .mask_int1 = 0x01,
 359                        .addr_stat_drdy = 0x67,
 360                },
 361                .multi_read_bit = false,
 362                .bootime = 2,
 363        },
 364};
 365
 366static int st_magn_read_raw(struct iio_dev *indio_dev,
 367                        struct iio_chan_spec const *ch, int *val,
 368                                                        int *val2, long mask)
 369{
 370        int err;
 371        struct st_sensor_data *mdata = iio_priv(indio_dev);
 372
 373        switch (mask) {
 374        case IIO_CHAN_INFO_RAW:
 375                err = st_sensors_read_info_raw(indio_dev, ch, val);
 376                if (err < 0)
 377                        goto read_error;
 378
 379                return IIO_VAL_INT;
 380        case IIO_CHAN_INFO_SCALE:
 381                *val = 0;
 382                if ((ch->scan_index == ST_SENSORS_SCAN_Z) &&
 383                                        (mdata->current_fullscale->gain2 != 0))
 384                        *val2 = mdata->current_fullscale->gain2;
 385                else
 386                        *val2 = mdata->current_fullscale->gain;
 387                return IIO_VAL_INT_PLUS_MICRO;
 388        case IIO_CHAN_INFO_SAMP_FREQ:
 389                *val = mdata->odr;
 390                return IIO_VAL_INT;
 391        default:
 392                return -EINVAL;
 393        }
 394
 395read_error:
 396        return err;
 397}
 398
 399static int st_magn_write_raw(struct iio_dev *indio_dev,
 400                struct iio_chan_spec const *chan, int val, int val2, long mask)
 401{
 402        int err;
 403
 404        switch (mask) {
 405        case IIO_CHAN_INFO_SCALE:
 406                err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 407                break;
 408        case IIO_CHAN_INFO_SAMP_FREQ:
 409                if (val2)
 410                        return -EINVAL;
 411                mutex_lock(&indio_dev->mlock);
 412                err = st_sensors_set_odr(indio_dev, val);
 413                mutex_unlock(&indio_dev->mlock);
 414                return err;
 415        default:
 416                err = -EINVAL;
 417        }
 418
 419        return err;
 420}
 421
 422static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 423static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
 424
 425static struct attribute *st_magn_attributes[] = {
 426        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 427        &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
 428        NULL,
 429};
 430
 431static const struct attribute_group st_magn_attribute_group = {
 432        .attrs = st_magn_attributes,
 433};
 434
 435static const struct iio_info magn_info = {
 436        .driver_module = THIS_MODULE,
 437        .attrs = &st_magn_attribute_group,
 438        .read_raw = &st_magn_read_raw,
 439        .write_raw = &st_magn_write_raw,
 440        .debugfs_reg_access = &st_sensors_debugfs_reg_access,
 441};
 442
 443#ifdef CONFIG_IIO_TRIGGER
 444static const struct iio_trigger_ops st_magn_trigger_ops = {
 445        .owner = THIS_MODULE,
 446        .set_trigger_state = ST_MAGN_TRIGGER_SET_STATE,
 447        .validate_device = st_sensors_validate_device,
 448};
 449#define ST_MAGN_TRIGGER_OPS (&st_magn_trigger_ops)
 450#else
 451#define ST_MAGN_TRIGGER_OPS NULL
 452#endif
 453
 454int st_magn_common_probe(struct iio_dev *indio_dev)
 455{
 456        struct st_sensor_data *mdata = iio_priv(indio_dev);
 457        int irq = mdata->get_irq_data_ready(indio_dev);
 458        int err;
 459
 460        indio_dev->modes = INDIO_DIRECT_MODE;
 461        indio_dev->info = &magn_info;
 462        mutex_init(&mdata->tb.buf_lock);
 463
 464        err = st_sensors_power_enable(indio_dev);
 465        if (err)
 466                return err;
 467
 468        err = st_sensors_check_device_support(indio_dev,
 469                                        ARRAY_SIZE(st_magn_sensors_settings),
 470                                        st_magn_sensors_settings);
 471        if (err < 0)
 472                goto st_magn_power_off;
 473
 474        mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
 475        mdata->multiread_bit = mdata->sensor_settings->multi_read_bit;
 476        indio_dev->channels = mdata->sensor_settings->ch;
 477        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
 478
 479        mdata->current_fullscale = (struct st_sensor_fullscale_avl *)
 480                                        &mdata->sensor_settings->fs.fs_avl[0];
 481        mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
 482
 483        err = st_sensors_init_sensor(indio_dev, NULL);
 484        if (err < 0)
 485                goto st_magn_power_off;
 486
 487        err = st_magn_allocate_ring(indio_dev);
 488        if (err < 0)
 489                goto st_magn_power_off;
 490
 491        if (irq > 0) {
 492                err = st_sensors_allocate_trigger(indio_dev,
 493                                                ST_MAGN_TRIGGER_OPS);
 494                if (err < 0)
 495                        goto st_magn_probe_trigger_error;
 496        }
 497
 498        err = iio_device_register(indio_dev);
 499        if (err)
 500                goto st_magn_device_register_error;
 501
 502        dev_info(&indio_dev->dev, "registered magnetometer %s\n",
 503                 indio_dev->name);
 504
 505        return 0;
 506
 507st_magn_device_register_error:
 508        if (irq > 0)
 509                st_sensors_deallocate_trigger(indio_dev);
 510st_magn_probe_trigger_error:
 511        st_magn_deallocate_ring(indio_dev);
 512st_magn_power_off:
 513        st_sensors_power_disable(indio_dev);
 514
 515        return err;
 516}
 517EXPORT_SYMBOL(st_magn_common_probe);
 518
 519void st_magn_common_remove(struct iio_dev *indio_dev)
 520{
 521        struct st_sensor_data *mdata = iio_priv(indio_dev);
 522
 523        st_sensors_power_disable(indio_dev);
 524
 525        iio_device_unregister(indio_dev);
 526        if (mdata->get_irq_data_ready(indio_dev) > 0)
 527                st_sensors_deallocate_trigger(indio_dev);
 528
 529        st_magn_deallocate_ring(indio_dev);
 530}
 531EXPORT_SYMBOL(st_magn_common_remove);
 532
 533MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 534MODULE_DESCRIPTION("STMicroelectronics magnetometers driver");
 535MODULE_LICENSE("GPL v2");
 536