Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adis16260: Add ADIS16266 support

The ADIS16266 is mostly register compatible to the ADIS16260. The
difference is a different gyroscope scale factor as well not having the
relative angular displacement channel.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Lars-Peter Clausen and committed by
Jonathan Cameron
f1afda12 3c386760

+98 -39
+98 -39
drivers/iio/gyro/adis16260.c
··· 101 101 #define ADIS16260_SCAN_TEMP 3 102 102 #define ADIS16260_SCAN_ANGL 4 103 103 104 - /* Power down the device */ 105 - static int adis16260_stop_device(struct iio_dev *indio_dev) 106 - { 107 - struct adis *adis = iio_priv(indio_dev); 108 - int ret; 109 - u16 val = ADIS16260_SLP_CNT_POWER_OFF; 104 + struct adis16260_chip_info { 105 + unsigned int gyro_max_val; 106 + unsigned int gyro_max_scale; 107 + const struct iio_chan_spec *channels; 108 + unsigned int num_channels; 109 + }; 110 110 111 - ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val); 112 - if (ret) 113 - dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT"); 111 + struct adis16260 { 112 + const struct adis16260_chip_info *info; 114 113 115 - return ret; 116 - } 114 + struct adis adis; 115 + }; 116 + 117 + enum adis16260_type { 118 + ADIS16251, 119 + ADIS16260, 120 + ADIS16266, 121 + }; 117 122 118 123 static const struct iio_chan_spec adis16260_channels[] = { 119 124 ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, ··· 136 131 IIO_CHAN_SOFT_TIMESTAMP(5), 137 132 }; 138 133 134 + static const struct iio_chan_spec adis16266_channels[] = { 135 + ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, 136 + BIT(IIO_CHAN_INFO_CALIBBIAS) | 137 + BIT(IIO_CHAN_INFO_CALIBSCALE), 138 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 14), 139 + ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 140 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 12), 141 + ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 142 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 12), 143 + ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 144 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 12), 145 + IIO_CHAN_SOFT_TIMESTAMP(4), 146 + }; 147 + 148 + static const struct adis16260_chip_info adis16260_chip_info_table[] = { 149 + [ADIS16251] = { 150 + .gyro_max_scale = 80, 151 + .gyro_max_val = IIO_RAD_TO_DEGREE(4368), 152 + .channels = adis16260_channels, 153 + .num_channels = ARRAY_SIZE(adis16260_channels), 154 + }, 155 + [ADIS16260] = { 156 + .gyro_max_scale = 320, 157 + .gyro_max_val = IIO_RAD_TO_DEGREE(4368), 158 + .channels = adis16260_channels, 159 + .num_channels = ARRAY_SIZE(adis16260_channels), 160 + }, 161 + [ADIS16266] = { 162 + .gyro_max_scale = 14000, 163 + .gyro_max_val = IIO_RAD_TO_DEGREE(3357), 164 + .channels = adis16266_channels, 165 + .num_channels = ARRAY_SIZE(adis16266_channels), 166 + }, 167 + }; 168 + 169 + /* Power down the device */ 170 + static int adis16260_stop_device(struct iio_dev *indio_dev) 171 + { 172 + struct adis16260 *adis16260 = iio_priv(indio_dev); 173 + int ret; 174 + u16 val = ADIS16260_SLP_CNT_POWER_OFF; 175 + 176 + ret = adis_write_reg_16(&adis16260->adis, ADIS16260_SLP_CNT, val); 177 + if (ret) 178 + dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT"); 179 + 180 + return ret; 181 + } 182 + 139 183 static const u8 adis16260_addresses[][2] = { 140 184 [ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE }, 141 185 }; ··· 194 140 int *val, int *val2, 195 141 long mask) 196 142 { 197 - struct adis *adis = iio_priv(indio_dev); 143 + struct adis16260 *adis16260 = iio_priv(indio_dev); 144 + const struct adis16260_chip_info *info = adis16260->info; 145 + struct adis *adis = &adis16260->adis; 198 146 int ret; 199 147 u8 addr; 200 148 s16 val16; ··· 208 152 case IIO_CHAN_INFO_SCALE: 209 153 switch (chan->type) { 210 154 case IIO_ANGL_VEL: 211 - *val = 0; 212 - if (spi_get_device_id(adis->spi)->driver_data) { 213 - /* 0.01832 degree / sec */ 214 - *val2 = IIO_DEGREE_TO_RAD(18320); 215 - } else { 216 - /* 0.07326 degree / sec */ 217 - *val2 = IIO_DEGREE_TO_RAD(73260); 218 - } 219 - return IIO_VAL_INT_PLUS_MICRO; 155 + *val = info->gyro_max_scale; 156 + *val2 = info->gyro_max_val; 157 + return IIO_VAL_FRACTIONAL; 220 158 case IIO_INCLI: 221 159 *val = 0; 222 160 *val2 = IIO_DEGREE_TO_RAD(36630); ··· 274 224 int val2, 275 225 long mask) 276 226 { 277 - struct adis *adis = iio_priv(indio_dev); 227 + struct adis16260 *adis16260 = iio_priv(indio_dev); 228 + struct adis *adis = &adis16260->adis; 278 229 int ret; 279 230 u8 addr; 280 231 u8 t; ··· 356 305 357 306 static int adis16260_probe(struct spi_device *spi) 358 307 { 308 + const struct spi_device_id *id; 309 + struct adis16260 *adis16260; 359 310 struct iio_dev *indio_dev; 360 - struct adis *adis; 361 311 int ret; 362 312 313 + id = spi_get_device_id(spi); 314 + if (!id) 315 + return -ENODEV; 316 + 363 317 /* setup the industrialio driver allocated elements */ 364 - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis)); 318 + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16260)); 365 319 if (!indio_dev) 366 320 return -ENOMEM; 367 - adis = iio_priv(indio_dev); 321 + adis16260 = iio_priv(indio_dev); 368 322 /* this is only used for removal purposes */ 369 323 spi_set_drvdata(spi, indio_dev); 370 324 371 - indio_dev->name = spi_get_device_id(spi)->name; 325 + adis16260->info = &adis16260_chip_info_table[id->driver_data]; 326 + 327 + indio_dev->name = id->name; 372 328 indio_dev->dev.parent = &spi->dev; 373 329 indio_dev->info = &adis16260_info; 374 - indio_dev->channels = adis16260_channels; 375 - indio_dev->num_channels = ARRAY_SIZE(adis16260_channels); 330 + indio_dev->channels = adis16260->info->channels; 331 + indio_dev->num_channels = adis16260->info->num_channels; 376 332 indio_dev->modes = INDIO_DIRECT_MODE; 377 333 378 - ret = adis_init(adis, indio_dev, spi, &adis16260_data); 334 + ret = adis_init(&adis16260->adis, indio_dev, spi, &adis16260_data); 379 335 if (ret) 380 336 return ret; 381 337 382 - ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL); 338 + ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); 383 339 if (ret) 384 340 return ret; 385 341 386 342 /* Get the device into a sane initial state */ 387 - ret = adis_initial_startup(adis); 343 + ret = adis_initial_startup(&adis16260->adis); 388 344 if (ret) 389 345 goto error_cleanup_buffer_trigger; 390 346 ret = iio_device_register(indio_dev); ··· 401 343 return 0; 402 344 403 345 error_cleanup_buffer_trigger: 404 - adis_cleanup_buffer_and_trigger(adis, indio_dev); 346 + adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); 405 347 return ret; 406 348 } 407 349 408 350 static int adis16260_remove(struct spi_device *spi) 409 351 { 410 352 struct iio_dev *indio_dev = spi_get_drvdata(spi); 411 - struct adis *adis = iio_priv(indio_dev); 353 + struct adis16260 *adis16260 = iio_priv(indio_dev); 412 354 413 355 iio_device_unregister(indio_dev); 414 356 adis16260_stop_device(indio_dev); 415 - adis_cleanup_buffer_and_trigger(adis, indio_dev); 357 + adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); 416 358 417 359 return 0; 418 360 } ··· 422 364 * support for the on chip filtering. 423 365 */ 424 366 static const struct spi_device_id adis16260_id[] = { 425 - {"adis16260", 0}, 426 - {"adis16265", 0}, 427 - {"adis16250", 0}, 428 - {"adis16255", 0}, 429 - {"adis16251", 1}, 367 + {"adis16260", ADIS16260}, 368 + {"adis16265", ADIS16260}, 369 + {"adis16266", ADIS16266}, 370 + {"adis16250", ADIS16260}, 371 + {"adis16255", ADIS16260}, 372 + {"adis16251", ADIS16251}, 430 373 {} 431 374 }; 432 375 MODULE_DEVICE_TABLE(spi, adis16260_id);