0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/delay.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/mutex.h>
0012 #include <linux/device.h>
0013 #include <linux/kernel.h>
0014 #include <linux/spi/spi.h>
0015 #include <linux/module.h>
0016 #include <asm/unaligned.h>
0017
0018 #include <linux/iio/iio.h>
0019 #include <linux/iio/imu/adis.h>
0020
0021 #define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2)
0022 #define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1)
0023 #define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
0024 #define ADIS_GLOB_CMD_SW_RESET BIT(7)
0025
0026
0027
0028
0029
0030
0031
0032
0033 int __adis_write_reg(struct adis *adis, unsigned int reg, unsigned int value,
0034 unsigned int size)
0035 {
0036 unsigned int page = reg / ADIS_PAGE_SIZE;
0037 int ret, i;
0038 struct spi_message msg;
0039 struct spi_transfer xfers[] = {
0040 {
0041 .tx_buf = adis->tx,
0042 .bits_per_word = 8,
0043 .len = 2,
0044 .cs_change = 1,
0045 .delay.value = adis->data->write_delay,
0046 .delay.unit = SPI_DELAY_UNIT_USECS,
0047 .cs_change_delay.value = adis->data->cs_change_delay,
0048 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
0049 }, {
0050 .tx_buf = adis->tx + 2,
0051 .bits_per_word = 8,
0052 .len = 2,
0053 .cs_change = 1,
0054 .delay.value = adis->data->write_delay,
0055 .delay.unit = SPI_DELAY_UNIT_USECS,
0056 .cs_change_delay.value = adis->data->cs_change_delay,
0057 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
0058 }, {
0059 .tx_buf = adis->tx + 4,
0060 .bits_per_word = 8,
0061 .len = 2,
0062 .cs_change = 1,
0063 .delay.value = adis->data->write_delay,
0064 .delay.unit = SPI_DELAY_UNIT_USECS,
0065 .cs_change_delay.value = adis->data->cs_change_delay,
0066 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
0067 }, {
0068 .tx_buf = adis->tx + 6,
0069 .bits_per_word = 8,
0070 .len = 2,
0071 .delay.value = adis->data->write_delay,
0072 .delay.unit = SPI_DELAY_UNIT_USECS,
0073 }, {
0074 .tx_buf = adis->tx + 8,
0075 .bits_per_word = 8,
0076 .len = 2,
0077 .delay.value = adis->data->write_delay,
0078 .delay.unit = SPI_DELAY_UNIT_USECS,
0079 },
0080 };
0081
0082 spi_message_init(&msg);
0083
0084 if (adis->current_page != page) {
0085 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
0086 adis->tx[1] = page;
0087 spi_message_add_tail(&xfers[0], &msg);
0088 }
0089
0090 switch (size) {
0091 case 4:
0092 adis->tx[8] = ADIS_WRITE_REG(reg + 3);
0093 adis->tx[9] = (value >> 24) & 0xff;
0094 adis->tx[6] = ADIS_WRITE_REG(reg + 2);
0095 adis->tx[7] = (value >> 16) & 0xff;
0096 fallthrough;
0097 case 2:
0098 adis->tx[4] = ADIS_WRITE_REG(reg + 1);
0099 adis->tx[5] = (value >> 8) & 0xff;
0100 fallthrough;
0101 case 1:
0102 adis->tx[2] = ADIS_WRITE_REG(reg);
0103 adis->tx[3] = value & 0xff;
0104 break;
0105 default:
0106 return -EINVAL;
0107 }
0108
0109 xfers[size].cs_change = 0;
0110
0111 for (i = 1; i <= size; i++)
0112 spi_message_add_tail(&xfers[i], &msg);
0113
0114 ret = spi_sync(adis->spi, &msg);
0115 if (ret) {
0116 dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
0117 reg, ret);
0118 } else {
0119 adis->current_page = page;
0120 }
0121
0122 return ret;
0123 }
0124 EXPORT_SYMBOL_NS_GPL(__adis_write_reg, IIO_ADISLIB);
0125
0126
0127
0128
0129
0130
0131
0132
0133 int __adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val,
0134 unsigned int size)
0135 {
0136 unsigned int page = reg / ADIS_PAGE_SIZE;
0137 struct spi_message msg;
0138 int ret;
0139 struct spi_transfer xfers[] = {
0140 {
0141 .tx_buf = adis->tx,
0142 .bits_per_word = 8,
0143 .len = 2,
0144 .cs_change = 1,
0145 .delay.value = adis->data->write_delay,
0146 .delay.unit = SPI_DELAY_UNIT_USECS,
0147 .cs_change_delay.value = adis->data->cs_change_delay,
0148 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
0149 }, {
0150 .tx_buf = adis->tx + 2,
0151 .bits_per_word = 8,
0152 .len = 2,
0153 .cs_change = 1,
0154 .delay.value = adis->data->read_delay,
0155 .delay.unit = SPI_DELAY_UNIT_USECS,
0156 .cs_change_delay.value = adis->data->cs_change_delay,
0157 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
0158 }, {
0159 .tx_buf = adis->tx + 4,
0160 .rx_buf = adis->rx,
0161 .bits_per_word = 8,
0162 .len = 2,
0163 .cs_change = 1,
0164 .delay.value = adis->data->read_delay,
0165 .delay.unit = SPI_DELAY_UNIT_USECS,
0166 .cs_change_delay.value = adis->data->cs_change_delay,
0167 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
0168 }, {
0169 .rx_buf = adis->rx + 2,
0170 .bits_per_word = 8,
0171 .len = 2,
0172 .delay.value = adis->data->read_delay,
0173 .delay.unit = SPI_DELAY_UNIT_USECS,
0174 },
0175 };
0176
0177 spi_message_init(&msg);
0178
0179 if (adis->current_page != page) {
0180 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
0181 adis->tx[1] = page;
0182 spi_message_add_tail(&xfers[0], &msg);
0183 }
0184
0185 switch (size) {
0186 case 4:
0187 adis->tx[2] = ADIS_READ_REG(reg + 2);
0188 adis->tx[3] = 0;
0189 spi_message_add_tail(&xfers[1], &msg);
0190 fallthrough;
0191 case 2:
0192 adis->tx[4] = ADIS_READ_REG(reg);
0193 adis->tx[5] = 0;
0194 spi_message_add_tail(&xfers[2], &msg);
0195 spi_message_add_tail(&xfers[3], &msg);
0196 break;
0197 default:
0198 return -EINVAL;
0199 }
0200
0201 ret = spi_sync(adis->spi, &msg);
0202 if (ret) {
0203 dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
0204 reg, ret);
0205 return ret;
0206 }
0207
0208 adis->current_page = page;
0209
0210 switch (size) {
0211 case 4:
0212 *val = get_unaligned_be32(adis->rx);
0213 break;
0214 case 2:
0215 *val = get_unaligned_be16(adis->rx + 2);
0216 break;
0217 }
0218
0219 return ret;
0220 }
0221 EXPORT_SYMBOL_NS_GPL(__adis_read_reg, IIO_ADISLIB);
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask,
0233 const u32 val, u8 size)
0234 {
0235 int ret;
0236 u32 __val;
0237
0238 ret = __adis_read_reg(adis, reg, &__val, size);
0239 if (ret)
0240 return ret;
0241
0242 __val = (__val & ~mask) | (val & mask);
0243
0244 return __adis_write_reg(adis, reg, __val, size);
0245 }
0246 EXPORT_SYMBOL_NS_GPL(__adis_update_bits_base, IIO_ADISLIB);
0247
0248 #ifdef CONFIG_DEBUG_FS
0249
0250 int adis_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg,
0251 unsigned int writeval, unsigned int *readval)
0252 {
0253 struct adis *adis = iio_device_get_drvdata(indio_dev);
0254
0255 if (readval) {
0256 u16 val16;
0257 int ret;
0258
0259 ret = adis_read_reg_16(adis, reg, &val16);
0260 if (ret == 0)
0261 *readval = val16;
0262
0263 return ret;
0264 }
0265
0266 return adis_write_reg_16(adis, reg, writeval);
0267 }
0268 EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB);
0269
0270 #endif
0271
0272
0273
0274
0275
0276
0277
0278
0279 int adis_enable_irq(struct adis *adis, bool enable)
0280 {
0281 int ret = 0;
0282 u16 msc;
0283
0284 mutex_lock(&adis->state_lock);
0285
0286 if (adis->data->enable_irq) {
0287 ret = adis->data->enable_irq(adis, enable);
0288 goto out_unlock;
0289 }
0290
0291 if (adis->data->unmasked_drdy) {
0292 if (enable)
0293 enable_irq(adis->spi->irq);
0294 else
0295 disable_irq(adis->spi->irq);
0296
0297 goto out_unlock;
0298 }
0299
0300 ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
0301 if (ret)
0302 goto out_unlock;
0303
0304 msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
0305 msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
0306 if (enable)
0307 msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
0308 else
0309 msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
0310
0311 ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
0312
0313 out_unlock:
0314 mutex_unlock(&adis->state_lock);
0315 return ret;
0316 }
0317 EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB);
0318
0319
0320
0321
0322
0323
0324
0325 int __adis_check_status(struct adis *adis)
0326 {
0327 u16 status;
0328 int ret;
0329 int i;
0330
0331 ret = __adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
0332 if (ret)
0333 return ret;
0334
0335 status &= adis->data->status_error_mask;
0336
0337 if (status == 0)
0338 return 0;
0339
0340 for (i = 0; i < 16; ++i) {
0341 if (status & BIT(i)) {
0342 dev_err(&adis->spi->dev, "%s.\n",
0343 adis->data->status_error_msgs[i]);
0344 }
0345 }
0346
0347 return -EIO;
0348 }
0349 EXPORT_SYMBOL_NS_GPL(__adis_check_status, IIO_ADISLIB);
0350
0351
0352
0353
0354
0355
0356
0357 int __adis_reset(struct adis *adis)
0358 {
0359 int ret;
0360 const struct adis_timeout *timeouts = adis->data->timeouts;
0361
0362 ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg,
0363 ADIS_GLOB_CMD_SW_RESET);
0364 if (ret) {
0365 dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
0366 return ret;
0367 }
0368
0369 msleep(timeouts->sw_reset_ms);
0370
0371 return 0;
0372 }
0373 EXPORT_SYMBOL_NS_GPL(__adis_reset, IIO_ADIS_LIB);
0374
0375 static int adis_self_test(struct adis *adis)
0376 {
0377 int ret;
0378 const struct adis_timeout *timeouts = adis->data->timeouts;
0379
0380 ret = __adis_write_reg_16(adis, adis->data->self_test_reg,
0381 adis->data->self_test_mask);
0382 if (ret) {
0383 dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
0384 ret);
0385 return ret;
0386 }
0387
0388 msleep(timeouts->self_test_ms);
0389
0390 ret = __adis_check_status(adis);
0391
0392 if (adis->data->self_test_no_autoclear)
0393 __adis_write_reg_16(adis, adis->data->self_test_reg, 0x00);
0394
0395 return ret;
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415 int __adis_initial_startup(struct adis *adis)
0416 {
0417 const struct adis_timeout *timeouts = adis->data->timeouts;
0418 struct gpio_desc *gpio;
0419 u16 prod_id;
0420 int ret;
0421
0422
0423 gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_OUT_HIGH);
0424 if (IS_ERR(gpio))
0425 return PTR_ERR(gpio);
0426
0427 if (gpio) {
0428 usleep_range(10, 12);
0429
0430 gpiod_set_value_cansleep(gpio, 0);
0431 msleep(timeouts->reset_ms);
0432 } else {
0433 ret = __adis_reset(adis);
0434 if (ret)
0435 return ret;
0436 }
0437
0438 ret = adis_self_test(adis);
0439 if (ret)
0440 return ret;
0441
0442
0443
0444
0445
0446
0447 if (!adis->data->unmasked_drdy)
0448 adis_enable_irq(adis, false);
0449
0450 if (!adis->data->prod_id_reg)
0451 return 0;
0452
0453 ret = adis_read_reg_16(adis, adis->data->prod_id_reg, &prod_id);
0454 if (ret)
0455 return ret;
0456
0457 if (prod_id != adis->data->prod_id)
0458 dev_warn(&adis->spi->dev,
0459 "Device ID(%u) and product ID(%u) do not match.\n",
0460 adis->data->prod_id, prod_id);
0461
0462 return 0;
0463 }
0464 EXPORT_SYMBOL_NS_GPL(__adis_initial_startup, IIO_ADISLIB);
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 int adis_single_conversion(struct iio_dev *indio_dev,
0482 const struct iio_chan_spec *chan,
0483 unsigned int error_mask, int *val)
0484 {
0485 struct adis *adis = iio_device_get_drvdata(indio_dev);
0486 unsigned int uval;
0487 int ret;
0488
0489 mutex_lock(&adis->state_lock);
0490
0491 ret = __adis_read_reg(adis, chan->address, &uval,
0492 chan->scan_type.storagebits / 8);
0493 if (ret)
0494 goto err_unlock;
0495
0496 if (uval & error_mask) {
0497 ret = __adis_check_status(adis);
0498 if (ret)
0499 goto err_unlock;
0500 }
0501
0502 if (chan->scan_type.sign == 's')
0503 *val = sign_extend32(uval, chan->scan_type.realbits - 1);
0504 else
0505 *val = uval & ((1 << chan->scan_type.realbits) - 1);
0506
0507 ret = IIO_VAL_INT;
0508 err_unlock:
0509 mutex_unlock(&adis->state_lock);
0510 return ret;
0511 }
0512 EXPORT_SYMBOL_NS_GPL(adis_single_conversion, IIO_ADISLIB);
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526 int adis_init(struct adis *adis, struct iio_dev *indio_dev,
0527 struct spi_device *spi, const struct adis_data *data)
0528 {
0529 if (!data || !data->timeouts) {
0530 dev_err(&spi->dev, "No config data or timeouts not defined!\n");
0531 return -EINVAL;
0532 }
0533
0534 mutex_init(&adis->state_lock);
0535 adis->spi = spi;
0536 adis->data = data;
0537 iio_device_set_drvdata(indio_dev, adis);
0538
0539 if (data->has_paging) {
0540
0541 adis->current_page = -1;
0542 } else {
0543
0544 adis->current_page = 0;
0545 }
0546
0547 return 0;
0548 }
0549 EXPORT_SYMBOL_NS_GPL(adis_init, IIO_ADISLIB);
0550
0551 MODULE_LICENSE("GPL");
0552 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
0553 MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");