1483 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (C) 2021 Analog Devices, Inc.4 * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>5 */6 7#include <linux/bitfield.h>8#include <linux/bitops.h>9#include <linux/iio/buffer.h>10#include <linux/iio/events.h>11#include <linux/iio/iio.h>12#include <linux/iio/kfifo_buf.h>13#include <linux/iio/sysfs.h>14#include <linux/interrupt.h>15#include <linux/irq.h>16#include <linux/mod_devicetable.h>17#include <linux/regmap.h>18#include <linux/regulator/consumer.h>19#include <linux/unaligned.h>20 21#include "adxl367.h"22 23#define ADXL367_REG_DEVID 0x0024#define ADXL367_DEVID_AD 0xAD25 26#define ADXL367_REG_STATUS 0x0B27#define ADXL367_STATUS_INACT_MASK BIT(5)28#define ADXL367_STATUS_ACT_MASK BIT(4)29#define ADXL367_STATUS_FIFO_FULL_MASK BIT(2)30 31#define ADXL367_FIFO_ENT_H_MASK GENMASK(1, 0)32 33#define ADXL367_REG_X_DATA_H 0x0E34#define ADXL367_REG_Y_DATA_H 0x1035#define ADXL367_REG_Z_DATA_H 0x1236#define ADXL367_REG_TEMP_DATA_H 0x1437#define ADXL367_REG_EX_ADC_DATA_H 0x1638#define ADXL367_DATA_MASK GENMASK(15, 2)39 40#define ADXL367_TEMP_25C 16541#define ADXL367_TEMP_PER_C 5442 43#define ADXL367_VOLTAGE_OFFSET 819244#define ADXL367_VOLTAGE_MAX_MV 100045#define ADXL367_VOLTAGE_MAX_RAW GENMASK(13, 0)46 47#define ADXL367_REG_RESET 0x1F48#define ADXL367_RESET_CODE 0x5249 50#define ADXL367_REG_THRESH_ACT_H 0x2051#define ADXL367_REG_THRESH_INACT_H 0x2352#define ADXL367_THRESH_MAX GENMASK(12, 0)53#define ADXL367_THRESH_VAL_H_MASK GENMASK(12, 6)54#define ADXL367_THRESH_H_MASK GENMASK(6, 0)55#define ADXL367_THRESH_VAL_L_MASK GENMASK(5, 0)56#define ADXL367_THRESH_L_MASK GENMASK(7, 2)57 58#define ADXL367_REG_TIME_ACT 0x2259#define ADXL367_REG_TIME_INACT_H 0x2560#define ADXL367_TIME_ACT_MAX GENMASK(7, 0)61#define ADXL367_TIME_INACT_MAX GENMASK(15, 0)62#define ADXL367_TIME_INACT_VAL_H_MASK GENMASK(15, 8)63#define ADXL367_TIME_INACT_H_MASK GENMASK(7, 0)64#define ADXL367_TIME_INACT_VAL_L_MASK GENMASK(7, 0)65#define ADXL367_TIME_INACT_L_MASK GENMASK(7, 0)66 67#define ADXL367_REG_ACT_INACT_CTL 0x2768#define ADXL367_ACT_EN_MASK GENMASK(1, 0)69#define ADXL367_ACT_LINKLOOP_MASK GENMASK(5, 4)70 71#define ADXL367_REG_FIFO_CTL 0x2872#define ADXL367_FIFO_CTL_FORMAT_MASK GENMASK(6, 3)73#define ADXL367_FIFO_CTL_MODE_MASK GENMASK(1, 0)74 75#define ADXL367_REG_FIFO_SAMPLES 0x2976#define ADXL367_FIFO_SIZE 51277#define ADXL367_FIFO_MAX_WATERMARK 51178 79#define ADXL367_SAMPLES_VAL_H_MASK BIT(8)80#define ADXL367_SAMPLES_H_MASK BIT(2)81#define ADXL367_SAMPLES_VAL_L_MASK GENMASK(7, 0)82#define ADXL367_SAMPLES_L_MASK GENMASK(7, 0)83 84#define ADXL367_REG_INT1_MAP 0x2A85#define ADXL367_INT_INACT_MASK BIT(5)86#define ADXL367_INT_ACT_MASK BIT(4)87#define ADXL367_INT_FIFO_WATERMARK_MASK BIT(2)88 89#define ADXL367_REG_FILTER_CTL 0x2C90#define ADXL367_FILTER_CTL_RANGE_MASK GENMASK(7, 6)91#define ADXL367_2G_RANGE_1G 409592#define ADXL367_2G_RANGE_100MG 40993#define ADXL367_FILTER_CTL_ODR_MASK GENMASK(2, 0)94 95#define ADXL367_REG_POWER_CTL 0x2D96#define ADXL367_POWER_CTL_MODE_MASK GENMASK(1, 0)97 98#define ADXL367_REG_ADC_CTL 0x3C99#define ADXL367_REG_TEMP_CTL 0x3D100#define ADXL367_ADC_EN_MASK BIT(0)101 102enum adxl367_range {103 ADXL367_2G_RANGE,104 ADXL367_4G_RANGE,105 ADXL367_8G_RANGE,106};107 108enum adxl367_fifo_mode {109 ADXL367_FIFO_MODE_DISABLED = 0b00,110 ADXL367_FIFO_MODE_STREAM = 0b10,111};112 113enum adxl367_fifo_format {114 ADXL367_FIFO_FORMAT_XYZ,115 ADXL367_FIFO_FORMAT_X,116 ADXL367_FIFO_FORMAT_Y,117 ADXL367_FIFO_FORMAT_Z,118 ADXL367_FIFO_FORMAT_XYZT,119 ADXL367_FIFO_FORMAT_XT,120 ADXL367_FIFO_FORMAT_YT,121 ADXL367_FIFO_FORMAT_ZT,122 ADXL367_FIFO_FORMAT_XYZA,123 ADXL367_FIFO_FORMAT_XA,124 ADXL367_FIFO_FORMAT_YA,125 ADXL367_FIFO_FORMAT_ZA,126};127 128enum adxl367_op_mode {129 ADXL367_OP_STANDBY = 0b00,130 ADXL367_OP_MEASURE = 0b10,131};132 133enum adxl367_act_proc_mode {134 ADXL367_LOOPED = 0b11,135};136 137enum adxl367_act_en_mode {138 ADXL367_ACT_DISABLED = 0b00,139 ADCL367_ACT_REF_ENABLED = 0b11,140};141 142enum adxl367_activity_type {143 ADXL367_ACTIVITY,144 ADXL367_INACTIVITY,145};146 147enum adxl367_odr {148 ADXL367_ODR_12P5HZ,149 ADXL367_ODR_25HZ,150 ADXL367_ODR_50HZ,151 ADXL367_ODR_100HZ,152 ADXL367_ODR_200HZ,153 ADXL367_ODR_400HZ,154};155 156struct adxl367_state {157 const struct adxl367_ops *ops;158 void *context;159 160 struct device *dev;161 struct regmap *regmap;162 163 /*164 * Synchronize access to members of driver state, and ensure atomicity165 * of consecutive regmap operations.166 */167 struct mutex lock;168 169 enum adxl367_odr odr;170 enum adxl367_range range;171 172 unsigned int act_threshold;173 unsigned int act_time_ms;174 unsigned int inact_threshold;175 unsigned int inact_time_ms;176 177 unsigned int fifo_set_size;178 unsigned int fifo_watermark;179 180 __be16 fifo_buf[ADXL367_FIFO_SIZE] __aligned(IIO_DMA_MINALIGN);181 __be16 sample_buf;182 u8 act_threshold_buf[2];183 u8 inact_time_buf[2];184 u8 status_buf[3];185};186 187static const unsigned int adxl367_threshold_h_reg_tbl[] = {188 [ADXL367_ACTIVITY] = ADXL367_REG_THRESH_ACT_H,189 [ADXL367_INACTIVITY] = ADXL367_REG_THRESH_INACT_H,190};191 192static const unsigned int adxl367_act_en_shift_tbl[] = {193 [ADXL367_ACTIVITY] = 0,194 [ADXL367_INACTIVITY] = 2,195};196 197static const unsigned int adxl367_act_int_mask_tbl[] = {198 [ADXL367_ACTIVITY] = ADXL367_INT_ACT_MASK,199 [ADXL367_INACTIVITY] = ADXL367_INT_INACT_MASK,200};201 202static const int adxl367_samp_freq_tbl[][2] = {203 [ADXL367_ODR_12P5HZ] = {12, 500000},204 [ADXL367_ODR_25HZ] = {25, 0},205 [ADXL367_ODR_50HZ] = {50, 0},206 [ADXL367_ODR_100HZ] = {100, 0},207 [ADXL367_ODR_200HZ] = {200, 0},208 [ADXL367_ODR_400HZ] = {400, 0},209};210 211/* (g * 2) * 9.80665 * 1000000 / (2^14 - 1) */212static const int adxl367_range_scale_tbl[][2] = {213 [ADXL367_2G_RANGE] = {0, 2394347},214 [ADXL367_4G_RANGE] = {0, 4788695},215 [ADXL367_8G_RANGE] = {0, 9577391},216};217 218static const int adxl367_range_scale_factor_tbl[] = {219 [ADXL367_2G_RANGE] = 1,220 [ADXL367_4G_RANGE] = 2,221 [ADXL367_8G_RANGE] = 4,222};223 224enum {225 ADXL367_X_CHANNEL_INDEX,226 ADXL367_Y_CHANNEL_INDEX,227 ADXL367_Z_CHANNEL_INDEX,228 ADXL367_TEMP_CHANNEL_INDEX,229 ADXL367_EX_ADC_CHANNEL_INDEX230};231 232#define ADXL367_X_CHANNEL_MASK BIT(ADXL367_X_CHANNEL_INDEX)233#define ADXL367_Y_CHANNEL_MASK BIT(ADXL367_Y_CHANNEL_INDEX)234#define ADXL367_Z_CHANNEL_MASK BIT(ADXL367_Z_CHANNEL_INDEX)235#define ADXL367_TEMP_CHANNEL_MASK BIT(ADXL367_TEMP_CHANNEL_INDEX)236#define ADXL367_EX_ADC_CHANNEL_MASK BIT(ADXL367_EX_ADC_CHANNEL_INDEX)237 238static const enum adxl367_fifo_format adxl367_fifo_formats[] = {239 ADXL367_FIFO_FORMAT_X,240 ADXL367_FIFO_FORMAT_Y,241 ADXL367_FIFO_FORMAT_Z,242 ADXL367_FIFO_FORMAT_XT,243 ADXL367_FIFO_FORMAT_YT,244 ADXL367_FIFO_FORMAT_ZT,245 ADXL367_FIFO_FORMAT_XA,246 ADXL367_FIFO_FORMAT_YA,247 ADXL367_FIFO_FORMAT_ZA,248 ADXL367_FIFO_FORMAT_XYZ,249 ADXL367_FIFO_FORMAT_XYZT,250 ADXL367_FIFO_FORMAT_XYZA,251};252 253static const unsigned long adxl367_channel_masks[] = {254 ADXL367_X_CHANNEL_MASK,255 ADXL367_Y_CHANNEL_MASK,256 ADXL367_Z_CHANNEL_MASK,257 ADXL367_X_CHANNEL_MASK | ADXL367_TEMP_CHANNEL_MASK,258 ADXL367_Y_CHANNEL_MASK | ADXL367_TEMP_CHANNEL_MASK,259 ADXL367_Z_CHANNEL_MASK | ADXL367_TEMP_CHANNEL_MASK,260 ADXL367_X_CHANNEL_MASK | ADXL367_EX_ADC_CHANNEL_MASK,261 ADXL367_Y_CHANNEL_MASK | ADXL367_EX_ADC_CHANNEL_MASK,262 ADXL367_Z_CHANNEL_MASK | ADXL367_EX_ADC_CHANNEL_MASK,263 ADXL367_X_CHANNEL_MASK | ADXL367_Y_CHANNEL_MASK | ADXL367_Z_CHANNEL_MASK,264 ADXL367_X_CHANNEL_MASK | ADXL367_Y_CHANNEL_MASK | ADXL367_Z_CHANNEL_MASK |265 ADXL367_TEMP_CHANNEL_MASK,266 ADXL367_X_CHANNEL_MASK | ADXL367_Y_CHANNEL_MASK | ADXL367_Z_CHANNEL_MASK |267 ADXL367_EX_ADC_CHANNEL_MASK,268 0,269};270 271static int adxl367_set_measure_en(struct adxl367_state *st, bool en)272{273 enum adxl367_op_mode op_mode = en ? ADXL367_OP_MEASURE274 : ADXL367_OP_STANDBY;275 int ret;276 277 ret = regmap_update_bits(st->regmap, ADXL367_REG_POWER_CTL,278 ADXL367_POWER_CTL_MODE_MASK,279 FIELD_PREP(ADXL367_POWER_CTL_MODE_MASK,280 op_mode));281 if (ret)282 return ret;283 284 /*285 * Wait for acceleration output to settle after entering286 * measure mode.287 */288 if (en)289 msleep(100);290 291 return 0;292}293 294static void adxl367_scale_act_thresholds(struct adxl367_state *st,295 enum adxl367_range old_range,296 enum adxl367_range new_range)297{298 st->act_threshold = st->act_threshold299 * adxl367_range_scale_factor_tbl[old_range]300 / adxl367_range_scale_factor_tbl[new_range];301 st->inact_threshold = st->inact_threshold302 * adxl367_range_scale_factor_tbl[old_range]303 / adxl367_range_scale_factor_tbl[new_range];304}305 306static int _adxl367_set_act_threshold(struct adxl367_state *st,307 enum adxl367_activity_type act,308 unsigned int threshold)309{310 u8 reg = adxl367_threshold_h_reg_tbl[act];311 int ret;312 313 if (threshold > ADXL367_THRESH_MAX)314 return -EINVAL;315 316 st->act_threshold_buf[0] = FIELD_PREP(ADXL367_THRESH_H_MASK,317 FIELD_GET(ADXL367_THRESH_VAL_H_MASK,318 threshold));319 st->act_threshold_buf[1] = FIELD_PREP(ADXL367_THRESH_L_MASK,320 FIELD_GET(ADXL367_THRESH_VAL_L_MASK,321 threshold));322 323 ret = regmap_bulk_write(st->regmap, reg, st->act_threshold_buf,324 sizeof(st->act_threshold_buf));325 if (ret)326 return ret;327 328 if (act == ADXL367_ACTIVITY)329 st->act_threshold = threshold;330 else331 st->inact_threshold = threshold;332 333 return 0;334}335 336static int adxl367_set_act_threshold(struct adxl367_state *st,337 enum adxl367_activity_type act,338 unsigned int threshold)339{340 int ret;341 342 guard(mutex)(&st->lock);343 344 ret = adxl367_set_measure_en(st, false);345 if (ret)346 return ret;347 348 ret = _adxl367_set_act_threshold(st, act, threshold);349 if (ret)350 return ret;351 352 return adxl367_set_measure_en(st, true);353}354 355static int adxl367_set_act_proc_mode(struct adxl367_state *st,356 enum adxl367_act_proc_mode mode)357{358 return regmap_update_bits(st->regmap, ADXL367_REG_ACT_INACT_CTL,359 ADXL367_ACT_LINKLOOP_MASK,360 FIELD_PREP(ADXL367_ACT_LINKLOOP_MASK,361 mode));362}363 364static int adxl367_set_act_interrupt_en(struct adxl367_state *st,365 enum adxl367_activity_type act,366 bool en)367{368 unsigned int mask = adxl367_act_int_mask_tbl[act];369 370 return regmap_update_bits(st->regmap, ADXL367_REG_INT1_MAP,371 mask, en ? mask : 0);372}373 374static int adxl367_get_act_interrupt_en(struct adxl367_state *st,375 enum adxl367_activity_type act,376 bool *en)377{378 unsigned int mask = adxl367_act_int_mask_tbl[act];379 unsigned int val;380 int ret;381 382 ret = regmap_read(st->regmap, ADXL367_REG_INT1_MAP, &val);383 if (ret)384 return ret;385 386 *en = !!(val & mask);387 388 return 0;389}390 391static int adxl367_set_act_en(struct adxl367_state *st,392 enum adxl367_activity_type act,393 enum adxl367_act_en_mode en)394{395 unsigned int ctl_shift = adxl367_act_en_shift_tbl[act];396 397 return regmap_update_bits(st->regmap, ADXL367_REG_ACT_INACT_CTL,398 ADXL367_ACT_EN_MASK << ctl_shift,399 en << ctl_shift);400}401 402static int adxl367_set_fifo_watermark_interrupt_en(struct adxl367_state *st,403 bool en)404{405 return regmap_update_bits(st->regmap, ADXL367_REG_INT1_MAP,406 ADXL367_INT_FIFO_WATERMARK_MASK,407 en ? ADXL367_INT_FIFO_WATERMARK_MASK : 0);408}409 410static int adxl367_get_fifo_mode(struct adxl367_state *st,411 enum adxl367_fifo_mode *fifo_mode)412{413 unsigned int val;414 int ret;415 416 ret = regmap_read(st->regmap, ADXL367_REG_FIFO_CTL, &val);417 if (ret)418 return ret;419 420 *fifo_mode = FIELD_GET(ADXL367_FIFO_CTL_MODE_MASK, val);421 422 return 0;423}424 425static int adxl367_set_fifo_mode(struct adxl367_state *st,426 enum adxl367_fifo_mode fifo_mode)427{428 return regmap_update_bits(st->regmap, ADXL367_REG_FIFO_CTL,429 ADXL367_FIFO_CTL_MODE_MASK,430 FIELD_PREP(ADXL367_FIFO_CTL_MODE_MASK,431 fifo_mode));432}433 434static int adxl367_set_fifo_format(struct adxl367_state *st,435 enum adxl367_fifo_format fifo_format)436{437 return regmap_update_bits(st->regmap, ADXL367_REG_FIFO_CTL,438 ADXL367_FIFO_CTL_FORMAT_MASK,439 FIELD_PREP(ADXL367_FIFO_CTL_FORMAT_MASK,440 fifo_format));441}442 443static int adxl367_set_fifo_watermark(struct adxl367_state *st,444 unsigned int fifo_watermark)445{446 unsigned int fifo_samples = fifo_watermark * st->fifo_set_size;447 unsigned int fifo_samples_h, fifo_samples_l;448 int ret;449 450 if (fifo_samples > ADXL367_FIFO_MAX_WATERMARK)451 fifo_samples = ADXL367_FIFO_MAX_WATERMARK;452 453 fifo_samples /= st->fifo_set_size;454 455 fifo_samples_h = FIELD_PREP(ADXL367_SAMPLES_H_MASK,456 FIELD_GET(ADXL367_SAMPLES_VAL_H_MASK,457 fifo_samples));458 fifo_samples_l = FIELD_PREP(ADXL367_SAMPLES_L_MASK,459 FIELD_GET(ADXL367_SAMPLES_VAL_L_MASK,460 fifo_samples));461 462 ret = regmap_update_bits(st->regmap, ADXL367_REG_FIFO_CTL,463 ADXL367_SAMPLES_H_MASK, fifo_samples_h);464 if (ret)465 return ret;466 467 ret = regmap_update_bits(st->regmap, ADXL367_REG_FIFO_SAMPLES,468 ADXL367_SAMPLES_L_MASK, fifo_samples_l);469 if (ret)470 return ret;471 472 st->fifo_watermark = fifo_watermark;473 474 return 0;475}476 477static int adxl367_set_range(struct iio_dev *indio_dev,478 enum adxl367_range range)479{480 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {481 struct adxl367_state *st = iio_priv(indio_dev);482 int ret;483 484 guard(mutex)(&st->lock);485 486 ret = adxl367_set_measure_en(st, false);487 if (ret)488 return ret;489 490 ret = regmap_update_bits(st->regmap, ADXL367_REG_FILTER_CTL,491 ADXL367_FILTER_CTL_RANGE_MASK,492 FIELD_PREP(ADXL367_FILTER_CTL_RANGE_MASK,493 range));494 if (ret)495 return ret;496 497 adxl367_scale_act_thresholds(st, st->range, range);498 499 /* Activity thresholds depend on range */500 ret = _adxl367_set_act_threshold(st, ADXL367_ACTIVITY,501 st->act_threshold);502 if (ret)503 return ret;504 505 ret = _adxl367_set_act_threshold(st, ADXL367_INACTIVITY,506 st->inact_threshold);507 if (ret)508 return ret;509 510 ret = adxl367_set_measure_en(st, true);511 if (ret)512 return ret;513 514 st->range = range;515 516 return 0;517 }518 unreachable();519}520 521static int adxl367_time_ms_to_samples(struct adxl367_state *st, unsigned int ms)522{523 int freq_hz = adxl367_samp_freq_tbl[st->odr][0];524 int freq_microhz = adxl367_samp_freq_tbl[st->odr][1];525 /* Scale to decihertz to prevent precision loss in 12.5Hz case. */526 int freq_dhz = freq_hz * 10 + freq_microhz / 100000;527 528 return DIV_ROUND_CLOSEST(ms * freq_dhz, 10000);529}530 531static int _adxl367_set_act_time_ms(struct adxl367_state *st, unsigned int ms)532{533 unsigned int val = adxl367_time_ms_to_samples(st, ms);534 int ret;535 536 if (val > ADXL367_TIME_ACT_MAX)537 val = ADXL367_TIME_ACT_MAX;538 539 ret = regmap_write(st->regmap, ADXL367_REG_TIME_ACT, val);540 if (ret)541 return ret;542 543 st->act_time_ms = ms;544 545 return 0;546}547 548static int _adxl367_set_inact_time_ms(struct adxl367_state *st, unsigned int ms)549{550 unsigned int val = adxl367_time_ms_to_samples(st, ms);551 int ret;552 553 if (val > ADXL367_TIME_INACT_MAX)554 val = ADXL367_TIME_INACT_MAX;555 556 st->inact_time_buf[0] = FIELD_PREP(ADXL367_TIME_INACT_H_MASK,557 FIELD_GET(ADXL367_TIME_INACT_VAL_H_MASK,558 val));559 st->inact_time_buf[1] = FIELD_PREP(ADXL367_TIME_INACT_L_MASK,560 FIELD_GET(ADXL367_TIME_INACT_VAL_L_MASK,561 val));562 563 ret = regmap_bulk_write(st->regmap, ADXL367_REG_TIME_INACT_H,564 st->inact_time_buf, sizeof(st->inact_time_buf));565 if (ret)566 return ret;567 568 st->inact_time_ms = ms;569 570 return 0;571}572 573static int adxl367_set_act_time_ms(struct adxl367_state *st,574 enum adxl367_activity_type act,575 unsigned int ms)576{577 int ret;578 579 guard(mutex)(&st->lock);580 581 ret = adxl367_set_measure_en(st, false);582 if (ret)583 return ret;584 585 if (act == ADXL367_ACTIVITY)586 ret = _adxl367_set_act_time_ms(st, ms);587 else588 ret = _adxl367_set_inact_time_ms(st, ms);589 590 if (ret)591 return ret;592 593 return adxl367_set_measure_en(st, true);594}595 596static int _adxl367_set_odr(struct adxl367_state *st, enum adxl367_odr odr)597{598 int ret;599 600 ret = regmap_update_bits(st->regmap, ADXL367_REG_FILTER_CTL,601 ADXL367_FILTER_CTL_ODR_MASK,602 FIELD_PREP(ADXL367_FILTER_CTL_ODR_MASK,603 odr));604 if (ret)605 return ret;606 607 /* Activity timers depend on ODR */608 ret = _adxl367_set_act_time_ms(st, st->act_time_ms);609 if (ret)610 return ret;611 612 ret = _adxl367_set_inact_time_ms(st, st->inact_time_ms);613 if (ret)614 return ret;615 616 st->odr = odr;617 618 return 0;619}620 621static int adxl367_set_odr(struct iio_dev *indio_dev, enum adxl367_odr odr)622{623 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {624 struct adxl367_state *st = iio_priv(indio_dev);625 int ret;626 627 guard(mutex)(&st->lock);628 629 ret = adxl367_set_measure_en(st, false);630 if (ret)631 return ret;632 633 ret = _adxl367_set_odr(st, odr);634 if (ret)635 return ret;636 637 return adxl367_set_measure_en(st, true);638 }639 unreachable();640}641 642static int adxl367_set_temp_adc_en(struct adxl367_state *st, unsigned int reg,643 bool en)644{645 return regmap_update_bits(st->regmap, reg, ADXL367_ADC_EN_MASK,646 en ? ADXL367_ADC_EN_MASK : 0);647}648 649static int adxl367_set_temp_adc_reg_en(struct adxl367_state *st,650 unsigned int reg, bool en)651{652 int ret;653 654 switch (reg) {655 case ADXL367_REG_TEMP_DATA_H:656 ret = adxl367_set_temp_adc_en(st, ADXL367_REG_TEMP_CTL, en);657 break;658 case ADXL367_REG_EX_ADC_DATA_H:659 ret = adxl367_set_temp_adc_en(st, ADXL367_REG_ADC_CTL, en);660 break;661 default:662 return 0;663 }664 665 if (ret)666 return ret;667 668 if (en)669 msleep(100);670 671 return 0;672}673 674static int adxl367_set_temp_adc_mask_en(struct adxl367_state *st,675 const unsigned long *active_scan_mask,676 bool en)677{678 if (*active_scan_mask & ADXL367_TEMP_CHANNEL_MASK)679 return adxl367_set_temp_adc_en(st, ADXL367_REG_TEMP_CTL, en);680 else if (*active_scan_mask & ADXL367_EX_ADC_CHANNEL_MASK)681 return adxl367_set_temp_adc_en(st, ADXL367_REG_ADC_CTL, en);682 683 return 0;684}685 686static int adxl367_find_odr(struct adxl367_state *st, int val, int val2,687 enum adxl367_odr *odr)688{689 size_t size = ARRAY_SIZE(adxl367_samp_freq_tbl);690 int i;691 692 for (i = 0; i < size; i++)693 if (val == adxl367_samp_freq_tbl[i][0] &&694 val2 == adxl367_samp_freq_tbl[i][1])695 break;696 697 if (i == size)698 return -EINVAL;699 700 *odr = i;701 702 return 0;703}704 705static int adxl367_find_range(struct adxl367_state *st, int val, int val2,706 enum adxl367_range *range)707{708 size_t size = ARRAY_SIZE(adxl367_range_scale_tbl);709 int i;710 711 for (i = 0; i < size; i++)712 if (val == adxl367_range_scale_tbl[i][0] &&713 val2 == adxl367_range_scale_tbl[i][1])714 break;715 716 if (i == size)717 return -EINVAL;718 719 *range = i;720 721 return 0;722}723 724static int adxl367_read_sample(struct iio_dev *indio_dev,725 struct iio_chan_spec const *chan,726 int *val)727{728 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {729 struct adxl367_state *st = iio_priv(indio_dev);730 u16 sample;731 int ret;732 733 guard(mutex)(&st->lock);734 735 ret = adxl367_set_temp_adc_reg_en(st, chan->address, true);736 if (ret)737 return ret;738 739 ret = regmap_bulk_read(st->regmap, chan->address, &st->sample_buf,740 sizeof(st->sample_buf));741 if (ret)742 return ret;743 744 sample = FIELD_GET(ADXL367_DATA_MASK, be16_to_cpu(st->sample_buf));745 *val = sign_extend32(sample, chan->scan_type.realbits - 1);746 747 ret = adxl367_set_temp_adc_reg_en(st, chan->address, false);748 if (ret)749 return ret;750 751 return IIO_VAL_INT;752 }753 unreachable();754}755 756static int adxl367_get_status(struct adxl367_state *st, u8 *status,757 u16 *fifo_entries)758{759 int ret;760 761 /* Read STATUS, FIFO_ENT_L and FIFO_ENT_H */762 ret = regmap_bulk_read(st->regmap, ADXL367_REG_STATUS,763 st->status_buf, sizeof(st->status_buf));764 if (ret)765 return ret;766 767 st->status_buf[2] &= ADXL367_FIFO_ENT_H_MASK;768 769 *status = st->status_buf[0];770 *fifo_entries = get_unaligned_le16(&st->status_buf[1]);771 772 return 0;773}774 775static bool adxl367_push_event(struct iio_dev *indio_dev, u8 status)776{777 unsigned int ev_dir;778 779 if (FIELD_GET(ADXL367_STATUS_ACT_MASK, status))780 ev_dir = IIO_EV_DIR_RISING;781 else if (FIELD_GET(ADXL367_STATUS_INACT_MASK, status))782 ev_dir = IIO_EV_DIR_FALLING;783 else784 return false;785 786 iio_push_event(indio_dev,787 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z,788 IIO_EV_TYPE_THRESH, ev_dir),789 iio_get_time_ns(indio_dev));790 791 return true;792}793 794static bool adxl367_push_fifo_data(struct iio_dev *indio_dev, u8 status,795 u16 fifo_entries)796{797 struct adxl367_state *st = iio_priv(indio_dev);798 int ret;799 int i;800 801 if (!FIELD_GET(ADXL367_STATUS_FIFO_FULL_MASK, status))802 return false;803 804 fifo_entries -= fifo_entries % st->fifo_set_size;805 806 ret = st->ops->read_fifo(st->context, st->fifo_buf, fifo_entries);807 if (ret) {808 dev_err(st->dev, "Failed to read FIFO: %d\n", ret);809 return true;810 }811 812 for (i = 0; i < fifo_entries; i += st->fifo_set_size)813 iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);814 815 return true;816}817 818static irqreturn_t adxl367_irq_handler(int irq, void *private)819{820 struct iio_dev *indio_dev = private;821 struct adxl367_state *st = iio_priv(indio_dev);822 u16 fifo_entries;823 bool handled;824 u8 status;825 int ret;826 827 ret = adxl367_get_status(st, &status, &fifo_entries);828 if (ret)829 return IRQ_NONE;830 831 handled = adxl367_push_event(indio_dev, status);832 handled |= adxl367_push_fifo_data(indio_dev, status, fifo_entries);833 834 return handled ? IRQ_HANDLED : IRQ_NONE;835}836 837static int adxl367_reg_access(struct iio_dev *indio_dev,838 unsigned int reg,839 unsigned int writeval,840 unsigned int *readval)841{842 struct adxl367_state *st = iio_priv(indio_dev);843 844 if (readval)845 return regmap_read(st->regmap, reg, readval);846 else847 return regmap_write(st->regmap, reg, writeval);848}849 850static int adxl367_read_raw(struct iio_dev *indio_dev,851 struct iio_chan_spec const *chan,852 int *val, int *val2, long info)853{854 struct adxl367_state *st = iio_priv(indio_dev);855 856 switch (info) {857 case IIO_CHAN_INFO_RAW:858 return adxl367_read_sample(indio_dev, chan, val);859 case IIO_CHAN_INFO_SCALE:860 switch (chan->type) {861 case IIO_ACCEL: {862 guard(mutex)(&st->lock);863 *val = adxl367_range_scale_tbl[st->range][0];864 *val2 = adxl367_range_scale_tbl[st->range][1];865 return IIO_VAL_INT_PLUS_NANO;866 }867 case IIO_TEMP:868 *val = 1000;869 *val2 = ADXL367_TEMP_PER_C;870 return IIO_VAL_FRACTIONAL;871 case IIO_VOLTAGE:872 *val = ADXL367_VOLTAGE_MAX_MV;873 *val2 = ADXL367_VOLTAGE_MAX_RAW;874 return IIO_VAL_FRACTIONAL;875 default:876 return -EINVAL;877 }878 case IIO_CHAN_INFO_OFFSET:879 switch (chan->type) {880 case IIO_TEMP:881 *val = 25 * ADXL367_TEMP_PER_C - ADXL367_TEMP_25C;882 return IIO_VAL_INT;883 case IIO_VOLTAGE:884 *val = ADXL367_VOLTAGE_OFFSET;885 return IIO_VAL_INT;886 default:887 return -EINVAL;888 }889 case IIO_CHAN_INFO_SAMP_FREQ: {890 guard(mutex)(&st->lock);891 *val = adxl367_samp_freq_tbl[st->odr][0];892 *val2 = adxl367_samp_freq_tbl[st->odr][1];893 return IIO_VAL_INT_PLUS_MICRO;894 }895 default:896 return -EINVAL;897 }898}899 900static int adxl367_write_raw(struct iio_dev *indio_dev,901 struct iio_chan_spec const *chan,902 int val, int val2, long info)903{904 struct adxl367_state *st = iio_priv(indio_dev);905 int ret;906 907 switch (info) {908 case IIO_CHAN_INFO_SAMP_FREQ: {909 enum adxl367_odr odr;910 911 ret = adxl367_find_odr(st, val, val2, &odr);912 if (ret)913 return ret;914 915 return adxl367_set_odr(indio_dev, odr);916 }917 case IIO_CHAN_INFO_SCALE: {918 enum adxl367_range range;919 920 ret = adxl367_find_range(st, val, val2, &range);921 if (ret)922 return ret;923 924 return adxl367_set_range(indio_dev, range);925 }926 default:927 return -EINVAL;928 }929}930 931static int adxl367_write_raw_get_fmt(struct iio_dev *indio_dev,932 struct iio_chan_spec const *chan,933 long info)934{935 switch (info) {936 case IIO_CHAN_INFO_SCALE:937 if (chan->type != IIO_ACCEL)938 return -EINVAL;939 940 return IIO_VAL_INT_PLUS_NANO;941 default:942 return IIO_VAL_INT_PLUS_MICRO;943 }944}945 946static int adxl367_read_avail(struct iio_dev *indio_dev,947 struct iio_chan_spec const *chan,948 const int **vals, int *type, int *length,949 long info)950{951 switch (info) {952 case IIO_CHAN_INFO_SCALE:953 if (chan->type != IIO_ACCEL)954 return -EINVAL;955 956 *vals = (int *)adxl367_range_scale_tbl;957 *type = IIO_VAL_INT_PLUS_NANO;958 *length = ARRAY_SIZE(adxl367_range_scale_tbl) * 2;959 return IIO_AVAIL_LIST;960 case IIO_CHAN_INFO_SAMP_FREQ:961 *vals = (int *)adxl367_samp_freq_tbl;962 *type = IIO_VAL_INT_PLUS_MICRO;963 *length = ARRAY_SIZE(adxl367_samp_freq_tbl) * 2;964 return IIO_AVAIL_LIST;965 default:966 return -EINVAL;967 }968}969 970static int adxl367_read_event_value(struct iio_dev *indio_dev,971 const struct iio_chan_spec *chan,972 enum iio_event_type type,973 enum iio_event_direction dir,974 enum iio_event_info info,975 int *val, int *val2)976{977 struct adxl367_state *st = iio_priv(indio_dev);978 979 guard(mutex)(&st->lock);980 switch (info) {981 case IIO_EV_INFO_VALUE: {982 switch (dir) {983 case IIO_EV_DIR_RISING:984 *val = st->act_threshold;985 return IIO_VAL_INT;986 case IIO_EV_DIR_FALLING:987 *val = st->inact_threshold;988 return IIO_VAL_INT;989 default:990 return -EINVAL;991 }992 }993 case IIO_EV_INFO_PERIOD:994 switch (dir) {995 case IIO_EV_DIR_RISING:996 *val = st->act_time_ms;997 *val2 = 1000;998 return IIO_VAL_FRACTIONAL;999 case IIO_EV_DIR_FALLING:1000 *val = st->inact_time_ms;1001 *val2 = 1000;1002 return IIO_VAL_FRACTIONAL;1003 default:1004 return -EINVAL;1005 }1006 default:1007 return -EINVAL;1008 }1009}1010 1011static int adxl367_write_event_value(struct iio_dev *indio_dev,1012 const struct iio_chan_spec *chan,1013 enum iio_event_type type,1014 enum iio_event_direction dir,1015 enum iio_event_info info,1016 int val, int val2)1017{1018 struct adxl367_state *st = iio_priv(indio_dev);1019 1020 switch (info) {1021 case IIO_EV_INFO_VALUE:1022 if (val < 0)1023 return -EINVAL;1024 1025 switch (dir) {1026 case IIO_EV_DIR_RISING:1027 return adxl367_set_act_threshold(st, ADXL367_ACTIVITY, val);1028 case IIO_EV_DIR_FALLING:1029 return adxl367_set_act_threshold(st, ADXL367_INACTIVITY, val);1030 default:1031 return -EINVAL;1032 }1033 case IIO_EV_INFO_PERIOD:1034 if (val < 0)1035 return -EINVAL;1036 1037 val = val * 1000 + DIV_ROUND_UP(val2, 1000);1038 switch (dir) {1039 case IIO_EV_DIR_RISING:1040 return adxl367_set_act_time_ms(st, ADXL367_ACTIVITY, val);1041 case IIO_EV_DIR_FALLING:1042 return adxl367_set_act_time_ms(st, ADXL367_INACTIVITY, val);1043 default:1044 return -EINVAL;1045 }1046 default:1047 return -EINVAL;1048 }1049}1050 1051static int adxl367_read_event_config(struct iio_dev *indio_dev,1052 const struct iio_chan_spec *chan,1053 enum iio_event_type type,1054 enum iio_event_direction dir)1055{1056 struct adxl367_state *st = iio_priv(indio_dev);1057 bool en;1058 int ret;1059 1060 switch (dir) {1061 case IIO_EV_DIR_RISING:1062 ret = adxl367_get_act_interrupt_en(st, ADXL367_ACTIVITY, &en);1063 return ret ?: en;1064 case IIO_EV_DIR_FALLING:1065 ret = adxl367_get_act_interrupt_en(st, ADXL367_INACTIVITY, &en);1066 return ret ?: en;1067 default:1068 return -EINVAL;1069 }1070}1071 1072static int adxl367_write_event_config(struct iio_dev *indio_dev,1073 const struct iio_chan_spec *chan,1074 enum iio_event_type type,1075 enum iio_event_direction dir,1076 int state)1077{1078 enum adxl367_activity_type act;1079 1080 switch (dir) {1081 case IIO_EV_DIR_RISING:1082 act = ADXL367_ACTIVITY;1083 break;1084 case IIO_EV_DIR_FALLING:1085 act = ADXL367_INACTIVITY;1086 break;1087 default:1088 return -EINVAL;1089 }1090 1091 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {1092 struct adxl367_state *st = iio_priv(indio_dev);1093 int ret;1094 1095 guard(mutex)(&st->lock);1096 1097 ret = adxl367_set_measure_en(st, false);1098 if (ret)1099 return ret;1100 1101 ret = adxl367_set_act_interrupt_en(st, act, state);1102 if (ret)1103 return ret;1104 1105 ret = adxl367_set_act_en(st, act, state ? ADCL367_ACT_REF_ENABLED1106 : ADXL367_ACT_DISABLED);1107 if (ret)1108 return ret;1109 1110 return adxl367_set_measure_en(st, true);1111 }1112 unreachable();1113}1114 1115static ssize_t adxl367_get_fifo_enabled(struct device *dev,1116 struct device_attribute *attr,1117 char *buf)1118{1119 struct adxl367_state *st = iio_priv(dev_to_iio_dev(dev));1120 enum adxl367_fifo_mode fifo_mode;1121 int ret;1122 1123 ret = adxl367_get_fifo_mode(st, &fifo_mode);1124 if (ret)1125 return ret;1126 1127 return sysfs_emit(buf, "%d\n", fifo_mode != ADXL367_FIFO_MODE_DISABLED);1128}1129 1130static ssize_t adxl367_get_fifo_watermark(struct device *dev,1131 struct device_attribute *attr,1132 char *buf)1133{1134 struct adxl367_state *st = iio_priv(dev_to_iio_dev(dev));1135 unsigned int fifo_watermark;1136 1137 guard(mutex)(&st->lock);1138 fifo_watermark = st->fifo_watermark;1139 1140 return sysfs_emit(buf, "%d\n", fifo_watermark);1141}1142 1143IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1");1144IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max,1145 __stringify(ADXL367_FIFO_MAX_WATERMARK));1146static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,1147 adxl367_get_fifo_watermark, NULL, 0);1148static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,1149 adxl367_get_fifo_enabled, NULL, 0);1150 1151static const struct iio_dev_attr *adxl367_fifo_attributes[] = {1152 &iio_dev_attr_hwfifo_watermark_min,1153 &iio_dev_attr_hwfifo_watermark_max,1154 &iio_dev_attr_hwfifo_watermark,1155 &iio_dev_attr_hwfifo_enabled,1156 NULL,1157};1158 1159static int adxl367_set_watermark(struct iio_dev *indio_dev, unsigned int val)1160{1161 struct adxl367_state *st = iio_priv(indio_dev);1162 int ret;1163 1164 if (val > ADXL367_FIFO_MAX_WATERMARK)1165 return -EINVAL;1166 1167 guard(mutex)(&st->lock);1168 1169 ret = adxl367_set_measure_en(st, false);1170 if (ret)1171 return ret;1172 1173 ret = adxl367_set_fifo_watermark(st, val);1174 if (ret)1175 return ret;1176 1177 return adxl367_set_measure_en(st, true);1178}1179 1180static bool adxl367_find_mask_fifo_format(const unsigned long *scan_mask,1181 enum adxl367_fifo_format *fifo_format)1182{1183 size_t size = ARRAY_SIZE(adxl367_fifo_formats);1184 int i;1185 1186 for (i = 0; i < size; i++)1187 if (*scan_mask == adxl367_channel_masks[i])1188 break;1189 1190 if (i == size)1191 return false;1192 1193 *fifo_format = adxl367_fifo_formats[i];1194 1195 return true;1196}1197 1198static int adxl367_update_scan_mode(struct iio_dev *indio_dev,1199 const unsigned long *active_scan_mask)1200{1201 struct adxl367_state *st = iio_priv(indio_dev);1202 enum adxl367_fifo_format fifo_format;1203 int ret;1204 1205 if (!adxl367_find_mask_fifo_format(active_scan_mask, &fifo_format))1206 return -EINVAL;1207 1208 guard(mutex)(&st->lock);1209 1210 ret = adxl367_set_measure_en(st, false);1211 if (ret)1212 return ret;1213 1214 ret = adxl367_set_fifo_format(st, fifo_format);1215 if (ret)1216 return ret;1217 1218 ret = adxl367_set_measure_en(st, true);1219 if (ret)1220 return ret;1221 1222 st->fifo_set_size = bitmap_weight(active_scan_mask,1223 iio_get_masklength(indio_dev));1224 1225 return 0;1226}1227 1228static int adxl367_buffer_postenable(struct iio_dev *indio_dev)1229{1230 struct adxl367_state *st = iio_priv(indio_dev);1231 int ret;1232 1233 guard(mutex)(&st->lock);1234 1235 ret = adxl367_set_temp_adc_mask_en(st, indio_dev->active_scan_mask,1236 true);1237 if (ret)1238 return ret;1239 1240 ret = adxl367_set_measure_en(st, false);1241 if (ret)1242 return ret;1243 1244 ret = adxl367_set_fifo_watermark_interrupt_en(st, true);1245 if (ret)1246 return ret;1247 1248 ret = adxl367_set_fifo_mode(st, ADXL367_FIFO_MODE_STREAM);1249 if (ret)1250 return ret;1251 1252 return adxl367_set_measure_en(st, true);1253}1254 1255static int adxl367_buffer_predisable(struct iio_dev *indio_dev)1256{1257 struct adxl367_state *st = iio_priv(indio_dev);1258 int ret;1259 1260 guard(mutex)(&st->lock);1261 1262 ret = adxl367_set_measure_en(st, false);1263 if (ret)1264 return ret;1265 1266 ret = adxl367_set_fifo_mode(st, ADXL367_FIFO_MODE_DISABLED);1267 if (ret)1268 return ret;1269 1270 ret = adxl367_set_fifo_watermark_interrupt_en(st, false);1271 if (ret)1272 return ret;1273 1274 ret = adxl367_set_measure_en(st, true);1275 if (ret)1276 return ret;1277 1278 return adxl367_set_temp_adc_mask_en(st, indio_dev->active_scan_mask,1279 false);1280}1281 1282static const struct iio_buffer_setup_ops adxl367_buffer_ops = {1283 .postenable = adxl367_buffer_postenable,1284 .predisable = adxl367_buffer_predisable,1285};1286 1287static const struct iio_info adxl367_info = {1288 .read_raw = adxl367_read_raw,1289 .write_raw = adxl367_write_raw,1290 .write_raw_get_fmt = adxl367_write_raw_get_fmt,1291 .read_avail = adxl367_read_avail,1292 .read_event_config = adxl367_read_event_config,1293 .write_event_config = adxl367_write_event_config,1294 .read_event_value = adxl367_read_event_value,1295 .write_event_value = adxl367_write_event_value,1296 .debugfs_reg_access = adxl367_reg_access,1297 .hwfifo_set_watermark = adxl367_set_watermark,1298 .update_scan_mode = adxl367_update_scan_mode,1299};1300 1301static const struct iio_event_spec adxl367_events[] = {1302 {1303 .type = IIO_EV_TYPE_MAG_REFERENCED,1304 .dir = IIO_EV_DIR_RISING,1305 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |1306 BIT(IIO_EV_INFO_PERIOD) |1307 BIT(IIO_EV_INFO_VALUE),1308 },1309 {1310 .type = IIO_EV_TYPE_MAG_REFERENCED,1311 .dir = IIO_EV_DIR_FALLING,1312 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |1313 BIT(IIO_EV_INFO_PERIOD) |1314 BIT(IIO_EV_INFO_VALUE),1315 },1316};1317 1318#define ADXL367_ACCEL_CHANNEL(index, reg, axis) { \1319 .type = IIO_ACCEL, \1320 .address = (reg), \1321 .modified = 1, \1322 .channel2 = IIO_MOD_##axis, \1323 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \1324 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \1325 .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \1326 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \1327 .info_mask_shared_by_all_available = \1328 BIT(IIO_CHAN_INFO_SAMP_FREQ), \1329 .event_spec = adxl367_events, \1330 .num_event_specs = ARRAY_SIZE(adxl367_events), \1331 .scan_index = (index), \1332 .scan_type = { \1333 .sign = 's', \1334 .realbits = 14, \1335 .storagebits = 16, \1336 .endianness = IIO_BE, \1337 }, \1338}1339 1340#define ADXL367_CHANNEL(index, reg, _type) { \1341 .type = (_type), \1342 .address = (reg), \1343 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \1344 BIT(IIO_CHAN_INFO_OFFSET) | \1345 BIT(IIO_CHAN_INFO_SCALE), \1346 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \1347 .scan_index = (index), \1348 .scan_type = { \1349 .sign = 's', \1350 .realbits = 14, \1351 .storagebits = 16, \1352 .endianness = IIO_BE, \1353 }, \1354}1355 1356static const struct iio_chan_spec adxl367_channels[] = {1357 ADXL367_ACCEL_CHANNEL(ADXL367_X_CHANNEL_INDEX, ADXL367_REG_X_DATA_H, X),1358 ADXL367_ACCEL_CHANNEL(ADXL367_Y_CHANNEL_INDEX, ADXL367_REG_Y_DATA_H, Y),1359 ADXL367_ACCEL_CHANNEL(ADXL367_Z_CHANNEL_INDEX, ADXL367_REG_Z_DATA_H, Z),1360 ADXL367_CHANNEL(ADXL367_TEMP_CHANNEL_INDEX, ADXL367_REG_TEMP_DATA_H,1361 IIO_TEMP),1362 ADXL367_CHANNEL(ADXL367_EX_ADC_CHANNEL_INDEX, ADXL367_REG_EX_ADC_DATA_H,1363 IIO_VOLTAGE),1364};1365 1366static int adxl367_verify_devid(struct adxl367_state *st)1367{1368 unsigned int val;1369 int ret;1370 1371 ret = regmap_read(st->regmap, ADXL367_REG_DEVID, &val);1372 if (ret)1373 return dev_err_probe(st->dev, ret, "Failed to read dev id\n");1374 1375 if (val != ADXL367_DEVID_AD)1376 return dev_err_probe(st->dev, -ENODEV,1377 "Invalid dev id 0x%02X, expected 0x%02X\n",1378 val, ADXL367_DEVID_AD);1379 1380 return 0;1381}1382 1383static int adxl367_setup(struct adxl367_state *st)1384{1385 int ret;1386 1387 ret = _adxl367_set_act_threshold(st, ADXL367_ACTIVITY,1388 ADXL367_2G_RANGE_1G);1389 if (ret)1390 return ret;1391 1392 ret = _adxl367_set_act_threshold(st, ADXL367_INACTIVITY,1393 ADXL367_2G_RANGE_100MG);1394 if (ret)1395 return ret;1396 1397 ret = adxl367_set_act_proc_mode(st, ADXL367_LOOPED);1398 if (ret)1399 return ret;1400 1401 ret = _adxl367_set_odr(st, ADXL367_ODR_400HZ);1402 if (ret)1403 return ret;1404 1405 ret = _adxl367_set_act_time_ms(st, 10);1406 if (ret)1407 return ret;1408 1409 ret = _adxl367_set_inact_time_ms(st, 10000);1410 if (ret)1411 return ret;1412 1413 return adxl367_set_measure_en(st, true);1414}1415 1416int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,1417 void *context, struct regmap *regmap, int irq)1418{1419 static const char * const regulator_names[] = { "vdd", "vddio" };1420 struct iio_dev *indio_dev;1421 struct adxl367_state *st;1422 int ret;1423 1424 indio_dev = devm_iio_device_alloc(dev, sizeof(*st));1425 if (!indio_dev)1426 return -ENOMEM;1427 1428 st = iio_priv(indio_dev);1429 st->dev = dev;1430 st->regmap = regmap;1431 st->context = context;1432 st->ops = ops;1433 1434 mutex_init(&st->lock);1435 1436 indio_dev->channels = adxl367_channels;1437 indio_dev->num_channels = ARRAY_SIZE(adxl367_channels);1438 indio_dev->available_scan_masks = adxl367_channel_masks;1439 indio_dev->name = "adxl367";1440 indio_dev->info = &adxl367_info;1441 indio_dev->modes = INDIO_DIRECT_MODE;1442 1443 ret = devm_regulator_bulk_get_enable(st->dev,1444 ARRAY_SIZE(regulator_names),1445 regulator_names);1446 if (ret)1447 return dev_err_probe(st->dev, ret,1448 "Failed to get regulators\n");1449 1450 ret = regmap_write(st->regmap, ADXL367_REG_RESET, ADXL367_RESET_CODE);1451 if (ret)1452 return ret;1453 1454 fsleep(15000);1455 1456 ret = adxl367_verify_devid(st);1457 if (ret)1458 return ret;1459 1460 ret = adxl367_setup(st);1461 if (ret)1462 return ret;1463 1464 ret = devm_iio_kfifo_buffer_setup_ext(st->dev, indio_dev,1465 &adxl367_buffer_ops,1466 adxl367_fifo_attributes);1467 if (ret)1468 return ret;1469 1470 ret = devm_request_threaded_irq(st->dev, irq, NULL,1471 adxl367_irq_handler, IRQF_ONESHOT,1472 indio_dev->name, indio_dev);1473 if (ret)1474 return dev_err_probe(st->dev, ret, "Failed to request irq\n");1475 1476 return devm_iio_device_register(dev, indio_dev);1477}1478EXPORT_SYMBOL_NS_GPL(adxl367_probe, IIO_ADXL367);1479 1480MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");1481MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer driver");1482MODULE_LICENSE("GPL");1483