FILE
adxl380.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/accel/adxl380.c
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * ADXL380 3-Axis Digital Accelerometer core driver 4 * 5 * Copyright 2024 Analog Devices Inc. 6 */ 7 8#include <linux/bitfield.h> 9#include <linux/interrupt.h> 10#include <linux/irq.h> 11#include <linux/module.h> 12#include <linux/property.h> 13#include <linux/regmap.h> 14#include <linux/units.h> 15 16#include <linux/unaligned.h> 17 18#include <linux/iio/buffer.h> 19#include <linux/iio/events.h> 20#include <linux/iio/iio.h> 21#include <linux/iio/kfifo_buf.h> 22#include <linux/iio/sysfs.h> 23 24#include <linux/regulator/consumer.h> 25 26#include "adxl380.h" 27 28#define ADXL380_ID_VAL 380 29#define ADXL318_ID_VAL 380 30#define ADXL382_ID_VAL 382 31#define ADXL319_ID_VAL 382 32 33#define ADXL380_DEVID_AD_REG 0x00 34#define ADLX380_PART_ID_REG 0x02 35 36#define ADXL380_X_DATA_H_REG 0x15 37#define ADXL380_Y_DATA_H_REG 0x17 38#define ADXL380_Z_DATA_H_REG 0x19 39#define ADXL380_T_DATA_H_REG 0x1B 40 41#define ADXL380_MISC_0_REG 0x20 42#define ADXL380_XL382_MSK BIT(7) 43 44#define ADXL380_MISC_1_REG 0x21 45 46#define ADXL380_X_DSM_OFFSET_REG 0x4D 47 48#define ADXL380_ACT_INACT_CTL_REG 0x37 49#define ADXL380_INACT_EN_MSK BIT(2) 50#define ADXL380_ACT_EN_MSK BIT(0) 51 52#define ADXL380_SNSR_AXIS_EN_REG 0x38 53#define ADXL380_ACT_INACT_AXIS_EN_MSK GENMASK(2, 0) 54 55#define ADXL380_THRESH_ACT_H_REG 0x39 56#define ADXL380_TIME_ACT_H_REG 0x3B 57#define ADXL380_THRESH_INACT_H_REG 0x3E 58#define ADXL380_TIME_INACT_H_REG 0x40 59#define ADXL380_THRESH_MAX GENMASK(12, 0) 60#define ADXL380_TIME_MAX GENMASK(24, 0) 61 62#define ADXL380_FIFO_CONFIG_0_REG 0x30 63#define ADXL380_FIFO_SAMPLES_8_MSK BIT(0) 64#define ADXL380_FIFO_MODE_MSK GENMASK(5, 4) 65 66#define ADXL380_FIFO_DISABLED 0 67#define ADXL380_FIFO_NORMAL 1 68#define ADXL380_FIFO_STREAMED 2 69#define ADXL380_FIFO_TRIGGERED 3 70 71#define ADXL380_FIFO_CONFIG_1_REG 0x31 72#define ADXL380_FIFO_STATUS_0_REG 0x1E 73 74#define ADXL380_TAP_THRESH_REG 0x43 75#define ADXL380_TAP_DUR_REG 0x44 76#define ADXL380_TAP_LATENT_REG 0x45 77#define ADXL380_TAP_WINDOW_REG 0x46 78#define ADXL380_TAP_TIME_MAX GENMASK(7, 0) 79 80#define ADXL380_TAP_CFG_REG 0x47 81#define ADXL380_TAP_AXIS_MSK GENMASK(1, 0) 82 83#define ADXL380_TRIG_CFG_REG 0x49 84#define ADXL380_TRIG_CFG_DEC_2X_MSK BIT(7) 85#define ADXL380_TRIG_CFG_SINC_RATE_MSK BIT(6) 86 87#define ADXL380_FILTER_REG 0x50 88#define ADXL380_FILTER_EQ_FILT_MSK BIT(6) 89#define ADXL380_FILTER_LPF_MODE_MSK GENMASK(5, 4) 90#define ADXL380_FILTER_HPF_PATH_MSK BIT(3) 91#define ADXL380_FILTER_HPF_CORNER_MSK GENMASK(2, 0) 92 93#define ADXL380_OP_MODE_REG 0x26 94#define ADXL380_OP_MODE_RANGE_MSK GENMASK(7, 6) 95#define ADXL380_OP_MODE_MSK GENMASK(3, 0) 96#define ADXL380_OP_MODE_STANDBY 0 97#define ADXL380_OP_MODE_HEART_SOUND 1 98#define ADXL380_OP_MODE_ULP 2 99#define ADXL380_OP_MODE_VLP 3 100#define ADXL380_OP_MODE_LP 4 101#define ADXL380_OP_MODE_LP_ULP 6 102#define ADXL380_OP_MODE_LP_VLP 7 103#define ADXL380_OP_MODE_RBW 8 104#define ADXL380_OP_MODE_RBW_ULP 10 105#define ADXL380_OP_MODE_RBW_VLP 11 106#define ADXL380_OP_MODE_HP 12 107#define ADXL380_OP_MODE_HP_ULP 14 108#define ADXL380_OP_MODE_HP_VLP 15 109 110#define ADXL380_OP_MODE_4G_RANGE 0 111#define ADXL382_OP_MODE_15G_RANGE 0 112#define ADXL380_OP_MODE_8G_RANGE 1 113#define ADXL382_OP_MODE_30G_RANGE 1 114#define ADXL380_OP_MODE_16G_RANGE 2 115#define ADXL382_OP_MODE_60G_RANGE 2 116 117#define ADXL380_DIG_EN_REG 0x27 118#define ADXL380_CHAN_EN_MSK(chan) BIT(4 + (chan)) 119#define ADXL380_FIFO_EN_MSK BIT(3) 120 121#define ADXL380_INT0_MAP0_REG 0x2B 122#define ADXL380_INT1_MAP0_REG 0x2D 123#define ADXL380_INT_MAP0_INACT_INT0_MSK BIT(6) 124#define ADXL380_INT_MAP0_ACT_INT0_MSK BIT(5) 125#define ADXL380_INT_MAP0_FIFO_WM_INT0_MSK BIT(3) 126 127#define ADXL380_INT0_MAP1_REG 0x2C 128#define ADXL380_INT1_MAP1_REG 0x2E 129#define ADXL380_INT_MAP1_DOUBLE_TAP_INT0_MSK BIT(1) 130#define ADXL380_INT_MAP1_SINGLE_TAP_INT0_MSK BIT(0) 131 132#define ADXL380_INT0_REG 0x5D 133#define ADXL380_INT0_POL_MSK BIT(7) 134 135#define ADXL380_RESET_REG 0x2A 136#define ADXL380_FIFO_DATA 0x1D 137 138#define ADXL380_DEVID_AD_VAL 0xAD 139#define ADXL380_RESET_CODE 0x52 140 141#define ADXL380_STATUS_0_REG 0x11 142#define ADXL380_STATUS_0_FIFO_FULL_MSK BIT(1) 143#define ADXL380_STATUS_0_FIFO_WM_MSK BIT(3) 144 145#define ADXL380_STATUS_1_INACT_MSK BIT(6) 146#define ADXL380_STATUS_1_ACT_MSK BIT(5) 147#define ADXL380_STATUS_1_DOUBLE_TAP_MSK BIT(1) 148#define ADXL380_STATUS_1_SINGLE_TAP_MSK BIT(0) 149 150#define ADXL380_FIFO_SAMPLES 315UL 151 152enum adxl380_channels { 153 ADXL380_ACCEL_X, 154 ADXL380_ACCEL_Y, 155 ADXL380_ACCEL_Z, 156 ADXL380_TEMP, 157 ADXL380_CH_NUM 158}; 159 160enum adxl380_axis { 161 ADXL380_X_AXIS, 162 ADXL380_Y_AXIS, 163 ADXL380_Z_AXIS, 164}; 165 166enum adxl380_activity_type { 167 ADXL380_ACTIVITY, 168 ADXL380_INACTIVITY, 169}; 170 171enum adxl380_tap_type { 172 ADXL380_SINGLE_TAP, 173 ADXL380_DOUBLE_TAP, 174}; 175 176enum adxl380_tap_time_type { 177 ADXL380_TAP_TIME_LATENT, 178 ADXL380_TAP_TIME_WINDOW, 179}; 180 181static const int adxl380_range_scale_factor_tbl[] = { 1, 2, 4 }; 182 183static const unsigned int adxl380_th_reg_high_addr[2] = { 184 [ADXL380_ACTIVITY] = ADXL380_THRESH_ACT_H_REG, 185 [ADXL380_INACTIVITY] = ADXL380_THRESH_INACT_H_REG, 186}; 187 188static const unsigned int adxl380_time_reg_high_addr[2] = { 189 [ADXL380_ACTIVITY] = ADXL380_TIME_ACT_H_REG, 190 [ADXL380_INACTIVITY] = ADXL380_TIME_INACT_H_REG, 191}; 192 193static const unsigned int adxl380_tap_time_reg[2] = { 194 [ADXL380_TAP_TIME_LATENT] = ADXL380_TAP_LATENT_REG, 195 [ADXL380_TAP_TIME_WINDOW] = ADXL380_TAP_WINDOW_REG, 196}; 197 198struct adxl380_state { 199 struct regmap *regmap; 200 struct device *dev; 201 const struct adxl380_chip_info *chip_info; 202 /* 203 * Synchronize access to members of driver state, and ensure atomicity 204 * of consecutive regmap operations. 205 */ 206 struct mutex lock; 207 enum adxl380_axis tap_axis_en; 208 u8 range; 209 u8 odr; 210 u8 fifo_set_size; 211 u8 transf_buf[3]; 212 u16 watermark; 213 u32 act_time_ms; 214 u32 act_threshold; 215 u32 inact_time_ms; 216 u32 inact_threshold; 217 u32 tap_latent_us; 218 u32 tap_window_us; 219 u32 tap_duration_us; 220 u32 tap_threshold; 221 int irq; 222 int int_map[2]; 223 int lpf_tbl[4]; 224 int hpf_tbl[7][2]; 225 226 __be16 fifo_buf[ADXL380_FIFO_SAMPLES] __aligned(IIO_DMA_MINALIGN); 227}; 228 229bool adxl380_readable_noinc_reg(struct device *dev, unsigned int reg) 230{ 231 return reg == ADXL380_FIFO_DATA; 232} 233EXPORT_SYMBOL_NS_GPL(adxl380_readable_noinc_reg, "IIO_ADXL380"); 234 235static int adxl380_set_measure_en(struct adxl380_state *st, bool en) 236{ 237 int ret; 238 unsigned int act_inact_ctl; 239 u8 op_mode = ADXL380_OP_MODE_STANDBY; 240 241 if (en) { 242 ret = regmap_read(st->regmap, ADXL380_ACT_INACT_CTL_REG, &act_inact_ctl); 243 if (ret) 244 return ret; 245 246 /* 247 * Activity/Inactivity detection available only in VLP/ULP 248 * mode and for devices that support low power modes. Otherwise 249 * go straight to measure mode (same bits as ADXL380_OP_MODE_HP). 250 */ 251 if (st->chip_info->has_low_power && 252 (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || 253 FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl))) 254 op_mode = ADXL380_OP_MODE_VLP; 255 else 256 op_mode = ADXL380_OP_MODE_HP; 257 } 258 259 return regmap_update_bits(st->regmap, ADXL380_OP_MODE_REG, 260 ADXL380_OP_MODE_MSK, 261 FIELD_PREP(ADXL380_OP_MODE_MSK, op_mode)); 262} 263 264static void adxl380_scale_act_inact_thresholds(struct adxl380_state *st, 265 u8 old_range, 266 u8 new_range) 267{ 268 st->act_threshold = mult_frac(st->act_threshold, 269 adxl380_range_scale_factor_tbl[old_range], 270 adxl380_range_scale_factor_tbl[new_range]); 271 st->inact_threshold = mult_frac(st->inact_threshold, 272 adxl380_range_scale_factor_tbl[old_range], 273 adxl380_range_scale_factor_tbl[new_range]); 274} 275 276static int adxl380_write_act_inact_threshold(struct adxl380_state *st, 277 enum adxl380_activity_type act, 278 unsigned int th) 279{ 280 int ret; 281 u8 reg = adxl380_th_reg_high_addr[act]; 282 283 if (th > ADXL380_THRESH_MAX) 284 return -EINVAL; 285 286 ret = regmap_write(st->regmap, reg + 1, th & GENMASK(7, 0)); 287 if (ret) 288 return ret; 289 290 ret = regmap_update_bits(st->regmap, reg, GENMASK(2, 0), th >> 8); 291 if (ret) 292 return ret; 293 294 if (act == ADXL380_ACTIVITY) 295 st->act_threshold = th; 296 else 297 st->inact_threshold = th; 298 299 return 0; 300} 301 302static int adxl380_set_act_inact_threshold(struct iio_dev *indio_dev, 303 enum adxl380_activity_type act, 304 u16 th) 305{ 306 struct adxl380_state *st = iio_priv(indio_dev); 307 int ret; 308 309 guard(mutex)(&st->lock); 310 311 ret = adxl380_set_measure_en(st, false); 312 if (ret) 313 return ret; 314 315 ret = adxl380_write_act_inact_threshold(st, act, th); 316 if (ret) 317 return ret; 318 319 return adxl380_set_measure_en(st, true); 320} 321 322static int adxl380_set_tap_threshold_value(struct iio_dev *indio_dev, u8 th) 323{ 324 int ret; 325 struct adxl380_state *st = iio_priv(indio_dev); 326 327 guard(mutex)(&st->lock); 328 329 ret = adxl380_set_measure_en(st, false); 330 if (ret) 331 return ret; 332 333 ret = regmap_write(st->regmap, ADXL380_TAP_THRESH_REG, th); 334 if (ret) 335 return ret; 336 337 st->tap_threshold = th; 338 339 return adxl380_set_measure_en(st, true); 340} 341 342static int _adxl380_write_tap_time_us(struct adxl380_state *st, 343 enum adxl380_tap_time_type tap_time_type, 344 u32 us) 345{ 346 u8 reg = adxl380_tap_time_reg[tap_time_type]; 347 unsigned int reg_val; 348 int ret; 349 350 /* scale factor for tap window is 1250us / LSB */ 351 reg_val = DIV_ROUND_CLOSEST(us, 1250); 352 if (reg_val > ADXL380_TAP_TIME_MAX) 353 reg_val = ADXL380_TAP_TIME_MAX; 354 355 ret = regmap_write(st->regmap, reg, reg_val); 356 if (ret) 357 return ret; 358 359 if (tap_time_type == ADXL380_TAP_TIME_WINDOW) 360 st->tap_window_us = us; 361 else 362 st->tap_latent_us = us; 363 364 return 0; 365} 366 367static int adxl380_write_tap_time_us(struct adxl380_state *st, 368 enum adxl380_tap_time_type tap_time_type, u32 us) 369{ 370 int ret; 371 372 guard(mutex)(&st->lock); 373 374 ret = adxl380_set_measure_en(st, false); 375 if (ret) 376 return ret; 377 378 ret = _adxl380_write_tap_time_us(st, tap_time_type, us); 379 if (ret) 380 return ret; 381 382 return adxl380_set_measure_en(st, true); 383} 384 385static int adxl380_write_tap_dur_us(struct iio_dev *indio_dev, u32 us) 386{ 387 int ret; 388 unsigned int reg_val; 389 struct adxl380_state *st = iio_priv(indio_dev); 390 391 /* 625us per code is the scale factor of TAP_DUR register */ 392 reg_val = DIV_ROUND_CLOSEST(us, 625); 393 394 ret = adxl380_set_measure_en(st, false); 395 if (ret) 396 return ret; 397 398 ret = regmap_write(st->regmap, ADXL380_TAP_DUR_REG, reg_val); 399 if (ret) 400 return ret; 401 402 return adxl380_set_measure_en(st, true); 403} 404 405static int adxl380_read_chn(struct adxl380_state *st, u8 addr) 406{ 407 int ret; 408 409 guard(mutex)(&st->lock); 410 411 ret = regmap_bulk_read(st->regmap, addr, &st->transf_buf, 2); 412 if (ret) 413 return ret; 414 415 return get_unaligned_be16(st->transf_buf); 416} 417 418static int adxl380_get_odr(struct adxl380_state *st, int *odr) 419{ 420 int ret; 421 unsigned int trig_cfg, odr_idx; 422 423 ret = regmap_read(st->regmap, ADXL380_TRIG_CFG_REG, &trig_cfg); 424 if (ret) 425 return ret; 426 427 odr_idx = (FIELD_GET(ADXL380_TRIG_CFG_SINC_RATE_MSK, trig_cfg) << 1) | 428 (FIELD_GET(ADXL380_TRIG_CFG_DEC_2X_MSK, trig_cfg) & 1); 429 430 *odr = st->chip_info->samp_freq_tbl[odr_idx]; 431 432 return 0; 433} 434 435static const int adxl380_lpf_div[] = { 436 1, 4, 8, 16, 437}; 438 439static int adxl380_fill_lpf_tbl(struct adxl380_state *st) 440{ 441 int ret, i; 442 int odr; 443 444 ret = adxl380_get_odr(st, &odr); 445 if (ret) 446 return ret; 447 448 for (i = 0; i < ARRAY_SIZE(st->lpf_tbl); i++) 449 st->lpf_tbl[i] = DIV_ROUND_CLOSEST(odr, adxl380_lpf_div[i]); 450 451 return 0; 452} 453 454static const int adxl380_hpf_mul[] = { 455 0, 247000, 62084, 15545, 3862, 954, 238, 456}; 457 458static int adxl380_fill_hpf_tbl(struct adxl380_state *st) 459{ 460 int i, ret, odr_hz; 461 u32 multiplier; 462 u64 div, rem, odr; 463 464 ret = adxl380_get_odr(st, &odr_hz); 465 if (ret) 466 return ret; 467 468 for (i = 0; i < ARRAY_SIZE(adxl380_hpf_mul); i++) { 469 odr = mul_u64_u32_shr(odr_hz, MEGA, 0); 470 multiplier = adxl380_hpf_mul[i]; 471 div = div64_u64_rem(mul_u64_u32_shr(odr, multiplier, 0), 472 TERA * 100, &rem); 473 474 st->hpf_tbl[i][0] = div; 475 st->hpf_tbl[i][1] = div_u64(rem, MEGA * 100); 476 } 477 478 return 0; 479} 480 481static int adxl380_set_odr(struct adxl380_state *st, u8 odr) 482{ 483 int ret; 484 485 guard(mutex)(&st->lock); 486 487 ret = adxl380_set_measure_en(st, false); 488 if (ret) 489 return ret; 490 491 ret = regmap_update_bits(st->regmap, ADXL380_TRIG_CFG_REG, 492 ADXL380_TRIG_CFG_DEC_2X_MSK, 493 FIELD_PREP(ADXL380_TRIG_CFG_DEC_2X_MSK, odr & 1)); 494 if (ret) 495 return ret; 496 497 ret = regmap_update_bits(st->regmap, ADXL380_TRIG_CFG_REG, 498 ADXL380_TRIG_CFG_SINC_RATE_MSK, 499 FIELD_PREP(ADXL380_TRIG_CFG_SINC_RATE_MSK, odr >> 1)); 500 if (ret) 501 return ret; 502 503 ret = adxl380_set_measure_en(st, true); 504 if (ret) 505 return ret; 506 507 ret = adxl380_fill_lpf_tbl(st); 508 if (ret) 509 return ret; 510 511 return adxl380_fill_hpf_tbl(st); 512} 513 514static int adxl380_find_match_1d_tbl(const int *array, unsigned int size, 515 int val) 516{ 517 int i; 518 519 for (i = 0; i < size; i++) { 520 if (val == array[i]) 521 return i; 522 } 523 524 return size - 1; 525} 526 527static int adxl380_find_match_2d_tbl(const int (*freq_tbl)[2], int n, int val, int val2) 528{ 529 int i; 530 531 for (i = 0; i < n; i++) { 532 if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2) 533 return i; 534 } 535 536 return -EINVAL; 537} 538 539static int adxl380_get_lpf(struct adxl380_state *st, int *lpf) 540{ 541 int ret; 542 unsigned int trig_cfg, lpf_idx; 543 544 guard(mutex)(&st->lock); 545 546 ret = regmap_read(st->regmap, ADXL380_FILTER_REG, &trig_cfg); 547 if (ret) 548 return ret; 549 550 lpf_idx = FIELD_GET(ADXL380_FILTER_LPF_MODE_MSK, trig_cfg); 551 552 *lpf = st->lpf_tbl[lpf_idx]; 553 554 return 0; 555} 556 557static int adxl380_set_lpf(struct adxl380_state *st, u8 lpf) 558{ 559 int ret; 560 u8 eq_bypass = 0; 561 562 guard(mutex)(&st->lock); 563 564 ret = adxl380_set_measure_en(st, false); 565 if (ret) 566 return ret; 567 568 if (lpf) 569 eq_bypass = 1; 570 571 ret = regmap_update_bits(st->regmap, ADXL380_FILTER_REG, 572 ADXL380_FILTER_EQ_FILT_MSK, 573 FIELD_PREP(ADXL380_FILTER_EQ_FILT_MSK, eq_bypass)); 574 if (ret) 575 return ret; 576 577 ret = regmap_update_bits(st->regmap, ADXL380_FILTER_REG, 578 ADXL380_FILTER_LPF_MODE_MSK, 579 FIELD_PREP(ADXL380_FILTER_LPF_MODE_MSK, lpf)); 580 if (ret) 581 return ret; 582 583 return adxl380_set_measure_en(st, true); 584} 585 586static int adxl380_get_hpf(struct adxl380_state *st, int *hpf_int, int *hpf_frac) 587{ 588 int ret; 589 unsigned int trig_cfg, hpf_idx; 590 591 guard(mutex)(&st->lock); 592 593 ret = regmap_read(st->regmap, ADXL380_FILTER_REG, &trig_cfg); 594 if (ret) 595 return ret; 596 597 hpf_idx = FIELD_GET(ADXL380_FILTER_HPF_CORNER_MSK, trig_cfg); 598 599 *hpf_int = st->hpf_tbl[hpf_idx][0]; 600 *hpf_frac = st->hpf_tbl[hpf_idx][1]; 601 602 return 0; 603} 604 605static int adxl380_set_hpf(struct adxl380_state *st, u8 hpf) 606{ 607 int ret; 608 u8 hpf_path = 0; 609 610 guard(mutex)(&st->lock); 611 612 ret = adxl380_set_measure_en(st, false); 613 if (ret) 614 return ret; 615 616 if (hpf) 617 hpf_path = 1; 618 619 ret = regmap_update_bits(st->regmap, ADXL380_FILTER_REG, 620 ADXL380_FILTER_HPF_PATH_MSK, 621 FIELD_PREP(ADXL380_FILTER_HPF_PATH_MSK, hpf_path)); 622 if (ret) 623 return ret; 624 625 ret = regmap_update_bits(st->regmap, ADXL380_FILTER_REG, 626 ADXL380_FILTER_HPF_CORNER_MSK, 627 FIELD_PREP(ADXL380_FILTER_HPF_CORNER_MSK, hpf)); 628 if (ret) 629 return ret; 630 631 return adxl380_set_measure_en(st, true); 632} 633 634static int _adxl380_set_act_inact_time_ms(struct adxl380_state *st, 635 enum adxl380_activity_type act, 636 u32 ms) 637{ 638 u8 reg = adxl380_time_reg_high_addr[act]; 639 unsigned int reg_val; 640 int ret; 641 642 /* 500us per code is the scale factor of TIME_ACT / TIME_INACT registers */ 643 reg_val = min(DIV_ROUND_CLOSEST(ms * 1000, 500), ADXL380_TIME_MAX); 644 645 put_unaligned_be24(reg_val, &st->transf_buf[0]); 646 647 ret = regmap_bulk_write(st->regmap, reg, st->transf_buf, sizeof(st->transf_buf)); 648 if (ret) 649 return ret; 650 651 if (act == ADXL380_ACTIVITY) 652 st->act_time_ms = ms; 653 else 654 st->inact_time_ms = ms; 655 656 return 0; 657} 658 659static int adxl380_set_act_inact_time_ms(struct adxl380_state *st, 660 enum adxl380_activity_type act, 661 u32 ms) 662{ 663 int ret; 664 665 guard(mutex)(&st->lock); 666 667 ret = adxl380_set_measure_en(st, false); 668 if (ret) 669 return ret; 670 671 ret = _adxl380_set_act_inact_time_ms(st, act, ms); 672 if (ret) 673 return ret; 674 675 return adxl380_set_measure_en(st, true); 676} 677 678static int adxl380_set_range(struct adxl380_state *st, u8 range) 679{ 680 int ret; 681 682 guard(mutex)(&st->lock); 683 684 ret = adxl380_set_measure_en(st, false); 685 if (ret) 686 return ret; 687 688 ret = regmap_update_bits(st->regmap, ADXL380_OP_MODE_REG, 689 ADXL380_OP_MODE_RANGE_MSK, 690 FIELD_PREP(ADXL380_OP_MODE_RANGE_MSK, range)); 691 692 if (ret) 693 return ret; 694 695 adxl380_scale_act_inact_thresholds(st, st->range, range); 696 697 /* Activity thresholds depend on range */ 698 ret = adxl380_write_act_inact_threshold(st, ADXL380_ACTIVITY, 699 st->act_threshold); 700 if (ret) 701 return ret; 702 703 ret = adxl380_write_act_inact_threshold(st, ADXL380_INACTIVITY, 704 st->inact_threshold); 705 if (ret) 706 return ret; 707 708 st->range = range; 709 710 return adxl380_set_measure_en(st, true); 711} 712 713static int adxl380_write_act_inact_en(struct adxl380_state *st, 714 enum adxl380_activity_type type, 715 bool en) 716{ 717 if (type == ADXL380_ACTIVITY) 718 return regmap_update_bits(st->regmap, ADXL380_ACT_INACT_CTL_REG, 719 ADXL380_ACT_EN_MSK, 720 FIELD_PREP(ADXL380_ACT_EN_MSK, en)); 721 722 return regmap_update_bits(st->regmap, ADXL380_ACT_INACT_CTL_REG, 723 ADXL380_INACT_EN_MSK, 724 FIELD_PREP(ADXL380_INACT_EN_MSK, en)); 725} 726 727static int adxl380_read_act_inact_int(struct adxl380_state *st, 728 enum adxl380_activity_type type, 729 bool *en) 730{ 731 int ret; 732 unsigned int reg_val; 733 734 guard(mutex)(&st->lock); 735 736 ret = regmap_read(st->regmap, st->int_map[0], ®_val); 737 if (ret) 738 return ret; 739 740 if (type == ADXL380_ACTIVITY) 741 *en = FIELD_GET(ADXL380_INT_MAP0_ACT_INT0_MSK, reg_val); 742 else 743 *en = FIELD_GET(ADXL380_INT_MAP0_INACT_INT0_MSK, reg_val); 744 745 return 0; 746} 747 748static int adxl380_write_act_inact_int(struct adxl380_state *st, 749 enum adxl380_activity_type act, 750 bool en) 751{ 752 if (act == ADXL380_ACTIVITY) 753 return regmap_update_bits(st->regmap, st->int_map[0], 754 ADXL380_INT_MAP0_ACT_INT0_MSK, 755 FIELD_PREP(ADXL380_INT_MAP0_ACT_INT0_MSK, en)); 756 757 return regmap_update_bits(st->regmap, st->int_map[0], 758 ADXL380_INT_MAP0_INACT_INT0_MSK, 759 FIELD_PREP(ADXL380_INT_MAP0_INACT_INT0_MSK, en)); 760} 761 762static int adxl380_act_inact_config(struct adxl380_state *st, 763 enum adxl380_activity_type type, 764 bool en) 765{ 766 int ret; 767 768 guard(mutex)(&st->lock); 769 770 ret = adxl380_set_measure_en(st, false); 771 if (ret) 772 return ret; 773 774 ret = adxl380_write_act_inact_en(st, type, en); 775 if (ret) 776 return ret; 777 778 ret = adxl380_write_act_inact_int(st, type, en); 779 if (ret) 780 return ret; 781 782 return adxl380_set_measure_en(st, true); 783} 784 785static int adxl380_write_tap_axis(struct adxl380_state *st, 786 enum adxl380_axis axis) 787{ 788 int ret; 789 790 ret = regmap_update_bits(st->regmap, ADXL380_TAP_CFG_REG, 791 ADXL380_TAP_AXIS_MSK, 792 FIELD_PREP(ADXL380_TAP_AXIS_MSK, axis)); 793 794 if (ret) 795 return ret; 796 797 st->tap_axis_en = axis; 798 799 return 0; 800} 801 802static int adxl380_read_tap_int(struct adxl380_state *st, enum adxl380_tap_type type, bool *en) 803{ 804 int ret; 805 unsigned int reg_val; 806 807 ret = regmap_read(st->regmap, st->int_map[1], ®_val); 808 if (ret) 809 return ret; 810 811 if (type == ADXL380_SINGLE_TAP) 812 *en = FIELD_GET(ADXL380_INT_MAP1_SINGLE_TAP_INT0_MSK, reg_val); 813 else 814 *en = FIELD_GET(ADXL380_INT_MAP1_DOUBLE_TAP_INT0_MSK, reg_val); 815 816 return 0; 817} 818 819static int adxl380_write_tap_int(struct adxl380_state *st, enum adxl380_tap_type type, bool en) 820{ 821 if (type == ADXL380_SINGLE_TAP) 822 return regmap_update_bits(st->regmap, st->int_map[1], 823 ADXL380_INT_MAP1_SINGLE_TAP_INT0_MSK, 824 FIELD_PREP(ADXL380_INT_MAP1_SINGLE_TAP_INT0_MSK, en)); 825 826 return regmap_update_bits(st->regmap, st->int_map[1], 827 ADXL380_INT_MAP1_DOUBLE_TAP_INT0_MSK, 828 FIELD_PREP(ADXL380_INT_MAP1_DOUBLE_TAP_INT0_MSK, en)); 829} 830 831static int adxl380_tap_config(struct adxl380_state *st, 832 enum adxl380_axis axis, 833 enum adxl380_tap_type type, 834 bool en) 835{ 836 int ret; 837 838 guard(mutex)(&st->lock); 839 840 ret = adxl380_set_measure_en(st, false); 841 if (ret) 842 return ret; 843 844 ret = adxl380_write_tap_axis(st, axis); 845 if (ret) 846 return ret; 847 848 ret = adxl380_write_tap_int(st, type, en); 849 if (ret) 850 return ret; 851 852 return adxl380_set_measure_en(st, true); 853} 854 855static int adxl380_set_fifo_samples(struct adxl380_state *st) 856{ 857 int ret; 858 u16 fifo_samples = st->watermark * st->fifo_set_size; 859 860 ret = regmap_update_bits(st->regmap, ADXL380_FIFO_CONFIG_0_REG, 861 ADXL380_FIFO_SAMPLES_8_MSK, 862 FIELD_PREP(ADXL380_FIFO_SAMPLES_8_MSK, 863 !!(fifo_samples & BIT(8)))); 864 if (ret) 865 return ret; 866 867 return regmap_write(st->regmap, ADXL380_FIFO_CONFIG_1_REG, 868 fifo_samples & 0xFF); 869} 870 871static int adxl380_get_status(struct adxl380_state *st, u8 *status0, u8 *status1) 872{ 873 int ret; 874 875 /* STATUS0, STATUS1 are adjacent regs */ 876 ret = regmap_bulk_read(st->regmap, ADXL380_STATUS_0_REG, 877 &st->transf_buf, 2); 878 if (ret) 879 return ret; 880 881 *status0 = st->transf_buf[0]; 882 *status1 = st->transf_buf[1]; 883 884 return 0; 885} 886 887static int adxl380_get_fifo_entries(struct adxl380_state *st, u16 *fifo_entries) 888{ 889 int ret; 890 891 ret = regmap_bulk_read(st->regmap, ADXL380_FIFO_STATUS_0_REG, 892 &st->transf_buf, 2); 893 if (ret) 894 return ret; 895 896 *fifo_entries = st->transf_buf[0] | ((BIT(0) & st->transf_buf[1]) << 8); 897 898 return 0; 899} 900 901static void adxl380_push_event(struct iio_dev *indio_dev, s64 timestamp, 902 u8 status1) 903{ 904 if (FIELD_GET(ADXL380_STATUS_1_ACT_MSK, status1)) 905 iio_push_event(indio_dev, 906 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, 907 IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 908 timestamp); 909 910 if (FIELD_GET(ADXL380_STATUS_1_INACT_MSK, status1)) 911 iio_push_event(indio_dev, 912 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, 913 IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), 914 timestamp); 915 if (FIELD_GET(ADXL380_STATUS_1_SINGLE_TAP_MSK, status1)) 916 iio_push_event(indio_dev, 917 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, 918 IIO_EV_TYPE_GESTURE, IIO_EV_DIR_SINGLETAP), 919 timestamp); 920 921 if (FIELD_GET(ADXL380_STATUS_1_DOUBLE_TAP_MSK, status1)) 922 iio_push_event(indio_dev, 923 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, 924 IIO_EV_TYPE_GESTURE, IIO_EV_DIR_DOUBLETAP), 925 timestamp); 926} 927 928static irqreturn_t adxl380_irq_handler(int irq, void *p) 929{ 930 struct iio_dev *indio_dev = p; 931 struct adxl380_state *st = iio_priv(indio_dev); 932 u8 status0, status1; 933 u16 fifo_entries; 934 int i; 935 int ret; 936 937 guard(mutex)(&st->lock); 938 939 ret = adxl380_get_status(st, &status0, &status1); 940 if (ret) 941 return IRQ_HANDLED; 942 943 adxl380_push_event(indio_dev, iio_get_time_ns(indio_dev), status1); 944 945 if (!FIELD_GET(ADXL380_STATUS_0_FIFO_WM_MSK, status0)) 946 return IRQ_HANDLED; 947 948 ret = adxl380_get_fifo_entries(st, &fifo_entries); 949 if (ret) 950 return IRQ_HANDLED; 951 952 fifo_entries = rounddown(fifo_entries, st->fifo_set_size); 953 for (i = 0; i < fifo_entries; i += st->fifo_set_size) { 954 ret = regmap_noinc_read(st->regmap, ADXL380_FIFO_DATA, 955 &st->fifo_buf[i], 956 2 * st->fifo_set_size); 957 if (ret) 958 return IRQ_HANDLED; 959 iio_push_to_buffers(indio_dev, &st->fifo_buf[i]); 960 } 961 962 return IRQ_HANDLED; 963} 964 965static int adxl380_write_calibbias_value(struct adxl380_state *st, 966 unsigned long chan_addr, 967 s8 calibbias) 968{ 969 int ret; 970 971 guard(mutex)(&st->lock); 972 973 ret = adxl380_set_measure_en(st, false); 974 if (ret) 975 return ret; 976 977 ret = regmap_write(st->regmap, ADXL380_X_DSM_OFFSET_REG + chan_addr, calibbias); 978 if (ret) 979 return ret; 980 981 return adxl380_set_measure_en(st, true); 982} 983 984static int adxl380_read_calibbias_value(struct adxl380_state *st, 985 unsigned long chan_addr, 986 int *calibbias) 987{ 988 int ret; 989 unsigned int reg_val; 990 991 guard(mutex)(&st->lock); 992 993 ret = regmap_read(st->regmap, ADXL380_X_DSM_OFFSET_REG + chan_addr, ®_val); 994 if (ret) 995 return ret; 996 997 *calibbias = sign_extend32(reg_val, 7); 998 999 return 0; 1000} 1001 1002static ssize_t hwfifo_watermark_min_show(struct device *dev, 1003 struct device_attribute *attr, 1004 char *buf) 1005{ 1006 return sysfs_emit(buf, "1\n"); 1007} 1008 1009static ssize_t hwfifo_watermark_max_show(struct device *dev, 1010 struct device_attribute *attr, 1011 char *buf) 1012{ 1013 return sysfs_emit(buf, "%lu\n", ADXL380_FIFO_SAMPLES); 1014} 1015 1016static ssize_t adxl380_get_fifo_watermark(struct device *dev, 1017 struct device_attribute *attr, 1018 char *buf) 1019{ 1020 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1021 struct adxl380_state *st = iio_priv(indio_dev); 1022 1023 return sysfs_emit(buf, "%d\n", st->watermark); 1024} 1025 1026static ssize_t adxl380_get_fifo_enabled(struct device *dev, 1027 struct device_attribute *attr, 1028 char *buf) 1029{ 1030 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1031 struct adxl380_state *st = iio_priv(indio_dev); 1032 int ret; 1033 unsigned int reg_val; 1034 1035 ret = regmap_read(st->regmap, ADXL380_DIG_EN_REG, ®_val); 1036 if (ret) 1037 return ret; 1038 1039 return sysfs_emit(buf, "%lu\n", 1040 FIELD_GET(ADXL380_FIFO_EN_MSK, reg_val)); 1041} 1042 1043static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); 1044static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); 1045static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, 1046 adxl380_get_fifo_watermark, NULL, 0); 1047static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, 1048 adxl380_get_fifo_enabled, NULL, 0); 1049 1050static const struct iio_dev_attr *adxl380_fifo_attributes[] = { 1051 &iio_dev_attr_hwfifo_watermark_min, 1052 &iio_dev_attr_hwfifo_watermark_max, 1053 &iio_dev_attr_hwfifo_watermark, 1054 &iio_dev_attr_hwfifo_enabled, 1055 NULL 1056}; 1057 1058static int adxl380_buffer_postenable(struct iio_dev *indio_dev) 1059{ 1060 struct adxl380_state *st = iio_priv(indio_dev); 1061 int i; 1062 int ret; 1063 1064 guard(mutex)(&st->lock); 1065 1066 ret = adxl380_set_measure_en(st, false); 1067 if (ret) 1068 return ret; 1069 1070 ret = regmap_update_bits(st->regmap, 1071 st->int_map[0], 1072 ADXL380_INT_MAP0_FIFO_WM_INT0_MSK, 1073 FIELD_PREP(ADXL380_INT_MAP0_FIFO_WM_INT0_MSK, 1)); 1074 if (ret) 1075 return ret; 1076 1077 for_each_clear_bit(i, indio_dev->active_scan_mask, ADXL380_CH_NUM) { 1078 ret = regmap_update_bits(st->regmap, ADXL380_DIG_EN_REG, 1079 ADXL380_CHAN_EN_MSK(i), 1080 0 << (4 + i)); 1081 if (ret) 1082 return ret; 1083 } 1084 1085 st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, 1086 iio_get_masklength(indio_dev)); 1087 1088 if ((st->watermark * st->fifo_set_size) > ADXL380_FIFO_SAMPLES) 1089 st->watermark = (ADXL380_FIFO_SAMPLES / st->fifo_set_size); 1090 1091 ret = adxl380_set_fifo_samples(st); 1092 if (ret) 1093 return ret; 1094 1095 ret = regmap_update_bits(st->regmap, ADXL380_DIG_EN_REG, ADXL380_FIFO_EN_MSK, 1096 FIELD_PREP(ADXL380_FIFO_EN_MSK, 1)); 1097 if (ret) 1098 return ret; 1099 1100 return adxl380_set_measure_en(st, true); 1101} 1102 1103static int adxl380_buffer_predisable(struct iio_dev *indio_dev) 1104{ 1105 struct adxl380_state *st = iio_priv(indio_dev); 1106 int ret, i; 1107 1108 guard(mutex)(&st->lock); 1109 1110 ret = adxl380_set_measure_en(st, false); 1111 if (ret) 1112 return ret; 1113 1114 ret = regmap_update_bits(st->regmap, 1115 st->int_map[0], 1116 ADXL380_INT_MAP0_FIFO_WM_INT0_MSK, 1117 FIELD_PREP(ADXL380_INT_MAP0_FIFO_WM_INT0_MSK, 0)); 1118 if (ret) 1119 return ret; 1120 1121 for (i = 0; i < indio_dev->num_channels; i++) { 1122 ret = regmap_update_bits(st->regmap, ADXL380_DIG_EN_REG, 1123 ADXL380_CHAN_EN_MSK(i), 1124 1 << (4 + i)); 1125 if (ret) 1126 return ret; 1127 } 1128 1129 ret = regmap_update_bits(st->regmap, ADXL380_DIG_EN_REG, ADXL380_FIFO_EN_MSK, 1130 FIELD_PREP(ADXL380_FIFO_EN_MSK, 0)); 1131 if (ret) 1132 return ret; 1133 1134 return adxl380_set_measure_en(st, true); 1135} 1136 1137static const struct iio_buffer_setup_ops adxl380_buffer_ops = { 1138 .postenable = adxl380_buffer_postenable, 1139 .predisable = adxl380_buffer_predisable, 1140}; 1141 1142static int adxl380_read_raw(struct iio_dev *indio_dev, 1143 struct iio_chan_spec const *chan, 1144 int *val, int *val2, long info) 1145{ 1146 struct adxl380_state *st = iio_priv(indio_dev); 1147 int ret; 1148 1149 switch (info) { 1150 case IIO_CHAN_INFO_RAW: 1151 if (!iio_device_claim_direct(indio_dev)) 1152 return -EBUSY; 1153 1154 ret = adxl380_read_chn(st, chan->address); 1155 iio_device_release_direct(indio_dev); 1156 if (ret < 0) 1157 return ret; 1158 1159 *val = sign_extend32(ret >> chan->scan_type.shift, 1160 chan->scan_type.realbits - 1); 1161 return IIO_VAL_INT; 1162 case IIO_CHAN_INFO_SCALE: 1163 switch (chan->type) { 1164 case IIO_ACCEL: 1165 scoped_guard(mutex, &st->lock) { 1166 *val = st->chip_info->scale_tbl[st->range][0]; 1167 *val2 = st->chip_info->scale_tbl[st->range][1]; 1168 } 1169 return IIO_VAL_INT_PLUS_NANO; 1170 case IIO_TEMP: 1171 /* 10.2 LSB / Degree Celsius */ 1172 *val = 10000; 1173 *val2 = 102; 1174 return IIO_VAL_FRACTIONAL; 1175 default: 1176 return -EINVAL; 1177 } 1178 case IIO_CHAN_INFO_OFFSET: 1179 switch (chan->type) { 1180 case IIO_TEMP: 1181 *val = st->chip_info->temp_offset; 1182 return IIO_VAL_INT; 1183 default: 1184 return -EINVAL; 1185 } 1186 case IIO_CHAN_INFO_CALIBBIAS: 1187 switch (chan->type) { 1188 case IIO_ACCEL: 1189 ret = adxl380_read_calibbias_value(st, chan->scan_index, val); 1190 if (ret) 1191 return ret; 1192 return IIO_VAL_INT; 1193 default: 1194 return -EINVAL; 1195 } 1196 case IIO_CHAN_INFO_SAMP_FREQ: 1197 ret = adxl380_get_odr(st, val); 1198 if (ret) 1199 return ret; 1200 return IIO_VAL_INT; 1201 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 1202 ret = adxl380_get_lpf(st, val); 1203 if (ret) 1204 return ret; 1205 return IIO_VAL_INT; 1206 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 1207 ret = adxl380_get_hpf(st, val, val2); 1208 if (ret) 1209 return ret; 1210 return IIO_VAL_INT_PLUS_MICRO; 1211 } 1212 1213 return -EINVAL; 1214} 1215 1216static int adxl380_read_avail(struct iio_dev *indio_dev, 1217 struct iio_chan_spec const *chan, 1218 const int **vals, int *type, int *length, 1219 long mask) 1220{ 1221 struct adxl380_state *st = iio_priv(indio_dev); 1222 1223 if (chan->type != IIO_ACCEL) 1224 return -EINVAL; 1225 1226 switch (mask) { 1227 case IIO_CHAN_INFO_SCALE: 1228 *vals = (const int *)st->chip_info->scale_tbl; 1229 *type = IIO_VAL_INT_PLUS_NANO; 1230 *length = ARRAY_SIZE(st->chip_info->scale_tbl) * 2; 1231 return IIO_AVAIL_LIST; 1232 case IIO_CHAN_INFO_SAMP_FREQ: 1233 *vals = (const int *)st->chip_info->samp_freq_tbl; 1234 *type = IIO_VAL_INT; 1235 *length = ARRAY_SIZE(st->chip_info->samp_freq_tbl); 1236 return IIO_AVAIL_LIST; 1237 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 1238 *vals = (const int *)st->lpf_tbl; 1239 *type = IIO_VAL_INT; 1240 *length = ARRAY_SIZE(st->lpf_tbl); 1241 return IIO_AVAIL_LIST; 1242 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 1243 *vals = (const int *)st->hpf_tbl; 1244 *type = IIO_VAL_INT_PLUS_MICRO; 1245 /* Values are stored in a 2D matrix */ 1246 *length = ARRAY_SIZE(st->hpf_tbl) * 2; 1247 return IIO_AVAIL_LIST; 1248 default: 1249 return -EINVAL; 1250 } 1251} 1252 1253static int adxl380_write_raw(struct iio_dev *indio_dev, 1254 struct iio_chan_spec const *chan, 1255 int val, int val2, long info) 1256{ 1257 struct adxl380_state *st = iio_priv(indio_dev); 1258 int odr_index, lpf_index, hpf_index, range_index; 1259 1260 switch (info) { 1261 case IIO_CHAN_INFO_SAMP_FREQ: 1262 odr_index = adxl380_find_match_1d_tbl(st->chip_info->samp_freq_tbl, 1263 ARRAY_SIZE(st->chip_info->samp_freq_tbl), 1264 val); 1265 return adxl380_set_odr(st, odr_index); 1266 case IIO_CHAN_INFO_CALIBBIAS: 1267 return adxl380_write_calibbias_value(st, chan->scan_index, val); 1268 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 1269 lpf_index = adxl380_find_match_1d_tbl(st->lpf_tbl, 1270 ARRAY_SIZE(st->lpf_tbl), 1271 val); 1272 return adxl380_set_lpf(st, lpf_index); 1273 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 1274 hpf_index = adxl380_find_match_2d_tbl(st->hpf_tbl, 1275 ARRAY_SIZE(st->hpf_tbl), 1276 val, val2); 1277 if (hpf_index < 0) 1278 return hpf_index; 1279 return adxl380_set_hpf(st, hpf_index); 1280 case IIO_CHAN_INFO_SCALE: 1281 range_index = adxl380_find_match_2d_tbl(st->chip_info->scale_tbl, 1282 ARRAY_SIZE(st->chip_info->scale_tbl), 1283 val, val2); 1284 if (range_index < 0) 1285 return range_index; 1286 return adxl380_set_range(st, range_index); 1287 default: 1288 return -EINVAL; 1289 } 1290} 1291 1292static int adxl380_write_raw_get_fmt(struct iio_dev *indio_dev, 1293 struct iio_chan_spec const *chan, 1294 long info) 1295{ 1296 switch (info) { 1297 case IIO_CHAN_INFO_SCALE: 1298 if (chan->type != IIO_ACCEL) 1299 return -EINVAL; 1300 1301 return IIO_VAL_INT_PLUS_NANO; 1302 default: 1303 return IIO_VAL_INT_PLUS_MICRO; 1304 } 1305} 1306 1307static int adxl380_read_event_config(struct iio_dev *indio_dev, 1308 const struct iio_chan_spec *chan, 1309 enum iio_event_type type, 1310 enum iio_event_direction dir) 1311{ 1312 struct adxl380_state *st = iio_priv(indio_dev); 1313 int ret; 1314 bool int_en; 1315 bool tap_axis_en = false; 1316 1317 switch (chan->channel2) { 1318 case IIO_MOD_X: 1319 tap_axis_en = st->tap_axis_en == ADXL380_X_AXIS; 1320 break; 1321 case IIO_MOD_Y: 1322 tap_axis_en = st->tap_axis_en == ADXL380_Y_AXIS; 1323 break; 1324 case IIO_MOD_Z: 1325 tap_axis_en = st->tap_axis_en == ADXL380_Z_AXIS; 1326 break; 1327 default: 1328 return -EINVAL; 1329 } 1330 1331 switch (dir) { 1332 case IIO_EV_DIR_RISING: 1333 ret = adxl380_read_act_inact_int(st, ADXL380_ACTIVITY, &int_en); 1334 if (ret) 1335 return ret; 1336 return int_en; 1337 case IIO_EV_DIR_FALLING: 1338 ret = adxl380_read_act_inact_int(st, ADXL380_INACTIVITY, &int_en); 1339 if (ret) 1340 return ret; 1341 return int_en; 1342 case IIO_EV_DIR_SINGLETAP: 1343 ret = adxl380_read_tap_int(st, ADXL380_SINGLE_TAP, &int_en); 1344 if (ret) 1345 return ret; 1346 return int_en && tap_axis_en; 1347 case IIO_EV_DIR_DOUBLETAP: 1348 ret = adxl380_read_tap_int(st, ADXL380_DOUBLE_TAP, &int_en); 1349 if (ret) 1350 return ret; 1351 return int_en && tap_axis_en; 1352 default: 1353 return -EINVAL; 1354 } 1355} 1356 1357static int adxl380_write_event_config(struct iio_dev *indio_dev, 1358 const struct iio_chan_spec *chan, 1359 enum iio_event_type type, 1360 enum iio_event_direction dir, 1361 bool state) 1362{ 1363 struct adxl380_state *st = iio_priv(indio_dev); 1364 enum adxl380_axis axis; 1365 1366 switch (chan->channel2) { 1367 case IIO_MOD_X: 1368 axis = ADXL380_X_AXIS; 1369 break; 1370 case IIO_MOD_Y: 1371 axis = ADXL380_Y_AXIS; 1372 break; 1373 case IIO_MOD_Z: 1374 axis = ADXL380_Z_AXIS; 1375 break; 1376 default: 1377 return -EINVAL; 1378 } 1379 1380 switch (dir) { 1381 case IIO_EV_DIR_RISING: 1382 return adxl380_act_inact_config(st, ADXL380_ACTIVITY, state); 1383 case IIO_EV_DIR_FALLING: 1384 return adxl380_act_inact_config(st, ADXL380_INACTIVITY, state); 1385 case IIO_EV_DIR_SINGLETAP: 1386 return adxl380_tap_config(st, axis, ADXL380_SINGLE_TAP, state); 1387 case IIO_EV_DIR_DOUBLETAP: 1388 return adxl380_tap_config(st, axis, ADXL380_DOUBLE_TAP, state); 1389 default: 1390 return -EINVAL; 1391 } 1392} 1393 1394static int adxl380_read_event_value(struct iio_dev *indio_dev, 1395 const struct iio_chan_spec *chan, 1396 enum iio_event_type type, 1397 enum iio_event_direction dir, 1398 enum iio_event_info info, 1399 int *val, int *val2) 1400{ 1401 struct adxl380_state *st = iio_priv(indio_dev); 1402 1403 guard(mutex)(&st->lock); 1404 1405 switch (type) { 1406 case IIO_EV_TYPE_THRESH: 1407 switch (info) { 1408 case IIO_EV_INFO_VALUE: { 1409 switch (dir) { 1410 case IIO_EV_DIR_RISING: 1411 *val = st->act_threshold; 1412 return IIO_VAL_INT; 1413 case IIO_EV_DIR_FALLING: 1414 *val = st->inact_threshold; 1415 return IIO_VAL_INT; 1416 default: 1417 return -EINVAL; 1418 } 1419 } 1420 case IIO_EV_INFO_PERIOD: 1421 switch (dir) { 1422 case IIO_EV_DIR_RISING: 1423 *val = st->act_time_ms; 1424 *val2 = 1000; 1425 return IIO_VAL_FRACTIONAL; 1426 case IIO_EV_DIR_FALLING: 1427 *val = st->inact_time_ms; 1428 *val2 = 1000; 1429 return IIO_VAL_FRACTIONAL; 1430 default: 1431 return -EINVAL; 1432 } 1433 default: 1434 return -EINVAL; 1435 } 1436 case IIO_EV_TYPE_GESTURE: 1437 switch (info) { 1438 case IIO_EV_INFO_VALUE: 1439 *val = st->tap_threshold; 1440 return IIO_VAL_INT; 1441 case IIO_EV_INFO_RESET_TIMEOUT: 1442 *val = st->tap_window_us; 1443 *val2 = 1000000; 1444 return IIO_VAL_FRACTIONAL; 1445 case IIO_EV_INFO_TAP2_MIN_DELAY: 1446 *val = st->tap_latent_us; 1447 *val2 = 1000000; 1448 return IIO_VAL_FRACTIONAL; 1449 default: 1450 return -EINVAL; 1451 } 1452 default: 1453 return -EINVAL; 1454 } 1455} 1456 1457static int adxl380_write_event_value(struct iio_dev *indio_dev, 1458 const struct iio_chan_spec *chan, 1459 enum iio_event_type type, enum iio_event_direction dir, 1460 enum iio_event_info info, int val, int val2) 1461{ 1462 struct adxl380_state *st = iio_priv(indio_dev); 1463 u32 val_ms, val_us; 1464 1465 if (chan->type != IIO_ACCEL) 1466 return -EINVAL; 1467 1468 switch (type) { 1469 case IIO_EV_TYPE_THRESH: 1470 switch (info) { 1471 case IIO_EV_INFO_VALUE: 1472 switch (dir) { 1473 case IIO_EV_DIR_RISING: 1474 return adxl380_set_act_inact_threshold(indio_dev, 1475 ADXL380_ACTIVITY, val); 1476 case IIO_EV_DIR_FALLING: 1477 return adxl380_set_act_inact_threshold(indio_dev, 1478 ADXL380_INACTIVITY, val); 1479 default: 1480 return -EINVAL; 1481 } 1482 case IIO_EV_INFO_PERIOD: 1483 val_ms = val * 1000 + DIV_ROUND_UP(val2, 1000); 1484 switch (dir) { 1485 case IIO_EV_DIR_RISING: 1486 return adxl380_set_act_inact_time_ms(st, 1487 ADXL380_ACTIVITY, val_ms); 1488 case IIO_EV_DIR_FALLING: 1489 return adxl380_set_act_inact_time_ms(st, 1490 ADXL380_INACTIVITY, val_ms); 1491 default: 1492 return -EINVAL; 1493 } 1494 1495 default: 1496 return -EINVAL; 1497 } 1498 case IIO_EV_TYPE_GESTURE: 1499 switch (info) { 1500 case IIO_EV_INFO_VALUE: 1501 return adxl380_set_tap_threshold_value(indio_dev, val); 1502 case IIO_EV_INFO_RESET_TIMEOUT: 1503 val_us = val * 1000000 + val2; 1504 return adxl380_write_tap_time_us(st, 1505 ADXL380_TAP_TIME_WINDOW, 1506 val_us); 1507 case IIO_EV_INFO_TAP2_MIN_DELAY: 1508 val_us = val * 1000000 + val2; 1509 return adxl380_write_tap_time_us(st, 1510 ADXL380_TAP_TIME_LATENT, 1511 val_us); 1512 default: 1513 return -EINVAL; 1514 } 1515 default: 1516 return -EINVAL; 1517 } 1518} 1519 1520static ssize_t in_accel_gesture_tap_maxtomin_time_show(struct device *dev, 1521 struct device_attribute *attr, 1522 char *buf) 1523{ 1524 int vals[2]; 1525 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1526 struct adxl380_state *st = iio_priv(indio_dev); 1527 1528 guard(mutex)(&st->lock); 1529 1530 vals[0] = st->tap_duration_us; 1531 vals[1] = MICRO; 1532 1533 return iio_format_value(buf, IIO_VAL_FRACTIONAL, 2, vals); 1534} 1535 1536static ssize_t in_accel_gesture_tap_maxtomin_time_store(struct device *dev, 1537 struct device_attribute *attr, 1538 const char *buf, size_t len) 1539{ 1540 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1541 struct adxl380_state *st = iio_priv(indio_dev); 1542 int ret, val_int, val_fract_us; 1543 1544 guard(mutex)(&st->lock); 1545 1546 ret = iio_str_to_fixpoint(buf, 100000, &val_int, &val_fract_us); 1547 if (ret) 1548 return ret; 1549 1550 /* maximum value is 255 * 625 us = 0.159375 seconds */ 1551 if (val_int || val_fract_us > 159375 || val_fract_us < 0) 1552 return -EINVAL; 1553 1554 ret = adxl380_write_tap_dur_us(indio_dev, val_fract_us); 1555 if (ret) 1556 return ret; 1557 1558 return len; 1559} 1560 1561static IIO_DEVICE_ATTR_RW(in_accel_gesture_tap_maxtomin_time, 0); 1562 1563static struct attribute *adxl380_event_attributes[] = { 1564 &iio_dev_attr_in_accel_gesture_tap_maxtomin_time.dev_attr.attr, 1565 NULL 1566}; 1567 1568static const struct attribute_group adxl380_event_attribute_group = { 1569 .attrs = adxl380_event_attributes, 1570}; 1571 1572static int adxl380_reg_access(struct iio_dev *indio_dev, 1573 unsigned int reg, 1574 unsigned int writeval, 1575 unsigned int *readval) 1576{ 1577 struct adxl380_state *st = iio_priv(indio_dev); 1578 1579 if (readval) 1580 return regmap_read(st->regmap, reg, readval); 1581 1582 return regmap_write(st->regmap, reg, writeval); 1583} 1584 1585static int adxl380_set_watermark(struct iio_dev *indio_dev, unsigned int val) 1586{ 1587 struct adxl380_state *st = iio_priv(indio_dev); 1588 1589 st->watermark = min(val, ADXL380_FIFO_SAMPLES); 1590 1591 return 0; 1592} 1593 1594static const struct iio_info adxl318_info = { 1595 .read_raw = adxl380_read_raw, 1596 .read_avail = &adxl380_read_avail, 1597 .write_raw = adxl380_write_raw, 1598 .write_raw_get_fmt = adxl380_write_raw_get_fmt, 1599 .debugfs_reg_access = &adxl380_reg_access, 1600 .hwfifo_set_watermark = adxl380_set_watermark, 1601}; 1602 1603static const struct iio_info adxl380_info = { 1604 .read_raw = adxl380_read_raw, 1605 .read_avail = &adxl380_read_avail, 1606 .write_raw = adxl380_write_raw, 1607 .write_raw_get_fmt = adxl380_write_raw_get_fmt, 1608 .read_event_config = adxl380_read_event_config, 1609 .write_event_config = adxl380_write_event_config, 1610 .read_event_value = adxl380_read_event_value, 1611 .write_event_value = adxl380_write_event_value, 1612 .event_attrs = &adxl380_event_attribute_group, 1613 .debugfs_reg_access = &adxl380_reg_access, 1614 .hwfifo_set_watermark = adxl380_set_watermark, 1615}; 1616 1617const struct adxl380_chip_info adxl318_chip_info = { 1618 .name = "adxl318", 1619 .chip_id = ADXL318_ID_VAL, 1620 .scale_tbl = { 1621 [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 1622 [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 1623 [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 1624 }, 1625 .samp_freq_tbl = { 8000, 16000, 32000 }, 1626 /* 1627 * The datasheet defines an intercept of 550 LSB at 25 degC 1628 * and a sensitivity of 10.2 LSB/C. 1629 */ 1630 .temp_offset = 25 * 102 / 10 - 550, 1631 .info = &adxl318_info, 1632}; 1633EXPORT_SYMBOL_NS_GPL(adxl318_chip_info, "IIO_ADXL380"); 1634 1635const struct adxl380_chip_info adxl319_chip_info = { 1636 .name = "adxl319", 1637 .chip_id = ADXL319_ID_VAL, 1638 .scale_tbl = { 1639 [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 1640 [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 1641 [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 1642 }, 1643 .samp_freq_tbl = { 16000, 32000, 64000 }, 1644 /* 1645 * The datasheet defines an intercept of 550 LSB at 25 degC 1646 * and a sensitivity of 10.2 LSB/C. 1647 */ 1648 .temp_offset = 25 * 102 / 10 - 550, 1649 .info = &adxl318_info, 1650}; 1651EXPORT_SYMBOL_NS_GPL(adxl319_chip_info, "IIO_ADXL380"); 1652 1653const struct adxl380_chip_info adxl380_chip_info = { 1654 .name = "adxl380", 1655 .chip_id = ADXL380_ID_VAL, 1656 .scale_tbl = { 1657 [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 1658 [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 1659 [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 1660 }, 1661 .samp_freq_tbl = { 8000, 16000, 32000 }, 1662 /* 1663 * The datasheet defines an intercept of 470 LSB at 25 degC 1664 * and a sensitivity of 10.2 LSB/C. 1665 */ 1666 .temp_offset = 25 * 102 / 10 - 470, 1667 .has_low_power = true, 1668 .info = &adxl380_info, 1669 1670}; 1671EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380"); 1672 1673const struct adxl380_chip_info adxl382_chip_info = { 1674 .name = "adxl382", 1675 .chip_id = ADXL382_ID_VAL, 1676 .scale_tbl = { 1677 [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 1678 [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 1679 [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 1680 }, 1681 .samp_freq_tbl = { 16000, 32000, 64000 }, 1682 /* 1683 * The datasheet defines an intercept of 570 LSB at 25 degC 1684 * and a sensitivity of 10.2 LSB/C. 1685 */ 1686 .temp_offset = 25 * 102 / 10 - 570, 1687 .has_low_power = true, 1688 .info = &adxl380_info, 1689}; 1690EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380"); 1691 1692static const struct iio_event_spec adxl380_events[] = { 1693 { 1694 .type = IIO_EV_TYPE_THRESH, 1695 .dir = IIO_EV_DIR_RISING, 1696 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | 1697 BIT(IIO_EV_INFO_VALUE) | 1698 BIT(IIO_EV_INFO_PERIOD), 1699 }, 1700 { 1701 .type = IIO_EV_TYPE_THRESH, 1702 .dir = IIO_EV_DIR_FALLING, 1703 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | 1704 BIT(IIO_EV_INFO_VALUE) | 1705 BIT(IIO_EV_INFO_PERIOD), 1706 }, 1707 { 1708 .type = IIO_EV_TYPE_GESTURE, 1709 .dir = IIO_EV_DIR_SINGLETAP, 1710 .mask_separate = BIT(IIO_EV_INFO_ENABLE), 1711 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | 1712 BIT(IIO_EV_INFO_RESET_TIMEOUT), 1713 }, 1714 { 1715 .type = IIO_EV_TYPE_GESTURE, 1716 .dir = IIO_EV_DIR_DOUBLETAP, 1717 .mask_separate = BIT(IIO_EV_INFO_ENABLE), 1718 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | 1719 BIT(IIO_EV_INFO_RESET_TIMEOUT) | 1720 BIT(IIO_EV_INFO_TAP2_MIN_DELAY), 1721 }, 1722}; 1723 1724#define ADXL380_ACCEL_CHANNEL(index, reg, axis) { \ 1725 .type = IIO_ACCEL, \ 1726 .address = reg, \ 1727 .modified = 1, \ 1728 .channel2 = IIO_MOD_##axis, \ 1729 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 1730 BIT(IIO_CHAN_INFO_CALIBBIAS), \ 1731 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 1732 .info_mask_shared_by_all_available = \ 1733 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 1734 .info_mask_shared_by_type = \ 1735 BIT(IIO_CHAN_INFO_SCALE) | \ 1736 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ 1737 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ 1738 .info_mask_shared_by_type_available = \ 1739 BIT(IIO_CHAN_INFO_SCALE) | \ 1740 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ 1741 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ 1742 .scan_index = index, \ 1743 .scan_type = { \ 1744 .sign = 's', \ 1745 .realbits = 16, \ 1746 .storagebits = 16, \ 1747 .endianness = IIO_BE, \ 1748 }, \ 1749 .event_spec = adxl380_events, \ 1750 .num_event_specs = ARRAY_SIZE(adxl380_events) \ 1751} 1752 1753static const struct iio_chan_spec adxl380_channels[] = { 1754 ADXL380_ACCEL_CHANNEL(0, ADXL380_X_DATA_H_REG, X), 1755 ADXL380_ACCEL_CHANNEL(1, ADXL380_Y_DATA_H_REG, Y), 1756 ADXL380_ACCEL_CHANNEL(2, ADXL380_Z_DATA_H_REG, Z), 1757 { 1758 .type = IIO_TEMP, 1759 .address = ADXL380_T_DATA_H_REG, 1760 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1761 BIT(IIO_CHAN_INFO_SCALE) | 1762 BIT(IIO_CHAN_INFO_OFFSET), 1763 .scan_index = 3, 1764 .scan_type = { 1765 .sign = 's', 1766 .realbits = 12, 1767 .storagebits = 16, 1768 .shift = 4, 1769 .endianness = IIO_BE, 1770 }, 1771 }, 1772}; 1773 1774static int adxl380_config_irq(struct iio_dev *indio_dev) 1775{ 1776 struct adxl380_state *st = iio_priv(indio_dev); 1777 unsigned long irq_flag; 1778 u32 irq_type; 1779 u8 polarity; 1780 int ret; 1781 1782 st->irq = fwnode_irq_get_byname(dev_fwnode(st->dev), "INT0"); 1783 if (st->irq > 0) { 1784 st->int_map[0] = ADXL380_INT0_MAP0_REG; 1785 st->int_map[1] = ADXL380_INT0_MAP1_REG; 1786 } else { 1787 st->irq = fwnode_irq_get_byname(dev_fwnode(st->dev), "INT1"); 1788 if (st->irq < 0) 1789 return dev_err_probe(st->dev, st->irq, 1790 "no interrupt name specified\n"); 1791 st->int_map[0] = ADXL380_INT1_MAP0_REG; 1792 st->int_map[1] = ADXL380_INT1_MAP1_REG; 1793 } 1794 1795 irq_type = irq_get_trigger_type(st->irq); 1796 if (irq_type == IRQ_TYPE_LEVEL_HIGH) { 1797 polarity = 0; 1798 irq_flag = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; 1799 } else if (irq_type == IRQ_TYPE_LEVEL_LOW) { 1800 polarity = 1; 1801 irq_flag = IRQF_TRIGGER_LOW | IRQF_ONESHOT; 1802 } else { 1803 return dev_err_probe(st->dev, -EINVAL, 1804 "Invalid interrupt 0x%x. Only level interrupts supported\n", 1805 irq_type); 1806 } 1807 1808 ret = regmap_update_bits(st->regmap, ADXL380_INT0_REG, 1809 ADXL380_INT0_POL_MSK, 1810 FIELD_PREP(ADXL380_INT0_POL_MSK, polarity)); 1811 if (ret) 1812 return ret; 1813 1814 return devm_request_threaded_irq(st->dev, st->irq, NULL, 1815 adxl380_irq_handler, irq_flag, 1816 indio_dev->name, indio_dev); 1817} 1818 1819static int adxl380_setup(struct iio_dev *indio_dev) 1820{ 1821 unsigned int reg_val; 1822 u16 part_id, chip_id; 1823 int ret, i; 1824 struct adxl380_state *st = iio_priv(indio_dev); 1825 1826 ret = regmap_read(st->regmap, ADXL380_DEVID_AD_REG, ®_val); 1827 if (ret) 1828 return ret; 1829 1830 if (reg_val != ADXL380_DEVID_AD_VAL) 1831 dev_warn(st->dev, "Unknown chip id %x\n", reg_val); 1832 1833 ret = regmap_bulk_read(st->regmap, ADLX380_PART_ID_REG, 1834 &st->transf_buf, 2); 1835 if (ret) 1836 return ret; 1837 1838 part_id = get_unaligned_be16(st->transf_buf); 1839 part_id >>= 4; 1840 1841 if (part_id != ADXL380_ID_VAL) 1842 dev_warn(st->dev, "Unknown part id %x\n", part_id); 1843 1844 ret = regmap_read(st->regmap, ADXL380_MISC_0_REG, ®_val); 1845 if (ret) 1846 return ret; 1847 1848 /* Bit to differentiate between ADXL380/382. */ 1849 if (reg_val & ADXL380_XL382_MSK) 1850 chip_id = ADXL382_ID_VAL; 1851 else 1852 chip_id = ADXL380_ID_VAL; 1853 1854 if (chip_id != st->chip_info->chip_id) 1855 dev_warn(st->dev, "Unknown chip id %x\n", chip_id); 1856 1857 ret = regmap_write(st->regmap, ADXL380_RESET_REG, ADXL380_RESET_CODE); 1858 if (ret) 1859 return ret; 1860 1861 /* 1862 * A latency of approximately 0.5 ms is required after soft reset. 1863 * Stated in the register REG_RESET description. 1864 */ 1865 fsleep(500); 1866 1867 for (i = 0; i < indio_dev->num_channels; i++) { 1868 ret = regmap_update_bits(st->regmap, ADXL380_DIG_EN_REG, 1869 ADXL380_CHAN_EN_MSK(i), 1870 1 << (4 + i)); 1871 if (ret) 1872 return ret; 1873 } 1874 1875 ret = regmap_update_bits(st->regmap, ADXL380_FIFO_CONFIG_0_REG, 1876 ADXL380_FIFO_MODE_MSK, 1877 FIELD_PREP(ADXL380_FIFO_MODE_MSK, ADXL380_FIFO_STREAMED)); 1878 if (ret) 1879 return ret; 1880 1881 /* Select all 3 axis for act/inact detection. */ 1882 ret = regmap_update_bits(st->regmap, ADXL380_SNSR_AXIS_EN_REG, 1883 ADXL380_ACT_INACT_AXIS_EN_MSK, 1884 FIELD_PREP(ADXL380_ACT_INACT_AXIS_EN_MSK, 1885 ADXL380_ACT_INACT_AXIS_EN_MSK)); 1886 if (ret) 1887 return ret; 1888 1889 ret = adxl380_config_irq(indio_dev); 1890 if (ret) 1891 return ret; 1892 1893 ret = adxl380_fill_lpf_tbl(st); 1894 if (ret) 1895 return ret; 1896 1897 ret = adxl380_fill_hpf_tbl(st); 1898 if (ret) 1899 return ret; 1900 1901 return adxl380_set_measure_en(st, true); 1902} 1903 1904int adxl380_probe(struct device *dev, struct regmap *regmap, 1905 const struct adxl380_chip_info *chip_info) 1906{ 1907 struct iio_dev *indio_dev; 1908 struct adxl380_state *st; 1909 int ret; 1910 1911 indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); 1912 if (!indio_dev) 1913 return -ENOMEM; 1914 1915 st = iio_priv(indio_dev); 1916 1917 st->dev = dev; 1918 st->regmap = regmap; 1919 st->chip_info = chip_info; 1920 1921 mutex_init(&st->lock); 1922 1923 indio_dev->channels = adxl380_channels; 1924 indio_dev->num_channels = ARRAY_SIZE(adxl380_channels); 1925 indio_dev->name = chip_info->name; 1926 indio_dev->info = chip_info->info; 1927 indio_dev->modes = INDIO_DIRECT_MODE; 1928 1929 ret = devm_regulator_get_enable(dev, "vddio"); 1930 if (ret) 1931 return dev_err_probe(st->dev, ret, 1932 "Failed to get vddio regulator\n"); 1933 1934 ret = devm_regulator_get_enable(st->dev, "vsupply"); 1935 if (ret) 1936 return dev_err_probe(st->dev, ret, 1937 "Failed to get vsupply regulator\n"); 1938 1939 ret = adxl380_setup(indio_dev); 1940 if (ret) 1941 return ret; 1942 1943 ret = devm_iio_kfifo_buffer_setup_ext(st->dev, indio_dev, 1944 &adxl380_buffer_ops, 1945 adxl380_fifo_attributes); 1946 if (ret) 1947 return ret; 1948 1949 return devm_iio_device_register(dev, indio_dev); 1950} 1951EXPORT_SYMBOL_NS_GPL(adxl380_probe, "IIO_ADXL380"); 1952 1953MODULE_AUTHOR("Ramona Gradinariu <ramona.gradinariu@analog.com>"); 1954MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>"); 1955MODULE_DESCRIPTION("Analog Devices ADXL380 3-axis accelerometer driver"); 1956MODULE_LICENSE("GPL");
~/
Read-only file preview.