linux/drivers/iio/gyro/adis16136.c
<<
>>
Prefs
   1/*
   2 * ADIS16133/ADIS16135/ADIS16136 gyroscope driver
   3 *
   4 * Copyright 2012 Analog Devices Inc.
   5 *   Author: Lars-Peter Clausen <lars@metafoo.de>
   6 *
   7 * Licensed under the GPL-2.
   8 */
   9
  10#include <linux/interrupt.h>
  11#include <linux/delay.h>
  12#include <linux/mutex.h>
  13#include <linux/device.h>
  14#include <linux/kernel.h>
  15#include <linux/spi/spi.h>
  16#include <linux/slab.h>
  17#include <linux/sysfs.h>
  18#include <linux/module.h>
  19
  20#include <linux/iio/iio.h>
  21#include <linux/iio/sysfs.h>
  22#include <linux/iio/buffer.h>
  23#include <linux/iio/imu/adis.h>
  24
  25#include <linux/debugfs.h>
  26
  27#define ADIS16136_REG_FLASH_CNT         0x00
  28#define ADIS16136_REG_TEMP_OUT          0x02
  29#define ADIS16136_REG_GYRO_OUT2         0x04
  30#define ADIS16136_REG_GYRO_OUT          0x06
  31#define ADIS16136_REG_GYRO_OFF2         0x08
  32#define ADIS16136_REG_GYRO_OFF          0x0A
  33#define ADIS16136_REG_ALM_MAG1          0x10
  34#define ADIS16136_REG_ALM_MAG2          0x12
  35#define ADIS16136_REG_ALM_SAMPL1        0x14
  36#define ADIS16136_REG_ALM_SAMPL2        0x16
  37#define ADIS16136_REG_ALM_CTRL          0x18
  38#define ADIS16136_REG_GPIO_CTRL         0x1A
  39#define ADIS16136_REG_MSC_CTRL          0x1C
  40#define ADIS16136_REG_SMPL_PRD          0x1E
  41#define ADIS16136_REG_AVG_CNT           0x20
  42#define ADIS16136_REG_DEC_RATE          0x22
  43#define ADIS16136_REG_SLP_CTRL          0x24
  44#define ADIS16136_REG_DIAG_STAT         0x26
  45#define ADIS16136_REG_GLOB_CMD          0x28
  46#define ADIS16136_REG_LOT1              0x32
  47#define ADIS16136_REG_LOT2              0x34
  48#define ADIS16136_REG_LOT3              0x36
  49#define ADIS16136_REG_PROD_ID           0x38
  50#define ADIS16136_REG_SERIAL_NUM        0x3A
  51
  52#define ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL   2
  53#define ADIS16136_DIAG_STAT_SPI_FAIL            3
  54#define ADIS16136_DIAG_STAT_SELF_TEST_FAIL      5
  55#define ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL   6
  56
  57#define ADIS16136_MSC_CTRL_MEMORY_TEST BIT(11)
  58#define ADIS16136_MSC_CTRL_SELF_TEST BIT(10)
  59
  60struct adis16136_chip_info {
  61        unsigned int precision;
  62        unsigned int fullscale;
  63};
  64
  65struct adis16136 {
  66        const struct adis16136_chip_info *chip_info;
  67
  68        struct adis adis;
  69};
  70
  71#ifdef CONFIG_DEBUG_FS
  72
  73static ssize_t adis16136_show_serial(struct file *file,
  74                char __user *userbuf, size_t count, loff_t *ppos)
  75{
  76        struct adis16136 *adis16136 = file->private_data;
  77        uint16_t lot1, lot2, lot3, serial;
  78        char buf[20];
  79        size_t len;
  80        int ret;
  81
  82        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SERIAL_NUM,
  83                &serial);
  84        if (ret < 0)
  85                return ret;
  86
  87        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT1, &lot1);
  88        if (ret < 0)
  89                return ret;
  90
  91        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT2, &lot2);
  92        if (ret < 0)
  93                return ret;
  94
  95        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT3, &lot3);
  96        if (ret < 0)
  97                return ret;
  98
  99        len = snprintf(buf, sizeof(buf), "%.4x%.4x%.4x-%.4x\n", lot1, lot2,
 100                lot3, serial);
 101
 102        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
 103}
 104
 105static const struct file_operations adis16136_serial_fops = {
 106        .open = simple_open,
 107        .read = adis16136_show_serial,
 108        .llseek = default_llseek,
 109        .owner = THIS_MODULE,
 110};
 111
 112static int adis16136_show_product_id(void *arg, u64 *val)
 113{
 114        struct adis16136 *adis16136 = arg;
 115        u16 prod_id;
 116        int ret;
 117
 118        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID,
 119                &prod_id);
 120        if (ret < 0)
 121                return ret;
 122
 123        *val = prod_id;
 124
 125        return 0;
 126}
 127DEFINE_SIMPLE_ATTRIBUTE(adis16136_product_id_fops,
 128        adis16136_show_product_id, NULL, "%llu\n");
 129
 130static int adis16136_show_flash_count(void *arg, u64 *val)
 131{
 132        struct adis16136 *adis16136 = arg;
 133        uint16_t flash_count;
 134        int ret;
 135
 136        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_FLASH_CNT,
 137                &flash_count);
 138        if (ret < 0)
 139                return ret;
 140
 141        *val = flash_count;
 142
 143        return 0;
 144}
 145DEFINE_SIMPLE_ATTRIBUTE(adis16136_flash_count_fops,
 146        adis16136_show_flash_count, NULL, "%lld\n");
 147
 148static int adis16136_debugfs_init(struct iio_dev *indio_dev)
 149{
 150        struct adis16136 *adis16136 = iio_priv(indio_dev);
 151
 152        debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
 153                adis16136, &adis16136_serial_fops);
 154        debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
 155                adis16136, &adis16136_product_id_fops);
 156        debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
 157                adis16136, &adis16136_flash_count_fops);
 158
 159        return 0;
 160}
 161
 162#else
 163
 164static int adis16136_debugfs_init(struct iio_dev *indio_dev)
 165{
 166        return 0;
 167}
 168
 169#endif
 170
 171static int adis16136_set_freq(struct adis16136 *adis16136, unsigned int freq)
 172{
 173        unsigned int t;
 174
 175        t = 32768 / freq;
 176        if (t < 0xf)
 177                t = 0xf;
 178        else if (t > 0xffff)
 179                t = 0xffff;
 180        else
 181                t--;
 182
 183        return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, t);
 184}
 185
 186static int adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq)
 187{
 188        uint16_t t;
 189        int ret;
 190
 191        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t);
 192        if (ret < 0)
 193                return ret;
 194
 195        *freq = 32768 / (t + 1);
 196
 197        return 0;
 198}
 199
 200static ssize_t adis16136_write_frequency(struct device *dev,
 201        struct device_attribute *attr, const char *buf, size_t len)
 202{
 203        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 204        struct adis16136 *adis16136 = iio_priv(indio_dev);
 205        unsigned int val;
 206        int ret;
 207
 208        ret = kstrtouint(buf, 10, &val);
 209        if (ret)
 210                return ret;
 211
 212        if (val == 0)
 213                return -EINVAL;
 214
 215        ret = adis16136_set_freq(adis16136, val);
 216
 217        return ret ? ret : len;
 218}
 219
 220static ssize_t adis16136_read_frequency(struct device *dev,
 221        struct device_attribute *attr, char *buf)
 222{
 223        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 224        struct adis16136 *adis16136 = iio_priv(indio_dev);
 225        unsigned int freq;
 226        int ret;
 227
 228        ret = adis16136_get_freq(adis16136, &freq);
 229        if (ret < 0)
 230                return ret;
 231
 232        return sprintf(buf, "%d\n", freq);
 233}
 234
 235static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 236                                  adis16136_read_frequency,
 237                                  adis16136_write_frequency);
 238
 239static const unsigned adis16136_3db_divisors[] = {
 240        [0] = 2, /* Special case */
 241        [1] = 6,
 242        [2] = 12,
 243        [3] = 25,
 244        [4] = 50,
 245        [5] = 100,
 246        [6] = 200,
 247        [7] = 200, /* Not a valid setting */
 248};
 249
 250static int adis16136_set_filter(struct iio_dev *indio_dev, int val)
 251{
 252        struct adis16136 *adis16136 = iio_priv(indio_dev);
 253        unsigned int freq;
 254        int i, ret;
 255
 256        ret = adis16136_get_freq(adis16136, &freq);
 257        if (ret < 0)
 258                return ret;
 259
 260        for (i = ARRAY_SIZE(adis16136_3db_divisors) - 1; i >= 1; i--) {
 261                if (freq / adis16136_3db_divisors[i] >= val)
 262                        break;
 263        }
 264
 265        return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i);
 266}
 267
 268static int adis16136_get_filter(struct iio_dev *indio_dev, int *val)
 269{
 270        struct adis16136 *adis16136 = iio_priv(indio_dev);
 271        unsigned int freq;
 272        uint16_t val16;
 273        int ret;
 274
 275        mutex_lock(&indio_dev->mlock);
 276
 277        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, &val16);
 278        if (ret < 0)
 279                goto err_unlock;
 280
 281        ret = adis16136_get_freq(adis16136, &freq);
 282        if (ret < 0)
 283                goto err_unlock;
 284
 285        *val = freq / adis16136_3db_divisors[val16 & 0x07];
 286
 287err_unlock:
 288        mutex_unlock(&indio_dev->mlock);
 289
 290        return ret ? ret : IIO_VAL_INT;
 291}
 292
 293static int adis16136_read_raw(struct iio_dev *indio_dev,
 294        const struct iio_chan_spec *chan, int *val, int *val2, long info)
 295{
 296        struct adis16136 *adis16136 = iio_priv(indio_dev);
 297        uint32_t val32;
 298        int ret;
 299
 300        switch (info) {
 301        case IIO_CHAN_INFO_RAW:
 302                return adis_single_conversion(indio_dev, chan, 0, val);
 303        case IIO_CHAN_INFO_SCALE:
 304                switch (chan->type) {
 305                case IIO_ANGL_VEL:
 306                        *val = adis16136->chip_info->precision;
 307                        *val2 = (adis16136->chip_info->fullscale << 16);
 308                        return IIO_VAL_FRACTIONAL;
 309                case IIO_TEMP:
 310                        *val = 10;
 311                        *val2 = 697000; /* 0.010697 degree Celsius */
 312                        return IIO_VAL_INT_PLUS_MICRO;
 313                default:
 314                        return -EINVAL;
 315                }
 316        case IIO_CHAN_INFO_CALIBBIAS:
 317                ret = adis_read_reg_32(&adis16136->adis,
 318                        ADIS16136_REG_GYRO_OFF2, &val32);
 319                if (ret < 0)
 320                        return ret;
 321
 322                *val = sign_extend32(val32, 31);
 323
 324                return IIO_VAL_INT;
 325        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 326                return adis16136_get_filter(indio_dev, val);
 327        default:
 328                return -EINVAL;
 329        }
 330}
 331
 332static int adis16136_write_raw(struct iio_dev *indio_dev,
 333        const struct iio_chan_spec *chan, int val, int val2, long info)
 334{
 335        struct adis16136 *adis16136 = iio_priv(indio_dev);
 336
 337        switch (info) {
 338        case IIO_CHAN_INFO_CALIBBIAS:
 339                return adis_write_reg_32(&adis16136->adis,
 340                        ADIS16136_REG_GYRO_OFF2, val);
 341        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 342                return adis16136_set_filter(indio_dev, val);
 343        default:
 344                break;
 345        }
 346
 347        return -EINVAL;
 348}
 349
 350enum {
 351        ADIS16136_SCAN_GYRO,
 352        ADIS16136_SCAN_TEMP,
 353};
 354
 355static const struct iio_chan_spec adis16136_channels[] = {
 356        {
 357                .type = IIO_ANGL_VEL,
 358                .modified = 1,
 359                .channel2 = IIO_MOD_X,
 360                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 361                        BIT(IIO_CHAN_INFO_CALIBBIAS) |
 362                        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
 363                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 364
 365                .address = ADIS16136_REG_GYRO_OUT2,
 366                .scan_index = ADIS16136_SCAN_GYRO,
 367                .scan_type = {
 368                        .sign = 's',
 369                        .realbits = 32,
 370                        .storagebits = 32,
 371                        .endianness = IIO_BE,
 372                },
 373        }, {
 374                .type = IIO_TEMP,
 375                .indexed = 1,
 376                .channel = 0,
 377                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 378                        BIT(IIO_CHAN_INFO_SCALE),
 379                .address = ADIS16136_REG_TEMP_OUT,
 380                .scan_index = ADIS16136_SCAN_TEMP,
 381                .scan_type = {
 382                        .sign = 's',
 383                        .realbits = 16,
 384                        .storagebits = 16,
 385                        .endianness = IIO_BE,
 386                },
 387        },
 388        IIO_CHAN_SOFT_TIMESTAMP(2),
 389};
 390
 391static struct attribute *adis16136_attributes[] = {
 392        &iio_dev_attr_sampling_frequency.dev_attr.attr,
 393        NULL
 394};
 395
 396static const struct attribute_group adis16136_attribute_group = {
 397        .attrs = adis16136_attributes,
 398};
 399
 400static const struct iio_info adis16136_info = {
 401        .driver_module = THIS_MODULE,
 402        .attrs = &adis16136_attribute_group,
 403        .read_raw = &adis16136_read_raw,
 404        .write_raw = &adis16136_write_raw,
 405        .update_scan_mode = adis_update_scan_mode,
 406        .debugfs_reg_access = adis_debugfs_reg_access,
 407};
 408
 409static int adis16136_stop_device(struct iio_dev *indio_dev)
 410{
 411        struct adis16136 *adis16136 = iio_priv(indio_dev);
 412        int ret;
 413
 414        ret = adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SLP_CTRL, 0xff);
 415        if (ret)
 416                dev_err(&indio_dev->dev,
 417                        "Could not power down device: %d\n", ret);
 418
 419        return ret;
 420}
 421
 422static int adis16136_initial_setup(struct iio_dev *indio_dev)
 423{
 424        struct adis16136 *adis16136 = iio_priv(indio_dev);
 425        unsigned int device_id;
 426        uint16_t prod_id;
 427        int ret;
 428
 429        ret = adis_initial_startup(&adis16136->adis);
 430        if (ret)
 431                return ret;
 432
 433        ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID,
 434                &prod_id);
 435        if (ret)
 436                return ret;
 437
 438        sscanf(indio_dev->name, "adis%u\n", &device_id);
 439
 440        if (prod_id != device_id)
 441                dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
 442                                device_id, prod_id);
 443
 444        return 0;
 445}
 446
 447static const char * const adis16136_status_error_msgs[] = {
 448        [ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL] = "Flash update failed",
 449        [ADIS16136_DIAG_STAT_SPI_FAIL] = "SPI failure",
 450        [ADIS16136_DIAG_STAT_SELF_TEST_FAIL] = "Self test error",
 451        [ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL] = "Flash checksum error",
 452};
 453
 454static const struct adis_data adis16136_data = {
 455        .diag_stat_reg = ADIS16136_REG_DIAG_STAT,
 456        .glob_cmd_reg = ADIS16136_REG_GLOB_CMD,
 457        .msc_ctrl_reg = ADIS16136_REG_MSC_CTRL,
 458
 459        .self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST,
 460        .startup_delay = 80,
 461
 462        .read_delay = 10,
 463        .write_delay = 10,
 464
 465        .status_error_msgs = adis16136_status_error_msgs,
 466        .status_error_mask = BIT(ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL) |
 467                BIT(ADIS16136_DIAG_STAT_SPI_FAIL) |
 468                BIT(ADIS16136_DIAG_STAT_SELF_TEST_FAIL) |
 469                BIT(ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL),
 470};
 471
 472enum adis16136_id {
 473        ID_ADIS16133,
 474        ID_ADIS16135,
 475        ID_ADIS16136,
 476};
 477
 478static const struct adis16136_chip_info adis16136_chip_info[] = {
 479        [ID_ADIS16133] = {
 480                .precision = IIO_DEGREE_TO_RAD(1200),
 481                .fullscale = 24000,
 482        },
 483        [ID_ADIS16135] = {
 484                .precision = IIO_DEGREE_TO_RAD(300),
 485                .fullscale = 24000,
 486        },
 487        [ID_ADIS16136] = {
 488                .precision = IIO_DEGREE_TO_RAD(450),
 489                .fullscale = 24623,
 490        },
 491};
 492
 493static int adis16136_probe(struct spi_device *spi)
 494{
 495        const struct spi_device_id *id = spi_get_device_id(spi);
 496        struct adis16136 *adis16136;
 497        struct iio_dev *indio_dev;
 498        int ret;
 499
 500        indio_dev = iio_device_alloc(sizeof(*adis16136));
 501        if (indio_dev == NULL)
 502                return -ENOMEM;
 503
 504        spi_set_drvdata(spi, indio_dev);
 505
 506        adis16136 = iio_priv(indio_dev);
 507
 508        adis16136->chip_info = &adis16136_chip_info[id->driver_data];
 509        indio_dev->dev.parent = &spi->dev;
 510        indio_dev->name = spi_get_device_id(spi)->name;
 511        indio_dev->channels = adis16136_channels;
 512        indio_dev->num_channels = ARRAY_SIZE(adis16136_channels);
 513        indio_dev->info = &adis16136_info;
 514        indio_dev->modes = INDIO_DIRECT_MODE;
 515
 516        ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
 517        if (ret)
 518                goto error_free_dev;
 519
 520        ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
 521        if (ret)
 522                goto error_free_dev;
 523
 524        ret = adis16136_initial_setup(indio_dev);
 525        if (ret)
 526                goto error_cleanup_buffer;
 527
 528        ret = iio_device_register(indio_dev);
 529        if (ret)
 530                goto error_stop_device;
 531
 532        adis16136_debugfs_init(indio_dev);
 533
 534        return 0;
 535
 536error_stop_device:
 537        adis16136_stop_device(indio_dev);
 538error_cleanup_buffer:
 539        adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
 540error_free_dev:
 541        iio_device_free(indio_dev);
 542        return ret;
 543}
 544
 545static int adis16136_remove(struct spi_device *spi)
 546{
 547        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 548        struct adis16136 *adis16136 = iio_priv(indio_dev);
 549
 550        iio_device_unregister(indio_dev);
 551        adis16136_stop_device(indio_dev);
 552
 553        adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
 554
 555        iio_device_free(indio_dev);
 556
 557        return 0;
 558}
 559
 560static const struct spi_device_id adis16136_ids[] = {
 561        { "adis16133", ID_ADIS16133 },
 562        { "adis16135", ID_ADIS16135 },
 563        { "adis16136", ID_ADIS16136 },
 564        { }
 565};
 566MODULE_DEVICE_TABLE(spi, adis16136_ids);
 567
 568static struct spi_driver adis16136_driver = {
 569        .driver = {
 570                .name = "adis16136",
 571                .owner = THIS_MODULE,
 572        },
 573        .id_table = adis16136_ids,
 574        .probe = adis16136_probe,
 575        .remove = adis16136_remove,
 576};
 577module_spi_driver(adis16136_driver);
 578
 579MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 580MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver");
 581MODULE_LICENSE("GPL v2");
 582