root/drivers/iio/gyro/adis16136.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. adis16136_show_serial
  2. adis16136_show_product_id
  3. adis16136_show_flash_count
  4. adis16136_debugfs_init
  5. adis16136_debugfs_init
  6. adis16136_set_freq
  7. adis16136_get_freq
  8. adis16136_write_frequency
  9. adis16136_read_frequency
  10. adis16136_set_filter
  11. adis16136_get_filter
  12. adis16136_read_raw
  13. adis16136_write_raw
  14. adis16136_stop_device
  15. adis16136_initial_setup
  16. adis16136_probe
  17. adis16136_remove

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

/* [<][>][^][v][top][bottom][index][help] */