adxl355_core.c (18895B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ADXL355 3-Axis Digital Accelerometer IIO core driver 4 * 5 * Copyright (c) 2021 Puranjay Mohan <puranjay12@gmail.com> 6 * 7 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl354_adxl355.pdf 8 */ 9 10#include <linux/bits.h> 11#include <linux/bitfield.h> 12#include <linux/iio/buffer.h> 13#include <linux/iio/iio.h> 14#include <linux/iio/trigger.h> 15#include <linux/iio/triggered_buffer.h> 16#include <linux/iio/trigger_consumer.h> 17#include <linux/limits.h> 18#include <linux/math64.h> 19#include <linux/module.h> 20#include <linux/mod_devicetable.h> 21#include <linux/property.h> 22#include <linux/regmap.h> 23#include <linux/units.h> 24 25#include <asm/unaligned.h> 26 27#include "adxl355.h" 28 29/* ADXL355 Register Definitions */ 30#define ADXL355_DEVID_AD_REG 0x00 31#define ADXL355_DEVID_MST_REG 0x01 32#define ADXL355_PARTID_REG 0x02 33#define ADXL355_STATUS_REG 0x04 34#define ADXL355_FIFO_ENTRIES_REG 0x05 35#define ADXL355_TEMP2_REG 0x06 36#define ADXL355_XDATA3_REG 0x08 37#define ADXL355_YDATA3_REG 0x0B 38#define ADXL355_ZDATA3_REG 0x0E 39#define ADXL355_FIFO_DATA_REG 0x11 40#define ADXL355_OFFSET_X_H_REG 0x1E 41#define ADXL355_OFFSET_Y_H_REG 0x20 42#define ADXL355_OFFSET_Z_H_REG 0x22 43#define ADXL355_ACT_EN_REG 0x24 44#define ADXL355_ACT_THRESH_H_REG 0x25 45#define ADXL355_ACT_THRESH_L_REG 0x26 46#define ADXL355_ACT_COUNT_REG 0x27 47#define ADXL355_FILTER_REG 0x28 48#define ADXL355_FILTER_ODR_MSK GENMASK(3, 0) 49#define ADXL355_FILTER_HPF_MSK GENMASK(6, 4) 50#define ADXL355_FIFO_SAMPLES_REG 0x29 51#define ADXL355_INT_MAP_REG 0x2A 52#define ADXL355_SYNC_REG 0x2B 53#define ADXL355_RANGE_REG 0x2C 54#define ADXL355_POWER_CTL_REG 0x2D 55#define ADXL355_POWER_CTL_MODE_MSK GENMASK(1, 0) 56#define ADXL355_POWER_CTL_DRDY_MSK BIT(2) 57#define ADXL355_SELF_TEST_REG 0x2E 58#define ADXL355_RESET_REG 0x2F 59 60#define ADXL355_DEVID_AD_VAL 0xAD 61#define ADXL355_DEVID_MST_VAL 0x1D 62#define ADXL355_PARTID_VAL 0xED 63#define ADXL355_RESET_CODE 0x52 64 65static const struct regmap_range adxl355_read_reg_range[] = { 66 regmap_reg_range(ADXL355_DEVID_AD_REG, ADXL355_FIFO_DATA_REG), 67 regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_SELF_TEST_REG), 68}; 69 70const struct regmap_access_table adxl355_readable_regs_tbl = { 71 .yes_ranges = adxl355_read_reg_range, 72 .n_yes_ranges = ARRAY_SIZE(adxl355_read_reg_range), 73}; 74EXPORT_SYMBOL_NS_GPL(adxl355_readable_regs_tbl, IIO_ADXL355); 75 76static const struct regmap_range adxl355_write_reg_range[] = { 77 regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_RESET_REG), 78}; 79 80const struct regmap_access_table adxl355_writeable_regs_tbl = { 81 .yes_ranges = adxl355_write_reg_range, 82 .n_yes_ranges = ARRAY_SIZE(adxl355_write_reg_range), 83}; 84EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355); 85 86enum adxl355_op_mode { 87 ADXL355_MEASUREMENT, 88 ADXL355_STANDBY, 89 ADXL355_TEMP_OFF, 90}; 91 92enum adxl355_odr { 93 ADXL355_ODR_4000HZ, 94 ADXL355_ODR_2000HZ, 95 ADXL355_ODR_1000HZ, 96 ADXL355_ODR_500HZ, 97 ADXL355_ODR_250HZ, 98 ADXL355_ODR_125HZ, 99 ADXL355_ODR_62_5HZ, 100 ADXL355_ODR_31_25HZ, 101 ADXL355_ODR_15_625HZ, 102 ADXL355_ODR_7_813HZ, 103 ADXL355_ODR_3_906HZ, 104}; 105 106enum adxl355_hpf_3db { 107 ADXL355_HPF_OFF, 108 ADXL355_HPF_24_7, 109 ADXL355_HPF_6_2084, 110 ADXL355_HPF_1_5545, 111 ADXL355_HPF_0_3862, 112 ADXL355_HPF_0_0954, 113 ADXL355_HPF_0_0238, 114}; 115 116static const int adxl355_odr_table[][2] = { 117 [0] = {4000, 0}, 118 [1] = {2000, 0}, 119 [2] = {1000, 0}, 120 [3] = {500, 0}, 121 [4] = {250, 0}, 122 [5] = {125, 0}, 123 [6] = {62, 500000}, 124 [7] = {31, 250000}, 125 [8] = {15, 625000}, 126 [9] = {7, 813000}, 127 [10] = {3, 906000}, 128}; 129 130static const int adxl355_hpf_3db_multipliers[] = { 131 0, 132 247000, 133 62084, 134 15545, 135 3862, 136 954, 137 238, 138}; 139 140enum adxl355_chans { 141 chan_x, chan_y, chan_z, 142}; 143 144struct adxl355_chan_info { 145 u8 data_reg; 146 u8 offset_reg; 147}; 148 149static const struct adxl355_chan_info adxl355_chans[] = { 150 [chan_x] = { 151 .data_reg = ADXL355_XDATA3_REG, 152 .offset_reg = ADXL355_OFFSET_X_H_REG 153 }, 154 [chan_y] = { 155 .data_reg = ADXL355_YDATA3_REG, 156 .offset_reg = ADXL355_OFFSET_Y_H_REG 157 }, 158 [chan_z] = { 159 .data_reg = ADXL355_ZDATA3_REG, 160 .offset_reg = ADXL355_OFFSET_Z_H_REG 161 }, 162}; 163 164struct adxl355_data { 165 struct regmap *regmap; 166 struct device *dev; 167 struct mutex lock; /* lock to protect op_mode */ 168 enum adxl355_op_mode op_mode; 169 enum adxl355_odr odr; 170 enum adxl355_hpf_3db hpf_3db; 171 int calibbias[3]; 172 int adxl355_hpf_3db_table[7][2]; 173 struct iio_trigger *dready_trig; 174 union { 175 u8 transf_buf[3]; 176 struct { 177 u8 buf[14]; 178 s64 ts; 179 } buffer; 180 } ____cacheline_aligned; 181}; 182 183static int adxl355_set_op_mode(struct adxl355_data *data, 184 enum adxl355_op_mode op_mode) 185{ 186 int ret; 187 188 if (data->op_mode == op_mode) 189 return 0; 190 191 ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG, 192 ADXL355_POWER_CTL_MODE_MSK, op_mode); 193 if (ret) 194 return ret; 195 196 data->op_mode = op_mode; 197 198 return ret; 199} 200 201static int adxl355_data_rdy_trigger_set_state(struct iio_trigger *trig, 202 bool state) 203{ 204 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 205 struct adxl355_data *data = iio_priv(indio_dev); 206 int ret; 207 208 mutex_lock(&data->lock); 209 ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG, 210 ADXL355_POWER_CTL_DRDY_MSK, 211 FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 212 state ? 0 : 1)); 213 mutex_unlock(&data->lock); 214 215 return ret; 216} 217 218static void adxl355_fill_3db_frequency_table(struct adxl355_data *data) 219{ 220 u32 multiplier; 221 u64 div, rem; 222 u64 odr; 223 int i; 224 225 odr = mul_u64_u32_shr(adxl355_odr_table[data->odr][0], MEGA, 0) + 226 adxl355_odr_table[data->odr][1]; 227 228 for (i = 0; i < ARRAY_SIZE(adxl355_hpf_3db_multipliers); i++) { 229 multiplier = adxl355_hpf_3db_multipliers[i]; 230 div = div64_u64_rem(mul_u64_u32_shr(odr, multiplier, 0), 231 TERA * 100, &rem); 232 233 data->adxl355_hpf_3db_table[i][0] = div; 234 data->adxl355_hpf_3db_table[i][1] = div_u64(rem, MEGA * 100); 235 } 236} 237 238static int adxl355_setup(struct adxl355_data *data) 239{ 240 unsigned int regval; 241 int ret; 242 243 ret = regmap_read(data->regmap, ADXL355_DEVID_AD_REG, ®val); 244 if (ret) 245 return ret; 246 247 if (regval != ADXL355_DEVID_AD_VAL) { 248 dev_err(data->dev, "Invalid ADI ID 0x%02x\n", regval); 249 return -ENODEV; 250 } 251 252 ret = regmap_read(data->regmap, ADXL355_DEVID_MST_REG, ®val); 253 if (ret) 254 return ret; 255 256 if (regval != ADXL355_DEVID_MST_VAL) { 257 dev_err(data->dev, "Invalid MEMS ID 0x%02x\n", regval); 258 return -ENODEV; 259 } 260 261 ret = regmap_read(data->regmap, ADXL355_PARTID_REG, ®val); 262 if (ret) 263 return ret; 264 265 if (regval != ADXL355_PARTID_VAL) { 266 dev_err(data->dev, "Invalid DEV ID 0x%02x\n", regval); 267 return -ENODEV; 268 } 269 270 /* 271 * Perform a software reset to make sure the device is in a consistent 272 * state after start-up. 273 */ 274 ret = regmap_write(data->regmap, ADXL355_RESET_REG, ADXL355_RESET_CODE); 275 if (ret) 276 return ret; 277 278 ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG, 279 ADXL355_POWER_CTL_DRDY_MSK, 280 FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 1)); 281 if (ret) 282 return ret; 283 284 adxl355_fill_3db_frequency_table(data); 285 286 return adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 287} 288 289static int adxl355_get_temp_data(struct adxl355_data *data, u8 addr) 290{ 291 return regmap_bulk_read(data->regmap, addr, data->transf_buf, 2); 292} 293 294static int adxl355_read_axis(struct adxl355_data *data, u8 addr) 295{ 296 int ret; 297 298 ret = regmap_bulk_read(data->regmap, addr, data->transf_buf, 299 ARRAY_SIZE(data->transf_buf)); 300 if (ret) 301 return ret; 302 303 return get_unaligned_be24(data->transf_buf); 304} 305 306static int adxl355_find_match(const int (*freq_tbl)[2], const int n, 307 const int val, const int val2) 308{ 309 int i; 310 311 for (i = 0; i < n; i++) { 312 if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2) 313 return i; 314 } 315 316 return -EINVAL; 317} 318 319static int adxl355_set_odr(struct adxl355_data *data, 320 enum adxl355_odr odr) 321{ 322 int ret; 323 324 mutex_lock(&data->lock); 325 326 if (data->odr == odr) { 327 mutex_unlock(&data->lock); 328 return 0; 329 } 330 331 ret = adxl355_set_op_mode(data, ADXL355_STANDBY); 332 if (ret) 333 goto err_unlock; 334 335 ret = regmap_update_bits(data->regmap, ADXL355_FILTER_REG, 336 ADXL355_FILTER_ODR_MSK, 337 FIELD_PREP(ADXL355_FILTER_ODR_MSK, odr)); 338 if (ret) 339 goto err_set_opmode; 340 341 data->odr = odr; 342 adxl355_fill_3db_frequency_table(data); 343 344 ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 345 if (ret) 346 goto err_set_opmode; 347 348 mutex_unlock(&data->lock); 349 return 0; 350 351err_set_opmode: 352 adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 353err_unlock: 354 mutex_unlock(&data->lock); 355 return ret; 356} 357 358static int adxl355_set_hpf_3db(struct adxl355_data *data, 359 enum adxl355_hpf_3db hpf) 360{ 361 int ret; 362 363 mutex_lock(&data->lock); 364 365 if (data->hpf_3db == hpf) { 366 mutex_unlock(&data->lock); 367 return 0; 368 } 369 370 ret = adxl355_set_op_mode(data, ADXL355_STANDBY); 371 if (ret) 372 goto err_unlock; 373 374 ret = regmap_update_bits(data->regmap, ADXL355_FILTER_REG, 375 ADXL355_FILTER_HPF_MSK, 376 FIELD_PREP(ADXL355_FILTER_HPF_MSK, hpf)); 377 if (ret) 378 goto err_set_opmode; 379 380 data->hpf_3db = hpf; 381 382 ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 383 if (ret) 384 goto err_set_opmode; 385 386 mutex_unlock(&data->lock); 387 return 0; 388 389err_set_opmode: 390 adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 391err_unlock: 392 mutex_unlock(&data->lock); 393 return ret; 394} 395 396static int adxl355_set_calibbias(struct adxl355_data *data, 397 enum adxl355_chans chan, int calibbias) 398{ 399 int ret; 400 401 mutex_lock(&data->lock); 402 403 ret = adxl355_set_op_mode(data, ADXL355_STANDBY); 404 if (ret) 405 goto err_unlock; 406 407 put_unaligned_be16(calibbias, data->transf_buf); 408 ret = regmap_bulk_write(data->regmap, 409 adxl355_chans[chan].offset_reg, 410 data->transf_buf, 2); 411 if (ret) 412 goto err_set_opmode; 413 414 data->calibbias[chan] = calibbias; 415 416 ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 417 if (ret) 418 goto err_set_opmode; 419 420 mutex_unlock(&data->lock); 421 return 0; 422 423err_set_opmode: 424 adxl355_set_op_mode(data, ADXL355_MEASUREMENT); 425err_unlock: 426 mutex_unlock(&data->lock); 427 return ret; 428} 429 430static int adxl355_read_raw(struct iio_dev *indio_dev, 431 struct iio_chan_spec const *chan, 432 int *val, int *val2, long mask) 433{ 434 struct adxl355_data *data = iio_priv(indio_dev); 435 int ret; 436 437 switch (mask) { 438 case IIO_CHAN_INFO_RAW: 439 switch (chan->type) { 440 case IIO_TEMP: 441 ret = adxl355_get_temp_data(data, chan->address); 442 if (ret < 0) 443 return ret; 444 *val = get_unaligned_be16(data->transf_buf); 445 446 return IIO_VAL_INT; 447 case IIO_ACCEL: 448 ret = adxl355_read_axis(data, adxl355_chans[ 449 chan->address].data_reg); 450 if (ret < 0) 451 return ret; 452 *val = sign_extend32(ret >> chan->scan_type.shift, 453 chan->scan_type.realbits - 1); 454 return IIO_VAL_INT; 455 default: 456 return -EINVAL; 457 } 458 459 case IIO_CHAN_INFO_SCALE: 460 switch (chan->type) { 461 /* 462 * The datasheet defines an intercept of 1885 LSB at 25 degC 463 * and a slope of -9.05 LSB/C. The following formula can be used 464 * to find the temperature: 465 * Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow 466 * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. 467 * Hence using some rearranging we get the scale as -110.497238 468 * and offset as -2111.25. 469 */ 470 case IIO_TEMP: 471 *val = -110; 472 *val2 = 497238; 473 return IIO_VAL_INT_PLUS_MICRO; 474 /* 475 * At +/- 2g with 20-bit resolution, scale is given in datasheet 476 * as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2. 477 */ 478 case IIO_ACCEL: 479 *val = 0; 480 *val2 = 38245; 481 return IIO_VAL_INT_PLUS_NANO; 482 default: 483 return -EINVAL; 484 } 485 case IIO_CHAN_INFO_OFFSET: 486 *val = -2111; 487 *val2 = 250000; 488 return IIO_VAL_INT_PLUS_MICRO; 489 case IIO_CHAN_INFO_CALIBBIAS: 490 *val = sign_extend32(data->calibbias[chan->address], 15); 491 return IIO_VAL_INT; 492 case IIO_CHAN_INFO_SAMP_FREQ: 493 *val = adxl355_odr_table[data->odr][0]; 494 *val2 = adxl355_odr_table[data->odr][1]; 495 return IIO_VAL_INT_PLUS_MICRO; 496 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 497 *val = data->adxl355_hpf_3db_table[data->hpf_3db][0]; 498 *val2 = data->adxl355_hpf_3db_table[data->hpf_3db][1]; 499 return IIO_VAL_INT_PLUS_MICRO; 500 default: 501 return -EINVAL; 502 } 503} 504 505static int adxl355_write_raw(struct iio_dev *indio_dev, 506 struct iio_chan_spec const *chan, 507 int val, int val2, long mask) 508{ 509 struct adxl355_data *data = iio_priv(indio_dev); 510 int odr_idx, hpf_idx, calibbias; 511 512 switch (mask) { 513 case IIO_CHAN_INFO_SAMP_FREQ: 514 odr_idx = adxl355_find_match(adxl355_odr_table, 515 ARRAY_SIZE(adxl355_odr_table), 516 val, val2); 517 if (odr_idx < 0) 518 return odr_idx; 519 520 return adxl355_set_odr(data, odr_idx); 521 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 522 hpf_idx = adxl355_find_match(data->adxl355_hpf_3db_table, 523 ARRAY_SIZE(data->adxl355_hpf_3db_table), 524 val, val2); 525 if (hpf_idx < 0) 526 return hpf_idx; 527 528 return adxl355_set_hpf_3db(data, hpf_idx); 529 case IIO_CHAN_INFO_CALIBBIAS: 530 calibbias = clamp_t(int, val, S16_MIN, S16_MAX); 531 532 return adxl355_set_calibbias(data, chan->address, calibbias); 533 default: 534 return -EINVAL; 535 } 536} 537 538static int adxl355_read_avail(struct iio_dev *indio_dev, 539 struct iio_chan_spec const *chan, 540 const int **vals, int *type, int *length, 541 long mask) 542{ 543 struct adxl355_data *data = iio_priv(indio_dev); 544 545 switch (mask) { 546 case IIO_CHAN_INFO_SAMP_FREQ: 547 *vals = (const int *)adxl355_odr_table; 548 *type = IIO_VAL_INT_PLUS_MICRO; 549 /* Values are stored in a 2D matrix */ 550 *length = ARRAY_SIZE(adxl355_odr_table) * 2; 551 552 return IIO_AVAIL_LIST; 553 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 554 *vals = (const int *)data->adxl355_hpf_3db_table; 555 *type = IIO_VAL_INT_PLUS_MICRO; 556 /* Values are stored in a 2D matrix */ 557 *length = ARRAY_SIZE(data->adxl355_hpf_3db_table) * 2; 558 559 return IIO_AVAIL_LIST; 560 default: 561 return -EINVAL; 562 } 563} 564 565static const unsigned long adxl355_avail_scan_masks[] = { 566 GENMASK(3, 0), 567 0 568}; 569 570static const struct iio_info adxl355_info = { 571 .read_raw = adxl355_read_raw, 572 .write_raw = adxl355_write_raw, 573 .read_avail = &adxl355_read_avail, 574}; 575 576static const struct iio_trigger_ops adxl355_trigger_ops = { 577 .set_trigger_state = &adxl355_data_rdy_trigger_set_state, 578 .validate_device = &iio_trigger_validate_own_device, 579}; 580 581static irqreturn_t adxl355_trigger_handler(int irq, void *p) 582{ 583 struct iio_poll_func *pf = p; 584 struct iio_dev *indio_dev = pf->indio_dev; 585 struct adxl355_data *data = iio_priv(indio_dev); 586 int ret; 587 588 mutex_lock(&data->lock); 589 590 /* 591 * data->buffer is used both for triggered buffer support 592 * and read/write_raw(), hence, it has to be zeroed here before usage. 593 */ 594 data->buffer.buf[0] = 0; 595 596 /* 597 * The acceleration data is 24 bits and big endian. It has to be saved 598 * in 32 bits, hence, it is saved in the 2nd byte of the 4 byte buffer. 599 * The buf array is 14 bytes as it includes 3x4=12 bytes for 600 * accelaration data of x, y, and z axis. It also includes 2 bytes for 601 * temperature data. 602 */ 603 ret = regmap_bulk_read(data->regmap, ADXL355_XDATA3_REG, 604 &data->buffer.buf[1], 3); 605 if (ret) 606 goto out_unlock_notify; 607 608 ret = regmap_bulk_read(data->regmap, ADXL355_YDATA3_REG, 609 &data->buffer.buf[5], 3); 610 if (ret) 611 goto out_unlock_notify; 612 613 ret = regmap_bulk_read(data->regmap, ADXL355_ZDATA3_REG, 614 &data->buffer.buf[9], 3); 615 if (ret) 616 goto out_unlock_notify; 617 618 ret = regmap_bulk_read(data->regmap, ADXL355_TEMP2_REG, 619 &data->buffer.buf[12], 2); 620 if (ret) 621 goto out_unlock_notify; 622 623 iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, 624 pf->timestamp); 625 626out_unlock_notify: 627 mutex_unlock(&data->lock); 628 iio_trigger_notify_done(indio_dev->trig); 629 630 return IRQ_HANDLED; 631} 632 633#define ADXL355_ACCEL_CHANNEL(index, reg, axis) { \ 634 .type = IIO_ACCEL, \ 635 .address = reg, \ 636 .modified = 1, \ 637 .channel2 = IIO_MOD_##axis, \ 638 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 639 BIT(IIO_CHAN_INFO_CALIBBIAS), \ 640 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 641 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 642 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ 643 .info_mask_shared_by_type_available = \ 644 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 645 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ 646 .scan_index = index, \ 647 .scan_type = { \ 648 .sign = 's', \ 649 .realbits = 20, \ 650 .storagebits = 32, \ 651 .shift = 4, \ 652 .endianness = IIO_BE, \ 653 } \ 654} 655 656static const struct iio_chan_spec adxl355_channels[] = { 657 ADXL355_ACCEL_CHANNEL(0, chan_x, X), 658 ADXL355_ACCEL_CHANNEL(1, chan_y, Y), 659 ADXL355_ACCEL_CHANNEL(2, chan_z, Z), 660 { 661 .type = IIO_TEMP, 662 .address = ADXL355_TEMP2_REG, 663 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 664 BIT(IIO_CHAN_INFO_SCALE) | 665 BIT(IIO_CHAN_INFO_OFFSET), 666 .scan_index = 3, 667 .scan_type = { 668 .sign = 's', 669 .realbits = 12, 670 .storagebits = 16, 671 .endianness = IIO_BE, 672 }, 673 }, 674 IIO_CHAN_SOFT_TIMESTAMP(4), 675}; 676 677static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq) 678{ 679 struct adxl355_data *data = iio_priv(indio_dev); 680 int ret; 681 682 data->dready_trig = devm_iio_trigger_alloc(data->dev, "%s-dev%d", 683 indio_dev->name, 684 iio_device_id(indio_dev)); 685 if (!data->dready_trig) 686 return -ENOMEM; 687 688 data->dready_trig->ops = &adxl355_trigger_ops; 689 iio_trigger_set_drvdata(data->dready_trig, indio_dev); 690 691 ret = devm_request_irq(data->dev, irq, 692 &iio_trigger_generic_data_rdy_poll, 693 IRQF_ONESHOT, "adxl355_irq", data->dready_trig); 694 if (ret) 695 return dev_err_probe(data->dev, ret, "request irq %d failed\n", 696 irq); 697 698 ret = devm_iio_trigger_register(data->dev, data->dready_trig); 699 if (ret) { 700 dev_err(data->dev, "iio trigger register failed\n"); 701 return ret; 702 } 703 704 indio_dev->trig = iio_trigger_get(data->dready_trig); 705 706 return 0; 707} 708 709int adxl355_core_probe(struct device *dev, struct regmap *regmap, 710 const char *name) 711{ 712 struct adxl355_data *data; 713 struct iio_dev *indio_dev; 714 int ret; 715 int irq; 716 717 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 718 if (!indio_dev) 719 return -ENOMEM; 720 721 data = iio_priv(indio_dev); 722 data->regmap = regmap; 723 data->dev = dev; 724 data->op_mode = ADXL355_STANDBY; 725 mutex_init(&data->lock); 726 727 indio_dev->name = name; 728 indio_dev->info = &adxl355_info; 729 indio_dev->modes = INDIO_DIRECT_MODE; 730 indio_dev->channels = adxl355_channels; 731 indio_dev->num_channels = ARRAY_SIZE(adxl355_channels); 732 indio_dev->available_scan_masks = adxl355_avail_scan_masks; 733 734 ret = adxl355_setup(data); 735 if (ret) { 736 dev_err(dev, "ADXL355 setup failed\n"); 737 return ret; 738 } 739 740 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 741 &iio_pollfunc_store_time, 742 &adxl355_trigger_handler, NULL); 743 if (ret) { 744 dev_err(dev, "iio triggered buffer setup failed\n"); 745 return ret; 746 } 747 748 irq = fwnode_irq_get_byname(dev_fwnode(dev), "DRDY"); 749 if (irq > 0) { 750 ret = adxl355_probe_trigger(indio_dev, irq); 751 if (ret) 752 return ret; 753 } 754 755 return devm_iio_device_register(dev, indio_dev); 756} 757EXPORT_SYMBOL_NS_GPL(adxl355_core_probe, IIO_ADXL355); 758 759MODULE_AUTHOR("Puranjay Mohan <puranjay12@gmail.com>"); 760MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer core driver"); 761MODULE_LICENSE("GPL v2");