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_DEBUGFS_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_DEBUGFS_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_DEBUGFS_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_unsafe("firmware_revision", 0400,
 241                indio_dev->debugfs_dentry, adis16480,
 242                &adis16480_firmware_revision_fops);
 243        debugfs_create_file_unsafe("firmware_date", 0400,
 244                indio_dev->debugfs_dentry, adis16480,
 245                &adis16480_firmware_date_fops);
 246        debugfs_create_file_unsafe("serial_number", 0400,
 247                indio_dev->debugfs_dentry, adis16480,
 248                &adis16480_serial_number_fops);
 249        debugfs_create_file_unsafe("product_id", 0400,
 250                indio_dev->debugfs_dentry, adis16480,
 251                &adis16480_product_id_fops);
 252        debugfs_create_file_unsafe("flash_count", 0400,
 253                indio_dev->debugfs_dentry, adis16480,
 254                &adis16480_flash_count_fops);
 255
 256        return 0;
 257}
 258
 259#else
 260
 261static int adis16480_debugfs_init(struct iio_dev *indio_dev)
 262{
 263        return 0;
 264}
 265
 266#endif
 267
 268static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2)
 269{
 270        struct adis16480 *st = iio_priv(indio_dev);
 271        unsigned int t;
 272
 273        t =  val * 1000 + val2 / 1000;
 274        if (t <= 0)
 275                return -EINVAL;
 276
 277        t = 2460000 / t;
 278        if (t > 2048)
 279                t = 2048;
 280
 281        if (t != 0)
 282                t--;
 283
 284        return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t);
 285}
 286
 287static int adis16480_get_freq(struct iio_dev *indio_dev, int *val, int *val2)
 288{
 289        struct adis16480 *st = iio_priv(indio_dev);
 290        uint16_t t;
 291        int ret;
 292        unsigned freq;
 293
 294        ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t);
 295        if (ret < 0)
 296                return ret;
 297
 298        freq = 2460000 / (t + 1);
 299        *val = freq / 1000;
 300        *val2 = (freq % 1000) * 1000;
 301
 302        return IIO_VAL_INT_PLUS_MICRO;
 303}
 304
 305enum {
 306        ADIS16480_SCAN_GYRO_X,
 307        ADIS16480_SCAN_GYRO_Y,
 308        ADIS16480_SCAN_GYRO_Z,
 309        ADIS16480_SCAN_ACCEL_X,
 310        ADIS16480_SCAN_ACCEL_Y,
 311        ADIS16480_SCAN_ACCEL_Z,
 312        ADIS16480_SCAN_MAGN_X,
 313        ADIS16480_SCAN_MAGN_Y,
 314        ADIS16480_SCAN_MAGN_Z,
 315        ADIS16480_SCAN_BARO,
 316        ADIS16480_SCAN_TEMP,
 317};
 318
 319static const unsigned int adis16480_calibbias_regs[] = {
 320        [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_BIAS,
 321        [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_BIAS,
 322        [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_BIAS,
 323        [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_BIAS,
 324        [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_BIAS,
 325        [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_BIAS,
 326        [ADIS16480_SCAN_MAGN_X] = ADIS16480_REG_X_HARD_IRON,
 327        [ADIS16480_SCAN_MAGN_Y] = ADIS16480_REG_Y_HARD_IRON,
 328        [ADIS16480_SCAN_MAGN_Z] = ADIS16480_REG_Z_HARD_IRON,
 329        [ADIS16480_SCAN_BARO] = ADIS16480_REG_BAROM_BIAS,
 330};
 331
 332static const unsigned int adis16480_calibscale_regs[] = {
 333        [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_SCALE,
 334        [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_SCALE,
 335        [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_SCALE,
 336        [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_SCALE,
 337        [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_SCALE,
 338        [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_SCALE,
 339};
 340
 341static int adis16480_set_calibbias(struct iio_dev *indio_dev,
 342        const struct iio_chan_spec *chan, int bias)
 343{
 344        unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
 345        struct adis16480 *st = iio_priv(indio_dev);
 346
 347        switch (chan->type) {
 348        case IIO_MAGN:
 349        case IIO_PRESSURE:
 350                if (bias < -0x8000 || bias >= 0x8000)
 351                        return -EINVAL;
 352                return adis_write_reg_16(&st->adis, reg, bias);
 353        case IIO_ANGL_VEL:
 354        case IIO_ACCEL:
 355                return adis_write_reg_32(&st->adis, reg, bias);
 356        default:
 357                break;
 358        }
 359
 360        return -EINVAL;
 361}
 362
 363static int adis16480_get_calibbias(struct iio_dev *indio_dev,
 364        const struct iio_chan_spec *chan, int *bias)
 365{
 366        unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
 367        struct adis16480 *st = iio_priv(indio_dev);
 368        uint16_t val16;
 369        uint32_t val32;
 370        int ret;
 371
 372        switch (chan->type) {
 373        case IIO_MAGN:
 374        case IIO_PRESSURE:
 375                ret = adis_read_reg_16(&st->adis, reg, &val16);
 376                *bias = sign_extend32(val16, 15);
 377                break;
 378        case IIO_ANGL_VEL:
 379        case IIO_ACCEL:
 380                ret = adis_read_reg_32(&st->adis, reg, &val32);
 381                *bias = sign_extend32(val32, 31);
 382                break;
 383        default:
 384                        ret = -EINVAL;
 385        }
 386
 387        if (ret < 0)
 388                return ret;
 389
 390        return IIO_VAL_INT;
 391}
 392
 393static int adis16480_set_calibscale(struct iio_dev *indio_dev,
 394        const struct iio_chan_spec *chan, int scale)
 395{
 396        unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
 397        struct adis16480 *st = iio_priv(indio_dev);
 398
 399        if (scale < -0x8000 || scale >= 0x8000)
 400                return -EINVAL;
 401
 402        return adis_write_reg_16(&st->adis, reg, scale);
 403}
 404
 405static int adis16480_get_calibscale(struct iio_dev *indio_dev,
 406        const struct iio_chan_spec *chan, int *scale)
 407{
 408        unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
 409        struct adis16480 *st = iio_priv(indio_dev);
 410        uint16_t val16;
 411        int ret;
 412
 413        ret = adis_read_reg_16(&st->adis, reg, &val16);
 414        if (ret < 0)
 415                return ret;
 416
 417        *scale = sign_extend32(val16, 15);
 418        return IIO_VAL_INT;
 419}
 420
 421static const unsigned int adis16480_def_filter_freqs[] = {
 422        310,
 423        55,
 424        275,
 425        63,
 426};
 427
 428static const unsigned int ad16480_filter_data[][2] = {
 429        [ADIS16480_SCAN_GYRO_X]         = { ADIS16480_REG_FILTER_BNK0, 0 },
 430        [ADIS16480_SCAN_GYRO_Y]         = { ADIS16480_REG_FILTER_BNK0, 3 },
 431        [ADIS16480_SCAN_GYRO_Z]         = { ADIS16480_REG_FILTER_BNK0, 6 },
 432        [ADIS16480_SCAN_ACCEL_X]        = { ADIS16480_REG_FILTER_BNK0, 9 },
 433        [ADIS16480_SCAN_ACCEL_Y]        = { ADIS16480_REG_FILTER_BNK0, 12 },
 434        [ADIS16480_SCAN_ACCEL_Z]        = { ADIS16480_REG_FILTER_BNK1, 0 },
 435        [ADIS16480_SCAN_MAGN_X]         = { ADIS16480_REG_FILTER_BNK1, 3 },
 436        [ADIS16480_SCAN_MAGN_Y]         = { ADIS16480_REG_FILTER_BNK1, 6 },
 437        [ADIS16480_SCAN_MAGN_Z]         = { ADIS16480_REG_FILTER_BNK1, 9 },
 438};
 439
 440static int adis16480_get_filter_freq(struct iio_dev *indio_dev,
 441        const struct iio_chan_spec *chan, int *freq)
 442{
 443        struct adis16480 *st = iio_priv(indio_dev);
 444        unsigned int enable_mask, offset, reg;
 445        uint16_t val;
 446        int ret;
 447
 448        reg = ad16480_filter_data[chan->scan_index][0];
 449        offset = ad16480_filter_data[chan->scan_index][1];
 450        enable_mask = BIT(offset + 2);
 451
 452        ret = adis_read_reg_16(&st->adis, reg, &val);
 453        if (ret < 0)
 454                return ret;
 455
 456        if (!(val & enable_mask))
 457                *freq = 0;
 458        else
 459                *freq = adis16480_def_filter_freqs[(val >> offset) & 0x3];
 460
 461        return IIO_VAL_INT;
 462}
 463
 464static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
 465        const struct iio_chan_spec *chan, unsigned int freq)
 466{
 467        struct adis16480 *st = iio_priv(indio_dev);
 468        unsigned int enable_mask, offset, reg;
 469        unsigned int diff, best_diff;
 470        unsigned int i, best_freq;
 471        uint16_t val;
 472        int ret;
 473
 474        reg = ad16480_filter_data[chan->scan_index][0];
 475        offset = ad16480_filter_data[chan->scan_index][1];
 476        enable_mask = BIT(offset + 2);
 477
 478        ret = adis_read_reg_16(&st->adis, reg, &val);
 479        if (ret < 0)
 480                return ret;
 481
 482        if (freq == 0) {
 483                val &= ~enable_mask;
 484        } else {
 485                best_freq = 0;
 486                best_diff = 310;
 487                for (i = 0; i < ARRAY_SIZE(adis16480_def_filter_freqs); i++) {
 488                        if (adis16480_def_filter_freqs[i] >= freq) {
 489                                diff = adis16480_def_filter_freqs[i] - freq;
 490                                if (diff < best_diff) {
 491                                        best_diff = diff;
 492                                        best_freq = i;
 493                                }
 494                        }
 495                }
 496
 497                val &= ~(0x3 << offset);
 498                val |= best_freq << offset;
 499                val |= enable_mask;
 500        }
 501
 502        return adis_write_reg_16(&st->adis, reg, val);
 503}
 504
 505static int adis16480_read_raw(struct iio_dev *indio_dev,
 506        const struct iio_chan_spec *chan, int *val, int *val2, long info)
 507{
 508        struct adis16480 *st = iio_priv(indio_dev);
 509
 510        switch (info) {
 511        case IIO_CHAN_INFO_RAW:
 512                return adis_single_conversion(indio_dev, chan, 0, val);
 513        case IIO_CHAN_INFO_SCALE:
 514                switch (chan->type) {
 515                case IIO_ANGL_VEL:
 516                        *val = st->chip_info->gyro_max_scale;
 517                        *val2 = st->chip_info->gyro_max_val;
 518                        return IIO_VAL_FRACTIONAL;
 519                case IIO_ACCEL:
 520                        *val = st->chip_info->accel_max_scale;
 521                        *val2 = st->chip_info->accel_max_val;
 522                        return IIO_VAL_FRACTIONAL;
 523                case IIO_MAGN:
 524                        *val = 0;
 525                        *val2 = 100; /* 0.0001 gauss */
 526                        return IIO_VAL_INT_PLUS_MICRO;
 527                case IIO_TEMP:
 528                        *val = 5;
 529                        *val2 = 650000; /* 5.65 milli degree Celsius */
 530                        return IIO_VAL_INT_PLUS_MICRO;
 531                case IIO_PRESSURE:
 532                        *val = 0;
 533                        *val2 = 4000; /* 40ubar = 0.004 kPa */
 534                        return IIO_VAL_INT_PLUS_MICRO;
 535                default:
 536                        return -EINVAL;
 537                }
 538        case IIO_CHAN_INFO_OFFSET:
 539                /* Only the temperature channel has a offset */
 540                *val = 4425; /* 25 degree Celsius = 0x0000 */
 541                return IIO_VAL_INT;
 542        case IIO_CHAN_INFO_CALIBBIAS:
 543                return adis16480_get_calibbias(indio_dev, chan, val);
 544        case IIO_CHAN_INFO_CALIBSCALE:
 545                return adis16480_get_calibscale(indio_dev, chan, val);
 546        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 547                return adis16480_get_filter_freq(indio_dev, chan, val);
 548        case IIO_CHAN_INFO_SAMP_FREQ:
 549                return adis16480_get_freq(indio_dev, val, val2);
 550        default:
 551                return -EINVAL;
 552        }
 553}
 554
 555static int adis16480_write_raw(struct iio_dev *indio_dev,
 556        const struct iio_chan_spec *chan, int val, int val2, long info)
 557{
 558        switch (info) {
 559        case IIO_CHAN_INFO_CALIBBIAS:
 560                return adis16480_set_calibbias(indio_dev, chan, val);
 561        case IIO_CHAN_INFO_CALIBSCALE:
 562                return adis16480_set_calibscale(indio_dev, chan, val);
 563        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 564                return adis16480_set_filter_freq(indio_dev, chan, val);
 565        case IIO_CHAN_INFO_SAMP_FREQ:
 566                return adis16480_set_freq(indio_dev, val, val2);
 567
 568        default:
 569                return -EINVAL;
 570        }
 571}
 572
 573#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info_sep, _bits) \
 574        { \
 575                .type = (_type), \
 576                .modified = 1, \
 577                .channel2 = (_mod), \
 578                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 579                        BIT(IIO_CHAN_INFO_CALIBBIAS) | \
 580                        _info_sep, \
 581                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 582                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 583                .address = (_address), \
 584                .scan_index = (_si), \
 585                .scan_type = { \
 586                        .sign = 's', \
 587                        .realbits = (_bits), \
 588                        .storagebits = (_bits), \
 589                        .endianness = IIO_BE, \
 590                }, \
 591        }
 592
 593#define ADIS16480_GYRO_CHANNEL(_mod) \
 594        ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
 595        ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \
 596        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
 597        BIT(IIO_CHAN_INFO_CALIBSCALE), \
 598        32)
 599
 600#define ADIS16480_ACCEL_CHANNEL(_mod) \
 601        ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \
 602        ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \
 603        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
 604        BIT(IIO_CHAN_INFO_CALIBSCALE), \
 605        32)
 606
 607#define ADIS16480_MAGN_CHANNEL(_mod) \
 608        ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \
 609        ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \
 610        BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
 611        16)
 612
 613#define ADIS16480_PRESSURE_CHANNEL() \
 614        { \
 615                .type = IIO_PRESSURE, \
 616                .indexed = 1, \
 617                .channel = 0, \
 618                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 619                        BIT(IIO_CHAN_INFO_CALIBBIAS) | \
 620                        BIT(IIO_CHAN_INFO_SCALE), \
 621                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 622                .address = ADIS16480_REG_BAROM_OUT, \
 623                .scan_index = ADIS16480_SCAN_BARO, \
 624                .scan_type = { \
 625                        .sign = 's', \
 626                        .realbits = 32, \
 627                        .storagebits = 32, \
 628                        .endianness = IIO_BE, \
 629                }, \
 630        }
 631
 632#define ADIS16480_TEMP_CHANNEL() { \
 633                .type = IIO_TEMP, \
 634                .indexed = 1, \
 635                .channel = 0, \
 636                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 637                        BIT(IIO_CHAN_INFO_SCALE) | \
 638                        BIT(IIO_CHAN_INFO_OFFSET), \
 639                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 640                .address = ADIS16480_REG_TEMP_OUT, \
 641                .scan_index = ADIS16480_SCAN_TEMP, \
 642                .scan_type = { \
 643                        .sign = 's', \
 644                        .realbits = 16, \
 645                        .storagebits = 16, \
 646                        .endianness = IIO_BE, \
 647                }, \
 648        }
 649
 650static const struct iio_chan_spec adis16480_channels[] = {
 651        ADIS16480_GYRO_CHANNEL(X),
 652        ADIS16480_GYRO_CHANNEL(Y),
 653        ADIS16480_GYRO_CHANNEL(Z),
 654        ADIS16480_ACCEL_CHANNEL(X),
 655        ADIS16480_ACCEL_CHANNEL(Y),
 656        ADIS16480_ACCEL_CHANNEL(Z),
 657        ADIS16480_MAGN_CHANNEL(X),
 658        ADIS16480_MAGN_CHANNEL(Y),
 659        ADIS16480_MAGN_CHANNEL(Z),
 660        ADIS16480_PRESSURE_CHANNEL(),
 661        ADIS16480_TEMP_CHANNEL(),
 662        IIO_CHAN_SOFT_TIMESTAMP(11)
 663};
 664
 665static const struct iio_chan_spec adis16485_channels[] = {
 666        ADIS16480_GYRO_CHANNEL(X),
 667        ADIS16480_GYRO_CHANNEL(Y),
 668        ADIS16480_GYRO_CHANNEL(Z),
 669        ADIS16480_ACCEL_CHANNEL(X),
 670        ADIS16480_ACCEL_CHANNEL(Y),
 671        ADIS16480_ACCEL_CHANNEL(Z),
 672        ADIS16480_TEMP_CHANNEL(),
 673        IIO_CHAN_SOFT_TIMESTAMP(7)
 674};
 675
 676enum adis16480_variant {
 677        ADIS16375,
 678        ADIS16480,
 679        ADIS16485,
 680        ADIS16488,
 681};
 682
 683static const struct adis16480_chip_info adis16480_chip_info[] = {
 684        [ADIS16375] = {
 685                .channels = adis16485_channels,
 686                .num_channels = ARRAY_SIZE(adis16485_channels),
 687                /*
 688                 * storing the value in rad/degree and the scale in degree
 689                 * gives us the result in rad and better precession than
 690                 * storing the scale directly in rad.
 691                 */
 692                .gyro_max_val = IIO_RAD_TO_DEGREE(22887),
 693                .gyro_max_scale = 300,
 694                .accel_max_val = IIO_M_S_2_TO_G(21973),
 695                .accel_max_scale = 18,
 696        },
 697        [ADIS16480] = {
 698                .channels = adis16480_channels,
 699                .num_channels = ARRAY_SIZE(adis16480_channels),
 700                .gyro_max_val = IIO_RAD_TO_DEGREE(22500),
 701                .gyro_max_scale = 450,
 702                .accel_max_val = IIO_M_S_2_TO_G(12500),
 703                .accel_max_scale = 10,
 704        },
 705        [ADIS16485] = {
 706                .channels = adis16485_channels,
 707                .num_channels = ARRAY_SIZE(adis16485_channels),
 708                .gyro_max_val = IIO_RAD_TO_DEGREE(22500),
 709                .gyro_max_scale = 450,
 710                .accel_max_val = IIO_M_S_2_TO_G(20000),
 711                .accel_max_scale = 5,
 712        },
 713        [ADIS16488] = {
 714                .channels = adis16480_channels,
 715                .num_channels = ARRAY_SIZE(adis16480_channels),
 716                .gyro_max_val = IIO_RAD_TO_DEGREE(22500),
 717                .gyro_max_scale = 450,
 718                .accel_max_val = IIO_M_S_2_TO_G(22500),
 719                .accel_max_scale = 18,
 720        },
 721};
 722
 723static const struct iio_info adis16480_info = {
 724        .read_raw = &adis16480_read_raw,
 725        .write_raw = &adis16480_write_raw,
 726        .update_scan_mode = adis_update_scan_mode,
 727};
 728
 729static int adis16480_stop_device(struct iio_dev *indio_dev)
 730{
 731        struct adis16480 *st = iio_priv(indio_dev);
 732        int ret;
 733
 734        ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9));
 735        if (ret)
 736                dev_err(&indio_dev->dev,
 737                        "Could not power down device: %d\n", ret);
 738
 739        return ret;
 740}
 741
 742static int adis16480_enable_irq(struct adis *adis, bool enable)
 743{
 744        return adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL,
 745                enable ? BIT(3) : 0);
 746}
 747
 748static int adis16480_initial_setup(struct iio_dev *indio_dev)
 749{
 750        struct adis16480 *st = iio_priv(indio_dev);
 751        uint16_t prod_id;
 752        unsigned int device_id;
 753        int ret;
 754
 755        adis_reset(&st->adis);
 756        msleep(70);
 757
 758        ret = adis_write_reg_16(&st->adis, ADIS16480_REG_GLOB_CMD, BIT(1));
 759        if (ret)
 760                return ret;
 761        msleep(30);
 762
 763        ret = adis_check_status(&st->adis);
 764        if (ret)
 765                return ret;
 766
 767        ret = adis_read_reg_16(&st->adis, ADIS16480_REG_PROD_ID, &prod_id);
 768        if (ret)
 769                return ret;
 770
 771        ret = sscanf(indio_dev->name, "adis%u\n", &device_id);
 772        if (ret != 1)
 773                return -EINVAL;
 774
 775        if (prod_id != device_id)
 776                dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
 777                                device_id, prod_id);
 778
 779        return 0;
 780}
 781
 782#define ADIS16480_DIAG_STAT_XGYRO_FAIL 0
 783#define ADIS16480_DIAG_STAT_YGYRO_FAIL 1
 784#define ADIS16480_DIAG_STAT_ZGYRO_FAIL 2
 785#define ADIS16480_DIAG_STAT_XACCL_FAIL 3
 786#define ADIS16480_DIAG_STAT_YACCL_FAIL 4
 787#define ADIS16480_DIAG_STAT_ZACCL_FAIL 5
 788#define ADIS16480_DIAG_STAT_XMAGN_FAIL 8
 789#define ADIS16480_DIAG_STAT_YMAGN_FAIL 9
 790#define ADIS16480_DIAG_STAT_ZMAGN_FAIL 10
 791#define ADIS16480_DIAG_STAT_BARO_FAIL 11
 792
 793static const char * const adis16480_status_error_msgs[] = {
 794        [ADIS16480_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
 795        [ADIS16480_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
 796        [ADIS16480_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
 797        [ADIS16480_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
 798        [ADIS16480_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
 799        [ADIS16480_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
 800        [ADIS16480_DIAG_STAT_XMAGN_FAIL] = "X-axis magnetometer self-test failure",
 801        [ADIS16480_DIAG_STAT_YMAGN_FAIL] = "Y-axis magnetometer self-test failure",
 802        [ADIS16480_DIAG_STAT_ZMAGN_FAIL] = "Z-axis magnetometer self-test failure",
 803        [ADIS16480_DIAG_STAT_BARO_FAIL] = "Barometer self-test failure",
 804};
 805
 806static const struct adis_data adis16480_data = {
 807        .diag_stat_reg = ADIS16480_REG_DIAG_STS,
 808        .glob_cmd_reg = ADIS16480_REG_GLOB_CMD,
 809        .has_paging = true,
 810
 811        .read_delay = 5,
 812        .write_delay = 5,
 813
 814        .status_error_msgs = adis16480_status_error_msgs,
 815        .status_error_mask = BIT(ADIS16480_DIAG_STAT_XGYRO_FAIL) |
 816                BIT(ADIS16480_DIAG_STAT_YGYRO_FAIL) |
 817                BIT(ADIS16480_DIAG_STAT_ZGYRO_FAIL) |
 818                BIT(ADIS16480_DIAG_STAT_XACCL_FAIL) |
 819                BIT(ADIS16480_DIAG_STAT_YACCL_FAIL) |
 820                BIT(ADIS16480_DIAG_STAT_ZACCL_FAIL) |
 821                BIT(ADIS16480_DIAG_STAT_XMAGN_FAIL) |
 822                BIT(ADIS16480_DIAG_STAT_YMAGN_FAIL) |
 823                BIT(ADIS16480_DIAG_STAT_ZMAGN_FAIL) |
 824                BIT(ADIS16480_DIAG_STAT_BARO_FAIL),
 825
 826        .enable_irq = adis16480_enable_irq,
 827};
 828
 829static int adis16480_probe(struct spi_device *spi)
 830{
 831        const struct spi_device_id *id = spi_get_device_id(spi);
 832        struct iio_dev *indio_dev;
 833        struct adis16480 *st;
 834        int ret;
 835
 836        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 837        if (indio_dev == NULL)
 838                return -ENOMEM;
 839
 840        spi_set_drvdata(spi, indio_dev);
 841
 842        st = iio_priv(indio_dev);
 843
 844        st->chip_info = &adis16480_chip_info[id->driver_data];
 845        indio_dev->dev.parent = &spi->dev;
 846        indio_dev->name = spi_get_device_id(spi)->name;
 847        indio_dev->channels = st->chip_info->channels;
 848        indio_dev->num_channels = st->chip_info->num_channels;
 849        indio_dev->info = &adis16480_info;
 850        indio_dev->modes = INDIO_DIRECT_MODE;
 851
 852        ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
 853        if (ret)
 854                return ret;
 855
 856        ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
 857        if (ret)
 858                return ret;
 859
 860        ret = adis16480_initial_setup(indio_dev);
 861        if (ret)
 862                goto error_cleanup_buffer;
 863
 864        ret = iio_device_register(indio_dev);
 865        if (ret)
 866                goto error_stop_device;
 867
 868        adis16480_debugfs_init(indio_dev);
 869
 870        return 0;
 871
 872error_stop_device:
 873        adis16480_stop_device(indio_dev);
 874error_cleanup_buffer:
 875        adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 876        return ret;
 877}
 878
 879static int adis16480_remove(struct spi_device *spi)
 880{
 881        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 882        struct adis16480 *st = iio_priv(indio_dev);
 883
 884        iio_device_unregister(indio_dev);
 885        adis16480_stop_device(indio_dev);
 886
 887        adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 888
 889        return 0;
 890}
 891
 892static const struct spi_device_id adis16480_ids[] = {
 893        { "adis16375", ADIS16375 },
 894        { "adis16480", ADIS16480 },
 895        { "adis16485", ADIS16485 },
 896        { "adis16488", ADIS16488 },
 897        { }
 898};
 899MODULE_DEVICE_TABLE(spi, adis16480_ids);
 900
 901static struct spi_driver adis16480_driver = {
 902        .driver = {
 903                .name = "adis16480",
 904        },
 905        .id_table = adis16480_ids,
 906        .probe = adis16480_probe,
 907        .remove = adis16480_remove,
 908};
 909module_spi_driver(adis16480_driver);
 910
 911MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 912MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver");
 913MODULE_LICENSE("GPL v2");
 914