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