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_data adis16203_data = { 241 .read_delay = 20, 242 .msc_ctrl_reg = ADIS16203_MSC_CTRL, 243 .glob_cmd_reg = ADIS16203_GLOB_CMD, 244 .diag_stat_reg = ADIS16203_DIAG_STAT, 245 246 .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN, 247 .self_test_no_autoclear = true, 248 .startup_delay = ADIS16203_STARTUP_DELAY, 249 250 .status_error_msgs = adis16203_status_error_msgs, 251 .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) | 252 BIT(ADIS16203_DIAG_STAT_SPI_FAIL_BIT) | 253 BIT(ADIS16203_DIAG_STAT_FLASH_UPT_BIT) | 254 BIT(ADIS16203_DIAG_STAT_POWER_HIGH_BIT) | 255 BIT(ADIS16203_DIAG_STAT_POWER_LOW_BIT), 256 }; 257 258 static int adis16203_probe(struct spi_device *spi) 259 { 260 int ret; 261 struct iio_dev *indio_dev; 262 struct adis *st; 263 264 /* setup the industrialio driver allocated elements */ 265 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 266 if (!indio_dev) 267 return -ENOMEM; 268 st = iio_priv(indio_dev); 269 /* this is only used for removal purposes */ 270 spi_set_drvdata(spi, indio_dev); 271 272 indio_dev->name = spi->dev.driver->name; 273 indio_dev->dev.parent = &spi->dev; 274 indio_dev->channels = adis16203_channels; 275 indio_dev->num_channels = ARRAY_SIZE(adis16203_channels); 276 indio_dev->info = &adis16203_info; 277 indio_dev->modes = INDIO_DIRECT_MODE; 278 279 ret = adis_init(st, indio_dev, spi, &adis16203_data); 280 if (ret) 281 return ret; 282 283 ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); 284 if (ret) 285 return ret; 286 287 /* Get the device into a sane initial state */ 288 ret = adis_initial_startup(st); 289 if (ret) 290 goto error_cleanup_buffer_trigger; 291 292 ret = iio_device_register(indio_dev); 293 if (ret) 294 goto error_cleanup_buffer_trigger; 295 296 return 0; 297 298 error_cleanup_buffer_trigger: 299 adis_cleanup_buffer_and_trigger(st, indio_dev); 300 return ret; 301 } 302 303 static int adis16203_remove(struct spi_device *spi) 304 { 305 struct iio_dev *indio_dev = spi_get_drvdata(spi); 306 struct adis *st = iio_priv(indio_dev); 307 308 iio_device_unregister(indio_dev); 309 adis_cleanup_buffer_and_trigger(st, indio_dev); 310 311 return 0; 312 } 313 314 static const struct of_device_id adis16203_of_match[] = { 315 { .compatible = "adi,adis16203" }, 316 { }, 317 }; 318 319 MODULE_DEVICE_TABLE(of, adis16203_of_match); 320 321 static struct spi_driver adis16203_driver = { 322 .driver = { 323 .name = "adis16203", 324 .of_match_table = adis16203_of_match, 325 }, 326 .probe = adis16203_probe, 327 .remove = adis16203_remove, 328 }; 329 module_spi_driver(adis16203_driver); 330 331 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 332 MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer"); 333 MODULE_LICENSE("GPL v2"); 334 MODULE_ALIAS("spi:adis16203"); 335