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