linux/drivers/iio/imu/adis16480.c
<<
>>
Prefs
   1/*
   2 * ADIS16480 and similar IMUs driver
   3 *
   4 * Copyright 2012 Analog Devices Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11
  12#include <linux/interrupt.h>
  13#include <linux/delay.h>
  14#include <linux/mutex.h>
  15#include <linux/device.h>
  16#include <linux/kernel.h>
  17#include <linux/spi/spi.h>
  18#include <linux/slab.h>
  19#include <linux/sysfs.h>
  20#include <linux/module.h>
  21
  22#include <linux/iio/iio.h>
  23#include <linux/iio/sysfs.h>
  24#include <linux/iio/buffer.h>
  25#include <linux/iio/imu/adis.h>
  26
  27#include <linux/debugfs.h>
  28
  29#define ADIS16480_PAGE_SIZE 0x80
  30
  31#define ADIS16480_REG(page, reg) ((page) * ADIS16480_PAGE_SIZE + (reg))
  32
  33#define ADIS16480_REG_PAGE_ID 0x00 /* Same address on each page */
  34#define ADIS16480_REG_SEQ_CNT                   ADIS16480_REG(0x00, 0x06)
  35#define ADIS16480_REG_SYS_E_FLA                 ADIS16480_REG(0x00, 0x08)
  36#define ADIS16480_REG_DIAG_STS                  ADIS16480_REG(0x00, 0x0A)
  37#define ADIS16480_REG_ALM_STS                   ADIS16480_REG(0x00, 0x0C)
  38#define ADIS16480_REG_TEMP_OUT                  ADIS16480_REG(0x00, 0x0E)
  39#define ADIS16480_REG_X_GYRO_OUT                ADIS16480_REG(0x00, 0x10)
  40#define ADIS16480_REG_Y_GYRO_OUT                ADIS16480_REG(0x00, 0x14)
  41#define ADIS16480_REG_Z_GYRO_OUT                ADIS16480_REG(0x00, 0x18)
  42#define ADIS16480_REG_X_ACCEL_OUT               ADIS16480_REG(0x00, 0x1C)
  43#define ADIS16480_REG_Y_ACCEL_OUT               ADIS16480_REG(0x00, 0x20)
  44#define ADIS16480_REG_Z_ACCEL_OUT               ADIS16480_REG(0x00, 0x24)
  45#define ADIS16480_REG_X_MAGN_OUT                ADIS16480_REG(0x00, 0x28)
  46#define ADIS16480_REG_Y_MAGN_OUT                ADIS16480_REG(0x00, 0x2A)
  47#define ADIS16480_REG_Z_MAGN_OUT                ADIS16480_REG(0x00, 0x2C)
  48#define ADIS16480_REG_BAROM_OUT                 ADIS16480_REG(0x00, 0x2E)
  49#define ADIS16480_REG_X_DELTAANG_OUT            ADIS16480_REG(0x00, 0x40)
  50#define ADIS16480_REG_Y_DELTAANG_OUT            ADIS16480_REG(0x00, 0x44)
  51#define ADIS16480_REG_Z_DELTAANG_OUT            ADIS16480_REG(0x00, 0x48)
  52#define ADIS16480_REG_X_DELTAVEL_OUT            ADIS16480_REG(0x00, 0x4C)
  53#define ADIS16480_REG_Y_DELTAVEL_OUT            ADIS16480_REG(0x00, 0x50)
  54#define ADIS16480_REG_Z_DELTAVEL_OUT            ADIS16480_REG(0x00, 0x54)
  55#define ADIS16480_REG_PROD_ID                   ADIS16480_REG(0x00, 0x7E)
  56
  57#define ADIS16480_REG_X_GYRO_SCALE              ADIS16480_REG(0x02, 0x04)
  58#define ADIS16480_REG_Y_GYRO_SCALE              ADIS16480_REG(0x02, 0x06)
  59#define ADIS16480_REG_Z_GYRO_SCALE              ADIS16480_REG(0x02, 0x08)
  60#define ADIS16480_REG_X_ACCEL_SCALE             ADIS16480_REG(0x02, 0x0A)
  61#define ADIS16480_REG_Y_ACCEL_SCALE             ADIS16480_REG(0x02, 0x0C)
  62#define ADIS16480_REG_Z_ACCEL_SCALE             ADIS16480_REG(0x02, 0x0E)
  63#define ADIS16480_REG_X_GYRO_BIAS               ADIS16480_REG(0x02, 0x10)
  64#define ADIS16480_REG_Y_GYRO_BIAS               ADIS16480_REG(0x02, 0x14)
  65#define ADIS16480_REG_Z_GYRO_BIAS               ADIS16480_REG(0x02, 0x18)
  66#define ADIS16480_REG_X_ACCEL_BIAS              ADIS16480_REG(0x02, 0x1C)
  67#define ADIS16480_REG_Y_ACCEL_BIAS              ADIS16480_REG(0x02, 0x20)
  68#define ADIS16480_REG_Z_ACCEL_BIAS              ADIS16480_REG(0x02, 0x24)
  69#define ADIS16480_REG_X_HARD_IRON               ADIS16480_REG(0x02, 0x28)
  70#define ADIS16480_REG_Y_HARD_IRON               ADIS16480_REG(0x02, 0x2A)
  71#define ADIS16480_REG_Z_HARD_IRON               ADIS16480_REG(0x02, 0x2C)
  72#define ADIS16480_REG_BAROM_BIAS                ADIS16480_REG(0x02, 0x40)
  73#define ADIS16480_REG_FLASH_CNT                 ADIS16480_REG(0x02, 0x7C)
  74
  75#define ADIS16480_REG_GLOB_CMD                  ADIS16480_REG(0x03, 0x02)
  76#define ADIS16480_REG_FNCTIO_CTRL               ADIS16480_REG(0x03, 0x06)
  77#define ADIS16480_REG_GPIO_CTRL                 ADIS16480_REG(0x03, 0x08)
  78#define ADIS16480_REG_CONFIG                    ADIS16480_REG(0x03, 0x0A)
  79#define ADIS16480_REG_DEC_RATE                  ADIS16480_REG(0x03, 0x0C)
  80#define ADIS16480_REG_SLP_CNT                   ADIS16480_REG(0x03, 0x10)
  81#define ADIS16480_REG_FILTER_BNK0               ADIS16480_REG(0x03, 0x16)
  82#define ADIS16480_REG_FILTER_BNK1               ADIS16480_REG(0x03, 0x18)
  83#define ADIS16480_REG_ALM_CNFG0                 ADIS16480_REG(0x03, 0x20)
  84#define ADIS16480_REG_ALM_CNFG1                 ADIS16480_REG(0x03, 0x22)
  85#define ADIS16480_REG_ALM_CNFG2                 ADIS16480_REG(0x03, 0x24)
  86#define ADIS16480_REG_XG_ALM_MAGN               ADIS16480_REG(0x03, 0x28)
  87#define ADIS16480_REG_YG_ALM_MAGN               ADIS16480_REG(0x03, 0x2A)
  88#define ADIS16480_REG_ZG_ALM_MAGN               ADIS16480_REG(0x03, 0x2C)
  89#define ADIS16480_REG_XA_ALM_MAGN               ADIS16480_REG(0x03, 0x2E)
  90#define ADIS16480_REG_YA_ALM_MAGN               ADIS16480_REG(0x03, 0x30)
  91#define ADIS16480_REG_ZA_ALM_MAGN               ADIS16480_REG(0x03, 0x32)
  92#define ADIS16480_REG_XM_ALM_MAGN               ADIS16480_REG(0x03, 0x34)
  93#define ADIS16480_REG_YM_ALM_MAGN               ADIS16480_REG(0x03, 0x36)
  94#define ADIS16480_REG_ZM_ALM_MAGN               ADIS16480_REG(0x03, 0x38)
  95#define ADIS16480_REG_BR_ALM_MAGN               ADIS16480_REG(0x03, 0x3A)
  96#define ADIS16480_REG_FIRM_REV                  ADIS16480_REG(0x03, 0x78)
  97#define ADIS16480_REG_FIRM_DM                   ADIS16480_REG(0x03, 0x7A)
  98#define ADIS16480_REG_FIRM_Y                    ADIS16480_REG(0x03, 0x7C)
  99
 100#define ADIS16480_REG_SERIAL_NUM                ADIS16480_REG(0x04, 0x20)
 101
 102/* Each filter coefficent bank spans two pages */
 103#define ADIS16480_FIR_COEF(page) (x < 60 ? ADIS16480_REG(page, (x) + 8) : \
 104                ADIS16480_REG((page) + 1, (x) - 60 + 8))
 105#define ADIS16480_FIR_COEF_A(x)                 ADIS16480_FIR_COEF(0x05, (x))
 106#define ADIS16480_FIR_COEF_B(x)                 ADIS16480_FIR_COEF(0x07, (x))
 107#define ADIS16480_FIR_COEF_C(x)                 ADIS16480_FIR_COEF(0x09, (x))
 108#define ADIS16480_FIR_COEF_D(x)                 ADIS16480_FIR_COEF(0x0B, (x))
 109
 110struct adis16480_chip_info {
 111        unsigned int num_channels;
 112        const struct iio_chan_spec *channels;
 113        unsigned int gyro_max_val;
 114        unsigned int gyro_max_scale;
 115        unsigned int accel_max_val;
 116        unsigned int accel_max_scale;
 117};
 118
 119struct adis16480 {
 120        const struct adis16480_chip_info *chip_info;
 121
 122        struct adis adis;
 123};
 124
 125#ifdef CONFIG_DEBUG_FS
 126
 127static ssize_t adis16480_show_firmware_revision(struct file *file,
 128                char __user *userbuf, size_t count, loff_t *ppos)
 129{
 130        struct adis16480 *adis16480 = file->private_data;
 131        char buf[7];
 132        size_t len;
 133        u16 rev;
 134        int ret;
 135
 136        ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_REV, &rev);
 137        if (ret < 0)
 138                return ret;
 139
 140        len = scnprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev & 0xff);
 141
 142        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
 143}
 144
 145static const struct file_operations adis16480_firmware_revision_fops = {
 146        .open = simple_open,
 147        .read = adis16480_show_firmware_revision,
 148        .llseek = default_llseek,
 149        .owner = THIS_MODULE,
 150};
 151
 152static ssize_t adis16480_show_firmware_date(struct file *file,
 153                char __user *userbuf, size_t count, loff_t *ppos)
 154{
 155        struct adis16480 *adis16480 = file->private_data;
 156        u16 md, year;
 157        char buf[12];
 158        size_t len;
 159        int ret;
 160
 161        ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_Y, &year);
 162        if (ret < 0)
 163                return ret;
 164
 165        ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_DM, &md);
 166        if (ret < 0)
 167                return ret;
 168
 169        len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n",
 170                        md >> 8, md & 0xff, year);
 171
 172        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
 173}
 174
 175static const struct file_operations adis16480_firmware_date_fops = {
 176        .open = simple_open,
 177        .read = adis16480_show_firmware_date,
 178        .llseek = default_llseek,
 179        .owner = THIS_MODULE,
 180};
 181
 182static int adis16480_show_serial_number(void *arg, u64 *val)
 183{
 184        struct adis16480 *adis16480 = arg;
 185        u16 serial;
 186        int ret;
 187
 188        ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_SERIAL_NUM,
 189                &serial);
 190        if (ret < 0)
 191                return ret;
 192
 193        *val = serial;
 194
 195        return 0;
 196}
 197DEFINE_SIMPLE_ATTRIBUTE(adis16480_serial_number_fops,
 198        adis16480_show_serial_number, NULL, "0x%.4llx\n");
 199
 200static int adis16480_show_product_id(void *arg, u64 *val)
 201{
 202        struct adis16480 *adis16480 = arg;
 203        u16 prod_id;
 204        int ret;
 205
 206        ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_PROD_ID,
 207                &prod_id);
 208        if (ret < 0)
 209                return ret;
 210
 211        *val = prod_id;
 212
 213        return 0;
 214}
 215DEFINE_SIMPLE_ATTRIBUTE(adis16480_product_id_fops,
 216        adis16480_show_product_id, NULL, "%llu\n");
 217
 218static int adis16480_show_flash_count(void *arg, u64 *val)
 219{
 220        struct adis16480 *adis16480 = arg;
 221        u32 flash_count;
 222        int ret;
 223
 224        ret = adis_read_reg_32(&adis16480->adis, ADIS16480_REG_FLASH_CNT,
 225                &flash_count);
 226        if (ret < 0)
 227                return ret;
 228
 229        *val = flash_count;
 230
 231        return 0;
 232}
 233DEFINE_SIMPLE_ATTRIBUTE(adis16480_flash_count_fops,
 234        adis16480_show_flash_count, NULL, "%lld\n");
 235
 236static int adis16480_debugfs_init(struct iio_dev *indio_dev)
 237{
 238        struct adis16480 *adis16480 = iio_priv(indio_dev);
 239
 240        debugfs_create_file("firmware_revision", 0400,
 241                indio_dev->debugfs_dentry, adis16480,
 242                &adis16480_firmware_revision_fops);
 243        debugfs_create_file("firmware_date", 0400, indio_dev->debugfs_dentry,
 244                adis16480, &adis16480_firmware_date_fops);
 245        debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
 246                adis16480, &adis16480_serial_number_fops);
 247        debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
 248                adis16480, &adis16480_product_id_fops);
 249        debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
 250                adis16480, &adis16480_flash_count_fops);
 251
 252        return 0;
 253}
 254
 255#else
 256
 257static int adis16480_debugfs_init(struct iio_dev *indio_dev)
 258{
 259        return 0;
 260}
 261
 262#endif
 263
 264static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2)
 265{
 266        struct adis16480 *st = iio_priv(indio_dev);
 267        unsigned int t;
 268
 269        t =  val * 1000 + val2 / 1000;
 270        if (t <= 0)
 271                return -EINVAL;
 272
 273        t = 2460000 / t;
 274        if (t > 2048)
 275                t = 2048;
 276
 277        if (t != 0)
 278                t--;
 279
 280        return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t);
 281}
 282
 283static int adis16480_get_freq(struct iio_dev *indio_dev, int *val, int *val2)
 284{
 285        struct adis16480 *st = iio_priv(indio_dev);
 286        uint16_t t;
 287        int ret;
 288        unsigned freq;
 289
 290        ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t);
 291        if (ret < 0)
 292                return ret;
 293
 294        freq = 2460000 / (t + 1);
 295        *val = freq / 1000;
 296        *val2 = (freq % 1000) * 1000;
 297
 298        return IIO_VAL_INT_PLUS_MICRO;
 299}
 300
 301enum {
 302        ADIS16480_SCAN_GYRO_X,
 303        ADIS16480_SCAN_GYRO_Y,
 304        ADIS16480_SCAN_GYRO_Z,
 305        ADIS16480_SCAN_ACCEL_X,
 306        ADIS16480_SCAN_ACCEL_Y,
 307        ADIS16480_SCAN_ACCEL_Z,
 308        ADIS16480_SCAN_MAGN_X,
 309        ADIS16480_SCAN_MAGN_Y,
 310        ADIS16480_SCAN_MAGN_Z,
 311        ADIS16480_SCAN_BARO,
 312        ADIS16480_SCAN_TEMP,
 313};
 314
 315static const unsigned int adis16480_calibbias_regs[] = {
 316        [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_BIAS,
 317        [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_BIAS,
 318        [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_BIAS,
 319        [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_BIAS,
 320        [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_BIAS,
 321        [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_BIAS,
 322        [ADIS16480_SCAN_MAGN_X] = ADIS16480_REG_X_HARD_IRON,
 323        [ADIS16480_SCAN_MAGN_Y] = ADIS16480_REG_Y_HARD_IRON,
 324        [ADIS16480_SCAN_MAGN_Z] = ADIS16480_REG_Z_HARD_IRON,
 325        [ADIS16480_SCAN_BARO] = ADIS16480_REG_BAROM_BIAS,
 326};
 327
 328static const unsigned int adis16480_calibscale_regs[] = {
 329        [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_SCALE,
 330        [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_SCALE,
 331        [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_SCALE,
 332        [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_SCALE,
 333        [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_SCALE,
 334        [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_SCALE,
 335};
 336
 337static int adis16480_set_calibbias(struct iio_dev *indio_dev,
 338        const struct iio_chan_spec *chan, int bias)
 339{
 340        unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
 341        struct adis16480 *st = iio_priv(indio_dev);
 342
 343        switch (chan->type) {
 344        case IIO_MAGN:
 345        case IIO_PRESSURE:
 346                if (bias < -0x8000 || bias >= 0x8000)
 347                        return -EINVAL;
 348                return adis_write_reg_16(&st->adis, reg, bias);
 349        case IIO_ANGL_VEL:
 350        case IIO_ACCEL:
 351                return adis_write_reg_32(&st->adis, reg, bias);
 352        default:
 353                break;
 354        }
 355
 356        return -EINVAL;
 357}
 358
 359static int adis16480_get_calibbias(struct iio_dev *indio_dev,
 360        const struct iio_chan_spec *chan, int *bias)
 361{
 362        unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
 363        struct adis16480 *st = iio_priv(indio_dev);
 364        uint16_t val16;
 365        uint32_t val32;
 366        int ret;
 367
 368        switch (chan->type) {
 369        case IIO_MAGN:
 370        case IIO_PRESSURE:
 371                ret = adis_read_reg_16(&st->adis, reg, &val16);
 372                *bias = sign_extend32(val16, 15);
 373                break;
 374        case IIO_ANGL_VEL:
 375        case IIO_ACCEL:
 376                ret = adis_read_reg_32(&st->adis, reg, &val32);
 377                *bias = sign_extend32(val32, 31);
 378                break;
 379        default:
 380                        ret = -EINVAL;
 381        }
 382
 383        if (ret < 0)
 384                return ret;
 385
 386        return IIO_VAL_INT;
 387}
 388
 389static int adis16480_set_calibscale(struct iio_dev *indio_dev,
 390        const struct iio_chan_spec *chan, int scale)
 391{
 392        unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
 393        struct adis16480 *st = iio_priv(indio_dev);
 394
 395        if (scale < -0x8000 || scale >= 0x8000)
 396                return -EINVAL;
 397
 398        return adis_write_reg_16(&st->adis, reg, scale);
 399}
 400
 401static int adis16480_get_calibscale(struct iio_dev *indio_dev,
 402        const struct iio_chan_spec *chan, int *scale)
 403{
 404        unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
 405        struct adis16480 *st = iio_priv(indio_dev);
 406        uint16_t val16;
 407        int ret;
 408
 409        ret = adis_read_reg_16(&st->adis, reg, &val16);
 410        if (ret < 0)
 411                return ret;
 412
 413        *scale = sign_extend32(val16, 15);
 414        return IIO_VAL_INT;
 415}
 416
 417static const unsigned int adis16480_def_filter_freqs[] = {
 418        310,
 419        55,
 420        275,
 421        63,
 422};
 423
 424static const unsigned int ad16480_filter_data[][2] = {
 425        [ADIS16480_SCAN_GYRO_X]         = { ADIS16480_REG_FILTER_BNK0, 0 },
 426        [ADIS16480_SCAN_GYRO_Y]         = { ADIS16480_REG_FILTER_BNK0, 3 },
 427        [ADIS16480_SCAN_GYRO_Z]         = { ADIS16480_REG_FILTER_BNK0, 6 },
 428        [ADIS16480_SCAN_ACCEL_X]        = { ADIS16480_REG_FILTER_BNK0, 9 },
 429        [ADIS16480_SCAN_ACCEL_Y]        = { ADIS16480_REG_FILTER_BNK0, 12 },
 430        [ADIS16480_SCAN_ACCEL_Z]        = { ADIS16480_REG_FILTER_BNK1, 0 },
 431        [ADIS16480_SCAN_MAGN_X]         = { ADIS16480_REG_FILTER_BNK1, 3 },
 432        [ADIS16480_SCAN_MAGN_Y]         = { ADIS16480_REG_FILTER_BNK1, 6 },
 433        [ADIS16480_SCAN_MAGN_Z]         = { ADIS16480_REG_FILTER_BNK1, 9 },
 434};
 435
 436static int adis16480_get_filter_freq(struct iio_dev *indio_dev,
 437        const struct iio_chan_spec *chan, int *freq)
 438{
 439        struct adis16480 *st = iio_priv(indio_dev);
 440        unsigned int enable_mask, offset, reg;
 441        uint16_t val;
 442        int ret;
 443
 444        reg = ad16480_filter_data[chan->scan_index][0];
 445        offset = ad16480_filter_data[chan->scan_index][1];
 446        enable_mask = BIT(offset + 2);
 447
 448        ret = adis_read_reg_16(&st->adis, reg, &val);
 449        if (ret < 0)
 450                return ret;
 451
 452        if (!(val & enable_mask))
 453                *freq = 0;
 454        else
 455                *freq = adis16480_def_filter_freqs[(val >> offset) & 0x3];
 456
 457        return IIO_VAL_INT;
 458}
 459
 460static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
 461        const struct iio_chan_spec *chan, unsigned int freq)
 462{
 463        struct adis16480 *st = iio_priv(indio_dev);
 464        unsigned int enable_mask, offset, reg;
 465        unsigned int diff, best_diff;
 466        unsigned int i, best_freq;
 467        uint16_t val;
 468        int ret;
 469
 470        reg = ad16480_filter_data[chan->scan_index][0];
 471        offset = ad16480_filter_data[chan->scan_index][1];
 472        enable_mask = BIT(offset + 2);
 473
 474        ret = adis_read_reg_16(&st->adis, reg, &val);
 475        if (ret < 0)
 476                return ret;
 477
 478        if (freq == 0) {
 479                val &= ~enable_mask;
 480        } else {
 481                best_freq = 0;
 482                best_diff = 310;
 483                for (i = 0; i < ARRAY_SIZE(adis16480_def_filter_freqs); i++) {
 484                        if (adis16480_def_filter_freqs[i] >= freq) {
 485                                diff = adis16480_def_filter_freqs[i] - freq;
 486                                if (diff < best_diff) {
 487                                        best_diff = diff;
 488                                        best_freq = i;
 489                                }
 490                        }
 491                }
 492
 493                val &= ~(0x3 << offset);
 494                val |= best_freq << offset;
 495                val |= enable_mask;
 496        }
 497
 498        return adis_write_reg_16(&st->adis, reg, val);
 499}
 500
 501static int adis16480_read_raw(struct iio_dev *indio_dev,
 502        const struct iio_chan_spec *chan, int *val, int *val2, long info)
 503{
 504        struct adis16480 *st = iio_priv(indio_dev);
 505
 506        switch (info) {
 507        case IIO_CHAN_INFO_RAW:
 508                return adis_single_conversion(indio_dev, chan, 0, val);
 509        case IIO_CHAN_INFO_SCALE:
 510                switch (chan->type) {
 511                case IIO_ANGL_VEL:
 512                        *val = st->chip_info->gyro_max_scale;
 513                        *val2 = st->chip_info->gyro_max_val;
 514                        return IIO_VAL_FRACTIONAL;
 515                case IIO_ACCEL:
 516                        *val = st->chip_info->accel_max_scale;
 517                        *val2 = st->chip_info->accel_max_val;
 518                        return IIO_VAL_FRACTIONAL;
 519                case IIO_MAGN:
 520                        *val = 0;
 521                        *val2 = 100; /* 0.0001 gauss */
 522                        return IIO_VAL_INT_PLUS_MICRO;
 523                case IIO_TEMP:
 524                        *val = 5;
 525                        *val2 = 650000; /* 5.65 milli degree Celsius */
 526                        return IIO_VAL_INT_PLUS_MICRO;
 527                case IIO_PRESSURE:
 528                        *val = 0;
 529                        *val2 = 4000; /* 40ubar = 0.004 kPa */
 530                        return IIO_VAL_INT_PLUS_MICRO;
 531                default:
 532                        return -EINVAL;
 533                }
 534        case IIO_CHAN_INFO_OFFSET:
 535                /* Only the temperature channel has a offset */
 536                *val = 4425; /* 25 degree Celsius = 0x0000 */
 537                return IIO_VAL_INT;
 538        case IIO_CHAN_INFO_CALIBBIAS:
 539                return adis16480_get_calibbias(indio_dev, chan, val);
 540        case IIO_CHAN_INFO_CALIBSCALE:
 541                return adis16480_get_calibscale(indio_dev, chan, val);
 542        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 543                return adis16480_get_filter_freq(indio_dev, chan, val);
 544        case IIO_CHAN_INFO_SAMP_FREQ:
 545                return adis16480_get_freq(indio_dev, val, val2);
 546        default:
 547                return -EINVAL;
 548        }
 549}
 550
 551static int adis16480_write_raw(struct iio_dev *indio_dev,
 552        const struct iio_chan_spec *chan, int val, int val2, long info)
 553{
 554        switch (info) {
 555        case IIO_CHAN_INFO_CALIBBIAS:
 556                return adis16480_set_calibbias(indio_dev, chan, val);
 557        case IIO_CHAN_INFO_CALIBSCALE:
 558                return adis16480_set_calibscale(indio_dev, chan, val);
 559        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 560                return adis16480_set_filter_freq(indio_dev, chan, val);
 561        case IIO_CHAN_INFO_SAMP_FREQ:
 562                return adis16480_set_freq(indio_dev, val, val2);
 563
 564        default:
 565                return -EINVAL;
 566        }
 567}
 568
 569#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info_sep, _bits) \
 570        { \
 571                .type = (_type), \
 572                .modified = 1, \
 573                .channel2 = (_mod), \
 574                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 575                        BIT(IIO_CHAN_INFO_CALIBBIAS) | \
 576                        _info_sep, \
 577                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 578                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 579                .address = (_address), \
 580                .scan_index = (_si), \
 581                .scan_type = { \
 582                        .sign = 's', \
 583                        .realbits = (_bits), \
 584                        .storagebits = (_bits), \
 585                        .endianness = IIO_BE, \
 586                }, \
 587        }
 588
 589#define ADIS16480_GYRO_CHANNEL(_mod) \
 590        ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
 591        ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \
 592        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
 593        BIT(IIO_CHAN_INFO_CALIBSCALE), \
 594        32)
 595
 596#define ADIS16480_ACCEL_CHANNEL(_mod) \
 597        ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \
 598        ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \
 599        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
 600        BIT(IIO_CHAN_INFO_CALIBSCALE), \
 601        32)
 602
 603#define ADIS16480_MAGN_CHANNEL(_mod) \
 604        ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \
 605        ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \
 606        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
 607        16)
 608
 609#define ADIS16480_PRESSURE_CHANNEL() \
 610        { \
 611                .type = IIO_PRESSURE, \
 612                .indexed = 1, \
 613                .channel = 0, \
 614                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 615                        BIT(IIO_CHAN_INFO_CALIBBIAS) | \
 616                        BIT(IIO_CHAN_INFO_SCALE), \
 617                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 618                .address = ADIS16480_REG_BAROM_OUT, \
 619                .scan_index = ADIS16480_SCAN_BARO, \
 620                .scan_type = { \
 621                        .sign = 's', \
 622                        .realbits = 32, \
 623                        .storagebits = 32, \
 624                        .endianness = IIO_BE, \
 625                }, \
 626        }
 627
 628#define ADIS16480_TEMP_CHANNEL() { \
 629                .type = IIO_TEMP, \
 630                .indexed = 1, \
 631                .channel = 0, \
 632                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 633                        BIT(IIO_CHAN_INFO_SCALE) | \
 634                        BIT(IIO_CHAN_INFO_OFFSET), \
 635                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 636                .address = ADIS16480_REG_TEMP_OUT, \
 637                .scan_index = ADIS16480_SCAN_TEMP, \
 638                .scan_type = { \
 639                        .sign = 's', \
 640                        .realbits = 16, \
 641                        .storagebits = 16, \
 642                        .endianness = IIO_BE, \
 643                }, \
 644        }
 645
 646static const struct iio_chan_spec adis16480_channels[] = {
 647        ADIS16480_GYRO_CHANNEL(X),
 648        ADIS16480_GYRO_CHANNEL(Y),
 649        ADIS16480_GYRO_CHANNEL(Z),
 650        ADIS16480_ACCEL_CHANNEL(X),
 651        ADIS16480_ACCEL_CHANNEL(Y),
 652        ADIS16480_ACCEL_CHANNEL(Z),
 653        ADIS16480_MAGN_CHANNEL(X),
 654        ADIS16480_MAGN_CHANNEL(Y),
 655        ADIS16480_MAGN_CHANNEL(Z),
 656        ADIS16480_PRESSURE_CHANNEL(),
 657        ADIS16480_TEMP_CHANNEL(),
 658        IIO_CHAN_SOFT_TIMESTAMP(11)
 659};
 660
 661static const struct iio_chan_spec adis16485_channels[] = {
 662        ADIS16480_GYRO_CHANNEL(X),
 663        ADIS16480_GYRO_CHANNEL(Y),
 664        ADIS16480_GYRO_CHANNEL(Z),
 665        ADIS16480_ACCEL_CHANNEL(X),
 666        ADIS16480_ACCEL_CHANNEL(Y),
 667        ADIS16480_ACCEL_CHANNEL(Z),
 668        ADIS16480_TEMP_CHANNEL(),
 669        IIO_CHAN_SOFT_TIMESTAMP(7)
 670};
 671
 672enum adis16480_variant {
 673        ADIS16375,
 674        ADIS16480,
 675        ADIS16485,
 676        ADIS16488,
 677};
 678
 679static const struct adis16480_chip_info adis16480_chip_info[] = {
 680        [ADIS16375] = {
 681                .channels = adis16485_channels,
 682                .num_channels = ARRAY_SIZE(adis16485_channels),
 683                /*
 684                 * storing the value in rad/degree and the scale in degree
 685                 * gives us the result in rad and better precession than
 686                 * storing the scale directly in rad.
 687                 */
 688                .gyro_max_val = IIO_RAD_TO_DEGREE(22887),
 689                .gyro_max_scale = 300,
 690                .accel_max_val = IIO_M_S_2_TO_G(21973),
 691                .accel_max_scale = 18,
 692        },
 693        [ADIS16480] = {
 694                .channels = adis16480_channels,
 695                .num_channels = ARRAY_SIZE(adis16480_channels),
 696                .gyro_max_val = IIO_RAD_TO_DEGREE(22500),
 697                .gyro_max_scale = 450,
 698                .accel_max_val = IIO_M_S_2_TO_G(12500),
 699                .accel_max_scale = 5,
 700        },
 701        [ADIS16485] = {
 702                .channels = adis16485_channels,
 703                .num_channels = ARRAY_SIZE(adis16485_channels),
 704                .gyro_max_val = IIO_RAD_TO_DEGREE(22500),
 705                .gyro_max_scale = 450,
 706                .accel_max_val = IIO_M_S_2_TO_G(20000),
 707                .accel_max_scale = 5,
 708        },
 709        [ADIS16488] = {
 710                .channels = adis16480_channels,
 711                .num_channels = ARRAY_SIZE(adis16480_channels),
 712                .gyro_max_val = IIO_RAD_TO_DEGREE(22500),
 713                .gyro_max_scale = 450,
 714                .accel_max_val = IIO_M_S_2_TO_G(22500),
 715                .accel_max_scale = 18,
 716        },
 717};
 718
 719static const struct iio_info adis16480_info = {
 720        .read_raw = &adis16480_read_raw,
 721        .write_raw = &adis16480_write_raw,
 722        .update_scan_mode = adis_update_scan_mode,
 723        .driver_module = THIS_MODULE,
 724};
 725
 726static int adis16480_stop_device(struct iio_dev *indio_dev)
 727{
 728        struct adis16480 *st = iio_priv(indio_dev);
 729        int ret;
 730
 731        ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9));
 732        if (ret)
 733                dev_err(&indio_dev->dev,
 734                        "Could not power down device: %d\n", ret);
 735
 736        return ret;
 737}
 738
 739static int adis16480_enable_irq(struct adis *adis, bool enable)
 740{
 741        return adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL,
 742                enable ? BIT(3) : 0);
 743}
 744
 745static int adis16480_initial_setup(struct iio_dev *indio_dev)
 746{
 747        struct adis16480 *st = iio_priv(indio_dev);
 748        uint16_t prod_id;
 749        unsigned int device_id;
 750        int ret;
 751
 752        adis_reset(&st->adis);
 753        msleep(70);
 754
 755        ret = adis_write_reg_16(&st->adis, ADIS16480_REG_GLOB_CMD, BIT(1));
 756        if (ret)
 757                return ret;
 758        msleep(30);
 759
 760        ret = adis_check_status(&st->adis);
 761        if (ret)
 762                return ret;
 763
 764        ret = adis_read_reg_16(&st->adis, ADIS16480_REG_PROD_ID, &prod_id);
 765        if (ret)
 766                return ret;
 767
 768        ret = sscanf(indio_dev->name, "adis%u\n", &device_id);
 769        if (ret != 1)
 770                return -EINVAL;
 771
 772        if (prod_id != device_id)
 773                dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
 774                                device_id, prod_id);
 775
 776        return 0;
 777}
 778
 779#define ADIS16480_DIAG_STAT_XGYRO_FAIL 0
 780#define ADIS16480_DIAG_STAT_YGYRO_FAIL 1
 781#define ADIS16480_DIAG_STAT_ZGYRO_FAIL 2
 782#define ADIS16480_DIAG_STAT_XACCL_FAIL 3
 783#define ADIS16480_DIAG_STAT_YACCL_FAIL 4
 784#define ADIS16480_DIAG_STAT_ZACCL_FAIL 5
 785#define ADIS16480_DIAG_STAT_XMAGN_FAIL 8
 786#define ADIS16480_DIAG_STAT_YMAGN_FAIL 9
 787#define ADIS16480_DIAG_STAT_ZMAGN_FAIL 10
 788#define ADIS16480_DIAG_STAT_BARO_FAIL 11
 789
 790static const char * const adis16480_status_error_msgs[] = {
 791        [ADIS16480_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
 792        [ADIS16480_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
 793        [ADIS16480_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
 794        [ADIS16480_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
 795        [ADIS16480_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
 796        [ADIS16480_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
 797        [ADIS16480_DIAG_STAT_XMAGN_FAIL] = "X-axis magnetometer self-test failure",
 798        [ADIS16480_DIAG_STAT_YMAGN_FAIL] = "Y-axis magnetometer self-test failure",
 799        [ADIS16480_DIAG_STAT_ZMAGN_FAIL] = "Z-axis magnetometer self-test failure",
 800        [ADIS16480_DIAG_STAT_BARO_FAIL] = "Barometer self-test failure",
 801};
 802
 803static const struct adis_data adis16480_data = {
 804        .diag_stat_reg = ADIS16480_REG_DIAG_STS,
 805        .glob_cmd_reg = ADIS16480_REG_GLOB_CMD,
 806        .has_paging = true,
 807
 808        .read_delay = 5,
 809        .write_delay = 5,
 810
 811        .status_error_msgs = adis16480_status_error_msgs,
 812        .status_error_mask = BIT(ADIS16480_DIAG_STAT_XGYRO_FAIL) |
 813                BIT(ADIS16480_DIAG_STAT_YGYRO_FAIL) |
 814                BIT(ADIS16480_DIAG_STAT_ZGYRO_FAIL) |
 815                BIT(ADIS16480_DIAG_STAT_XACCL_FAIL) |
 816                BIT(ADIS16480_DIAG_STAT_YACCL_FAIL) |
 817                BIT(ADIS16480_DIAG_STAT_ZACCL_FAIL) |
 818                BIT(ADIS16480_DIAG_STAT_XMAGN_FAIL) |
 819                BIT(ADIS16480_DIAG_STAT_YMAGN_FAIL) |
 820                BIT(ADIS16480_DIAG_STAT_ZMAGN_FAIL) |
 821                BIT(ADIS16480_DIAG_STAT_BARO_FAIL),
 822
 823        .enable_irq = adis16480_enable_irq,
 824};
 825
 826static int adis16480_probe(struct spi_device *spi)
 827{
 828        const struct spi_device_id *id = spi_get_device_id(spi);
 829        struct iio_dev *indio_dev;
 830        struct adis16480 *st;
 831        int ret;
 832
 833        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 834        if (indio_dev == NULL)
 835                return -ENOMEM;
 836
 837        spi_set_drvdata(spi, indio_dev);
 838
 839        st = iio_priv(indio_dev);
 840
 841        st->chip_info = &adis16480_chip_info[id->driver_data];
 842        indio_dev->dev.parent = &spi->dev;
 843        indio_dev->name = spi_get_device_id(spi)->name;
 844        indio_dev->channels = st->chip_info->channels;
 845        indio_dev->num_channels = st->chip_info->num_channels;
 846        indio_dev->info = &adis16480_info;
 847        indio_dev->modes = INDIO_DIRECT_MODE;
 848
 849        ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
 850        if (ret)
 851                return ret;
 852
 853        ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
 854        if (ret)
 855                return ret;
 856
 857        ret = adis16480_initial_setup(indio_dev);
 858        if (ret)
 859                goto error_cleanup_buffer;
 860
 861        ret = iio_device_register(indio_dev);
 862        if (ret)
 863                goto error_stop_device;
 864
 865        adis16480_debugfs_init(indio_dev);
 866
 867        return 0;
 868
 869error_stop_device:
 870        adis16480_stop_device(indio_dev);
 871error_cleanup_buffer:
 872        adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 873        return ret;
 874}
 875
 876static int adis16480_remove(struct spi_device *spi)
 877{
 878        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 879        struct adis16480 *st = iio_priv(indio_dev);
 880
 881        iio_device_unregister(indio_dev);
 882        adis16480_stop_device(indio_dev);
 883
 884        adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 885
 886        return 0;
 887}
 888
 889static const struct spi_device_id adis16480_ids[] = {
 890        { "adis16375", ADIS16375 },
 891        { "adis16480", ADIS16480 },
 892        { "adis16485", ADIS16485 },
 893        { "adis16488", ADIS16488 },
 894        { }
 895};
 896MODULE_DEVICE_TABLE(spi, adis16480_ids);
 897
 898static struct spi_driver adis16480_driver = {
 899        .driver = {
 900                .name = "adis16480",
 901        },
 902        .id_table = adis16480_ids,
 903        .probe = adis16480_probe,
 904        .remove = adis16480_remove,
 905};
 906module_spi_driver(adis16480_driver);
 907
 908MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 909MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver");
 910MODULE_LICENSE("GPL v2");
 911