1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * ADIS16203 Programmable 360 Degrees Inclinometer 4 * 5 * Copyright 2010 Analog Devices Inc. 6 */ 7 8 #include <linux/delay.h> 9 #include <linux/device.h> 10 11 #include <linux/iio/buffer.h> 12 #include <linux/iio/iio.h> 13 #include <linux/iio/imu/adis.h> 14 #include <linux/iio/sysfs.h> 15 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 #include <linux/slab.h> 20 #include <linux/spi/spi.h> 21 #include <linux/sysfs.h> 22 23 #define ADIS16203_STARTUP_DELAY 220 /* ms */ 24 25 /* Flash memory write count */ 26 #define ADIS16203_FLASH_CNT 0x00 27 28 /* Output, power supply */ 29 #define ADIS16203_SUPPLY_OUT 0x02 30 31 /* Output, auxiliary ADC input */ 32 #define ADIS16203_AUX_ADC 0x08 33 34 /* Output, temperature */ 35 #define ADIS16203_TEMP_OUT 0x0A 36 37 /* Output, x-axis inclination */ 38 #define ADIS16203_XINCL_OUT 0x0C 39 40 /* Output, y-axis inclination */ 41 #define ADIS16203_YINCL_OUT 0x0E 42 43 /* Incline null calibration */ 44 #define ADIS16203_INCL_NULL 0x18 45 46 /* Alarm 1 amplitude threshold */ 47 #define ADIS16203_ALM_MAG1 0x20 48 49 /* Alarm 2 amplitude threshold */ 50 #define ADIS16203_ALM_MAG2 0x22 51 52 /* Alarm 1, sample period */ 53 #define ADIS16203_ALM_SMPL1 0x24 54 55 /* Alarm 2, sample period */ 56 #define ADIS16203_ALM_SMPL2 0x26 57 58 /* Alarm control */ 59 #define ADIS16203_ALM_CTRL 0x28 60 61 /* Auxiliary DAC data */ 62 #define ADIS16203_AUX_DAC 0x30 63 64 /* General-purpose digital input/output control */ 65 #define ADIS16203_GPIO_CTRL 0x32 66 67 /* Miscellaneous control */ 68 #define ADIS16203_MSC_CTRL 0x34 69 70 /* Internal sample period (rate) control */ 71 #define ADIS16203_SMPL_PRD 0x36 72 73 /* Operation, filter configuration */ 74 #define ADIS16203_AVG_CNT 0x38 75 76 /* Operation, sleep mode control */ 77 #define ADIS16203_SLP_CNT 0x3A 78 79 /* Diagnostics, system status register */ 80 #define ADIS16203_DIAG_STAT 0x3C 81 82 /* Operation, system command register */ 83 #define ADIS16203_GLOB_CMD 0x3E 84 85 /* MSC_CTRL */ 86 87 /* Self-test at power-on: 1 = disabled, 0 = enabled */ 88 #define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST BIT(10) 89 90 /* Reverses rotation of both inclination outputs */ 91 #define ADIS16203_MSC_CTRL_REVERSE_ROT_EN BIT(9) 92 93 /* Self-test enable */ 94 #define ADIS16203_MSC_CTRL_SELF_TEST_EN BIT(8) 95 96 /* Data-ready enable: 1 = enabled, 0 = disabled */ 97 #define ADIS16203_MSC_CTRL_DATA_RDY_EN BIT(2) 98 99 /* Data-ready polarity: 1 = active high, 0 = active low */ 100 #define ADIS16203_MSC_CTRL_ACTIVE_HIGH BIT(1) 101 102 /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ 103 #define ADIS16203_MSC_CTRL_DATA_RDY_DIO1 BIT(0) 104 105 /* DIAG_STAT */ 106 107 /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ 108 #define ADIS16203_DIAG_STAT_ALARM2 BIT(9) 109 110 /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ 111 #define ADIS16203_DIAG_STAT_ALARM1 BIT(8) 112 113 /* Self-test diagnostic error flag */ 114 #define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5 115 116 /* SPI communications failure */ 117 #define ADIS16203_DIAG_STAT_SPI_FAIL_BIT 3 118 119 /* Flash update failure */ 120 #define ADIS16203_DIAG_STAT_FLASH_UPT_BIT 2 121 122 /* Power supply above 3.625 V */ 123 #define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 124 125 /* Power supply below 2.975 V */ 126 #define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 127 128 /* GLOB_CMD */ 129 130 #define ADIS16203_GLOB_CMD_SW_RESET BIT(7) 131 #define ADIS16203_GLOB_CMD_CLEAR_STAT BIT(4) 132 #define ADIS16203_GLOB_CMD_FACTORY_CAL BIT(1) 133 134 #define ADIS16203_ERROR_ACTIVE BIT(14) 135 136 enum adis16203_scan { 137 ADIS16203_SCAN_INCLI_X, 138 ADIS16203_SCAN_INCLI_Y, 139 ADIS16203_SCAN_SUPPLY, 140 ADIS16203_SCAN_AUX_ADC, 141 ADIS16203_SCAN_TEMP, 142 }; 143 144 #define DRIVER_NAME "adis16203" 145 146 static const u8 adis16203_addresses[] = { 147 [ADIS16203_SCAN_INCLI_X] = ADIS16203_INCL_NULL, 148 }; 149 150 static int adis16203_write_raw(struct iio_dev *indio_dev, 151 struct iio_chan_spec const *chan, 152 int val, 153 int val2, 154 long mask) 155 { 156 struct adis *st = iio_priv(indio_dev); 157 /* currently only one writable parameter which keeps this simple */ 158 u8 addr = adis16203_addresses[chan->scan_index]; 159 160 return adis_write_reg_16(st, addr, val & 0x3FFF); 161 } 162 163 static int adis16203_read_raw(struct iio_dev *indio_dev, 164 struct iio_chan_spec const *chan, 165 int *val, int *val2, 166 long mask) 167 { 168 struct adis *st = iio_priv(indio_dev); 169 int ret; 170 u8 addr; 171 s16 val16; 172 173 switch (mask) { 174 case IIO_CHAN_INFO_RAW: 175 return adis_single_conversion(indio_dev, chan, 176 ADIS16203_ERROR_ACTIVE, val); 177 case IIO_CHAN_INFO_SCALE: 178 switch (chan->type) { 179 case IIO_VOLTAGE: 180 if (chan->channel == 0) { 181 *val = 1; 182 *val2 = 220000; /* 1.22 mV */ 183 } else { 184 *val = 0; 185 *val2 = 610000; /* 0.61 mV */ 186 } 187 return IIO_VAL_INT_PLUS_MICRO; 188 case IIO_TEMP: 189 *val = -470; /* -0.47 C */ 190 *val2 = 0; 191 return IIO_VAL_INT_PLUS_MICRO; 192 case IIO_INCLI: 193 *val = 0; 194 *val2 = 25000; /* 0.025 degree */ 195 return IIO_VAL_INT_PLUS_MICRO; 196 default: 197 return -EINVAL; 198 } 199 case IIO_CHAN_INFO_OFFSET: 200 *val = 25000 / -470 - 1278; /* 25 C = 1278 */ 201 return IIO_VAL_INT; 202 case IIO_CHAN_INFO_CALIBBIAS: 203 addr = adis16203_addresses[chan->scan_index]; 204 ret = adis_read_reg_16(st, addr, &val16); 205 if (ret) 206 return ret; 207 *val = sign_extend32(val16, 13); 208 return IIO_VAL_INT; 209 default: 210 return -EINVAL; 211 } 212 } 213 214 static const struct iio_chan_spec adis16203_channels[] = { 215 ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 0, 12), 216 ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 0, 12), 217 ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X, 218 BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14), 219 /* Fixme: Not what it appears to be - see data sheet */ 220 ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 221 0, 0, 14), 222 ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 0, 12), 223 IIO_CHAN_SOFT_TIMESTAMP(5), 224 }; 225 226 static const struct iio_info adis16203_info = { 227 .read_raw = adis16203_read_raw, 228 .write_raw = adis16203_write_raw, 229 .update_scan_mode = adis_update_scan_mode, 230 }; 231 232 static const char * const adis16203_status_error_msgs[] = { 233 [ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", 234 [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", 235 [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", 236 [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", 237 [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", 238 }; 239 240 static const struct adis_timeout adis16203_timeouts = { 241 .reset_ms = ADIS16203_STARTUP_DELAY, 242 .sw_reset_ms = ADIS16203_STARTUP_DELAY, 243 .self_test_ms = ADIS16203_STARTUP_DELAY 244 }; 245 246 static const struct adis_data adis16203_data = { 247 .read_delay = 20, 248 .msc_ctrl_reg = ADIS16203_MSC_CTRL, 249 .glob_cmd_reg = ADIS16203_GLOB_CMD, 250 .diag_stat_reg = ADIS16203_DIAG_STAT, 251 252 .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN, 253 .self_test_reg = ADIS16203_MSC_CTRL, 254 .self_test_no_autoclear = true, 255 .timeouts = &adis16203_timeouts, 256 257 .status_error_msgs = adis16203_status_error_msgs, 258 .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) | 259 BIT(ADIS16203_DIAG_STAT_SPI_FAIL_BIT) | 260 BIT(ADIS16203_DIAG_STAT_FLASH_UPT_BIT) | 261 BIT(ADIS16203_DIAG_STAT_POWER_HIGH_BIT) | 262 BIT(ADIS16203_DIAG_STAT_POWER_LOW_BIT), 263 }; 264 265 static int adis16203_probe(struct spi_device *spi) 266 { 267 int ret; 268 struct iio_dev *indio_dev; 269 struct adis *st; 270 271 /* setup the industrialio driver allocated elements */ 272 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 273 if (!indio_dev) 274 return -ENOMEM; 275 st = iio_priv(indio_dev); 276 /* this is only used for removal purposes */ 277 spi_set_drvdata(spi, indio_dev); 278 279 indio_dev->name = spi->dev.driver->name; 280 indio_dev->channels = adis16203_channels; 281 indio_dev->num_channels = ARRAY_SIZE(adis16203_channels); 282 indio_dev->info = &adis16203_info; 283 indio_dev->modes = INDIO_DIRECT_MODE; 284 285 ret = adis_init(st, indio_dev, spi, &adis16203_data); 286 if (ret) 287 return ret; 288 289 ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); 290 if (ret) 291 return ret; 292 293 /* Get the device into a sane initial state */ 294 ret = adis_initial_startup(st); 295 if (ret) 296 goto error_cleanup_buffer_trigger; 297 298 ret = iio_device_register(indio_dev); 299 if (ret) 300 goto error_cleanup_buffer_trigger; 301 302 return 0; 303 304 error_cleanup_buffer_trigger: 305 adis_cleanup_buffer_and_trigger(st, indio_dev); 306 return ret; 307 } 308 309 static int adis16203_remove(struct spi_device *spi) 310 { 311 struct iio_dev *indio_dev = spi_get_drvdata(spi); 312 struct adis *st = iio_priv(indio_dev); 313 314 iio_device_unregister(indio_dev); 315 adis_cleanup_buffer_and_trigger(st, indio_dev); 316 317 return 0; 318 } 319 320 static const struct of_device_id adis16203_of_match[] = { 321 { .compatible = "adi,adis16203" }, 322 { }, 323 }; 324 325 MODULE_DEVICE_TABLE(of, adis16203_of_match); 326 327 static struct spi_driver adis16203_driver = { 328 .driver = { 329 .name = "adis16203", 330 .of_match_table = adis16203_of_match, 331 }, 332 .probe = adis16203_probe, 333 .remove = adis16203_remove, 334 }; 335 module_spi_driver(adis16203_driver); 336 337 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 338 MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer"); 339 MODULE_LICENSE("GPL v2"); 340 MODULE_ALIAS("spi:adis16203"); 341