^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ADIS16460 IMU driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2019 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/iio/imu/adis.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define ADIS16460_REG_FLASH_CNT 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define ADIS16460_REG_DIAG_STAT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define ADIS16460_REG_X_GYRO_LOW 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define ADIS16460_REG_X_GYRO_OUT 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define ADIS16460_REG_Y_GYRO_LOW 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define ADIS16460_REG_Y_GYRO_OUT 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define ADIS16460_REG_Z_GYRO_LOW 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ADIS16460_REG_Z_GYRO_OUT 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ADIS16460_REG_X_ACCL_LOW 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ADIS16460_REG_X_ACCL_OUT 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ADIS16460_REG_Y_ACCL_LOW 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ADIS16460_REG_Y_ACCL_OUT 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ADIS16460_REG_Z_ACCL_LOW 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ADIS16460_REG_Z_ACCL_OUT 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ADIS16460_REG_SMPL_CNTR 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ADIS16460_REG_TEMP_OUT 0x1E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ADIS16460_REG_X_DELT_ANG 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ADIS16460_REG_Y_DELT_ANG 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ADIS16460_REG_Z_DELT_ANG 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ADIS16460_REG_X_DELT_VEL 0x2A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ADIS16460_REG_Y_DELT_VEL 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ADIS16460_REG_Z_DELT_VEL 0x2E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ADIS16460_REG_MSC_CTRL 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ADIS16460_REG_SYNC_SCAL 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ADIS16460_REG_DEC_RATE 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ADIS16460_REG_FLTR_CTRL 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ADIS16460_REG_GLOB_CMD 0x3E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ADIS16460_REG_X_GYRO_OFF 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ADIS16460_REG_Y_GYRO_OFF 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ADIS16460_REG_Z_GYRO_OFF 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ADIS16460_REG_X_ACCL_OFF 0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ADIS16460_REG_Y_ACCL_OFF 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ADIS16460_REG_Z_ACCL_OFF 0x4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ADIS16460_REG_LOT_ID1 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ADIS16460_REG_LOT_ID2 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ADIS16460_REG_PROD_ID 0x56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ADIS16460_REG_SERIAL_NUM 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define ADIS16460_REG_CAL_SGNTR 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ADIS16460_REG_CAL_CRC 0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ADIS16460_REG_CODE_SGNTR 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ADIS16460_REG_CODE_CRC 0x66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct adis16460_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const struct iio_chan_spec *channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int gyro_max_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int gyro_max_scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int accel_max_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int accel_max_scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct adis16460 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) const struct adis16460_chip_info *chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct adis adis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int adis16460_show_serial_number(void *arg, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct adis16460 *adis16460 = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u16 serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ret = adis_read_reg_16(&adis16460->adis, ADIS16460_REG_SERIAL_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) &serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *val = serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) DEFINE_DEBUGFS_ATTRIBUTE(adis16460_serial_number_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) adis16460_show_serial_number, NULL, "0x%.4llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int adis16460_show_product_id(void *arg, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct adis16460 *adis16460 = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u16 prod_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = adis_read_reg_16(&adis16460->adis, ADIS16460_REG_PROD_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) &prod_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *val = prod_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) DEFINE_DEBUGFS_ATTRIBUTE(adis16460_product_id_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) adis16460_show_product_id, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int adis16460_show_flash_count(void *arg, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct adis16460 *adis16460 = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u32 flash_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = adis_read_reg_32(&adis16460->adis, ADIS16460_REG_FLASH_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) &flash_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *val = flash_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) DEFINE_DEBUGFS_ATTRIBUTE(adis16460_flash_count_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) adis16460_show_flash_count, NULL, "%lld\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int adis16460_debugfs_init(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct adis16460 *adis16460 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct dentry *d = iio_get_debugfs_dentry(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) debugfs_create_file_unsafe("serial_number", 0400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) d, adis16460, &adis16460_serial_number_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) debugfs_create_file_unsafe("product_id", 0400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) d, adis16460, &adis16460_product_id_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) debugfs_create_file_unsafe("flash_count", 0400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) d, adis16460, &adis16460_flash_count_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int adis16460_debugfs_init(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int adis16460_set_freq(struct iio_dev *indio_dev, int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct adis16460 *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) t = val * 1000 + val2 / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (t <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) t = 2048000 / t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (t > 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) t = 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (t != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) t--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return adis_write_reg_16(&st->adis, ADIS16460_REG_DEC_RATE, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int adis16460_get_freq(struct iio_dev *indio_dev, int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct adis16460 *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) uint16_t t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = adis_read_reg_16(&st->adis, ADIS16460_REG_DEC_RATE, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) freq = 2048000 / (t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *val = freq / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *val2 = (freq % 1000) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int adis16460_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) const struct iio_chan_spec *chan, int *val, int *val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct adis16460 *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return adis_single_conversion(indio_dev, chan, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case IIO_ANGL_VEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *val = st->chip_info->gyro_max_scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *val2 = st->chip_info->gyro_max_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case IIO_ACCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *val = st->chip_info->accel_max_scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *val2 = st->chip_info->accel_max_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case IIO_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *val = 50; /* 50 milli degrees Celsius/LSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *val = 500; /* 25 degrees Celsius = 0x0000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return adis16460_get_freq(indio_dev, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int adis16460_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) const struct iio_chan_spec *chan, int val, int val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return adis16460_set_freq(indio_dev, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ADIS16460_SCAN_GYRO_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ADIS16460_SCAN_GYRO_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ADIS16460_SCAN_GYRO_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ADIS16460_SCAN_ACCEL_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ADIS16460_SCAN_ACCEL_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ADIS16460_SCAN_ACCEL_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ADIS16460_SCAN_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define ADIS16460_MOD_CHANNEL(_type, _mod, _address, _si, _bits) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .type = (_type), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .channel2 = (_mod), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .address = (_address), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .scan_index = (_si), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .sign = 's', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .realbits = (_bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .storagebits = (_bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .endianness = IIO_BE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define ADIS16460_GYRO_CHANNEL(_mod) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ADIS16460_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ADIS16460_REG_ ## _mod ## _GYRO_LOW, ADIS16460_SCAN_GYRO_ ## _mod, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define ADIS16460_ACCEL_CHANNEL(_mod) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ADIS16460_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ADIS16460_REG_ ## _mod ## _ACCL_LOW, ADIS16460_SCAN_ACCEL_ ## _mod, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define ADIS16460_TEMP_CHANNEL() { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .type = IIO_TEMP, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .channel = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) BIT(IIO_CHAN_INFO_OFFSET), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .address = ADIS16460_REG_TEMP_OUT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .scan_index = ADIS16460_SCAN_TEMP, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .sign = 's', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .realbits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .endianness = IIO_BE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static const struct iio_chan_spec adis16460_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ADIS16460_GYRO_CHANNEL(X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ADIS16460_GYRO_CHANNEL(Y),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ADIS16460_GYRO_CHANNEL(Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ADIS16460_ACCEL_CHANNEL(X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ADIS16460_ACCEL_CHANNEL(Y),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ADIS16460_ACCEL_CHANNEL(Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ADIS16460_TEMP_CHANNEL(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) IIO_CHAN_SOFT_TIMESTAMP(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static const struct adis16460_chip_info adis16460_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .channels = adis16460_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .num_channels = ARRAY_SIZE(adis16460_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * storing the value in rad/degree and the scale in degree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * gives us the result in rad and better precession than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * storing the scale directly in rad.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .gyro_max_val = IIO_RAD_TO_DEGREE(200 << 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .gyro_max_scale = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .accel_max_val = IIO_M_S_2_TO_G(20000 << 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .accel_max_scale = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static const struct iio_info adis16460_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .read_raw = &adis16460_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) .write_raw = &adis16460_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .update_scan_mode = adis_update_scan_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .debugfs_reg_access = adis_debugfs_reg_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int adis16460_enable_irq(struct adis *adis, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * There is no way to gate the data-ready signal internally inside the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * ADIS16460 :(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) enable_irq(adis->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) disable_irq(adis->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define ADIS16460_DIAG_STAT_IN_CLK_OOS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define ADIS16460_DIAG_STAT_FLASH_MEM 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #define ADIS16460_DIAG_STAT_SELF_TEST 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define ADIS16460_DIAG_STAT_OVERRANGE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #define ADIS16460_DIAG_STAT_SPI_COMM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #define ADIS16460_DIAG_STAT_FLASH_UPT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static const char * const adis16460_status_error_msgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) [ADIS16460_DIAG_STAT_IN_CLK_OOS] = "Input clock out of sync",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) [ADIS16460_DIAG_STAT_FLASH_MEM] = "Flash memory failure",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) [ADIS16460_DIAG_STAT_SELF_TEST] = "Self test diagnostic failure",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) [ADIS16460_DIAG_STAT_OVERRANGE] = "Sensor overrange",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) [ADIS16460_DIAG_STAT_SPI_COMM] = "SPI communication failure",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) [ADIS16460_DIAG_STAT_FLASH_UPT] = "Flash update failure",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct adis_timeout adis16460_timeouts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .reset_ms = 225,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .sw_reset_ms = 225,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .self_test_ms = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static const struct adis_data adis16460_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .diag_stat_reg = ADIS16460_REG_DIAG_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .glob_cmd_reg = ADIS16460_REG_GLOB_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .prod_id_reg = ADIS16460_REG_PROD_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .prod_id = 16460,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .self_test_mask = BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .self_test_reg = ADIS16460_REG_GLOB_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .has_paging = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .read_delay = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .write_delay = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .cs_change_delay = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .status_error_msgs = adis16460_status_error_msgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .status_error_mask = BIT(ADIS16460_DIAG_STAT_IN_CLK_OOS) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) BIT(ADIS16460_DIAG_STAT_FLASH_MEM) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) BIT(ADIS16460_DIAG_STAT_SELF_TEST) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) BIT(ADIS16460_DIAG_STAT_OVERRANGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) BIT(ADIS16460_DIAG_STAT_SPI_COMM) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) BIT(ADIS16460_DIAG_STAT_FLASH_UPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .enable_irq = adis16460_enable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .timeouts = &adis16460_timeouts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int adis16460_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct adis16460 *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (indio_dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) spi_set_drvdata(spi, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) st->chip_info = &adis16460_chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) indio_dev->name = spi_get_device_id(spi)->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) indio_dev->channels = st->chip_info->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) indio_dev->num_channels = st->chip_info->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) indio_dev->info = &adis16460_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ret = adis_init(&st->adis, indio_dev, spi, &adis16460_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) adis16460_enable_irq(&st->adis, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = __adis_initial_startup(&st->adis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = devm_iio_device_register(&spi->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) adis16460_debugfs_init(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static const struct spi_device_id adis16460_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) { "adis16460", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) MODULE_DEVICE_TABLE(spi, adis16460_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static const struct of_device_id adis16460_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) { .compatible = "adi,adis16460" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) MODULE_DEVICE_TABLE(of, adis16460_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static struct spi_driver adis16460_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .name = "adis16460",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .of_match_table = adis16460_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .id_table = adis16460_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .probe = adis16460_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) module_spi_driver(adis16460_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) MODULE_AUTHOR("Dragos Bogdan <dragos.bogdan@analog.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) MODULE_DESCRIPTION("Analog Devices ADIS16460 IMU driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) MODULE_LICENSE("GPL");