brintos

brintos / linux-shallow public Read only

0
0
Text · 35.6 KiB · e790a66 Raw
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