File Index
Files and directories
Sign in
FILE

fxas21002c_core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/gyro/fxas21002c_core.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Driver for NXP FXAS21002C Gyroscope - Core
   4 *
   5 * Copyright (C) 2019 Linaro Ltd.
   6 */
   7
   8#include <linux/interrupt.h>
   9#include <linux/module.h>
  10#include <linux/pm.h>
  11#include <linux/pm_runtime.h>
  12#include <linux/property.h>
  13#include <linux/regmap.h>
  14#include <linux/regulator/consumer.h>
  15
  16#include <linux/iio/events.h>
  17#include <linux/iio/iio.h>
  18#include <linux/iio/buffer.h>
  19#include <linux/iio/sysfs.h>
  20#include <linux/iio/trigger.h>
  21#include <linux/iio/trigger_consumer.h>
  22#include <linux/iio/triggered_buffer.h>
  23
  24#include "fxas21002c.h"
  25
  26#define FXAS21002C_CHIP_ID_1	0xD6
  27#define FXAS21002C_CHIP_ID_2	0xD7
  28
  29enum fxas21002c_mode_state {
  30	FXAS21002C_MODE_STANDBY,
  31	FXAS21002C_MODE_READY,
  32	FXAS21002C_MODE_ACTIVE,
  33};
  34
  35#define FXAS21002C_STANDBY_ACTIVE_TIME_MS	62
  36#define FXAS21002C_READY_ACTIVE_TIME_MS		7
  37
  38#define FXAS21002C_ODR_LIST_MAX		10
  39
  40#define FXAS21002C_SCALE_FRACTIONAL	32
  41#define FXAS21002C_RANGE_LIMIT_DOUBLE	2000
  42
  43#define FXAS21002C_AXIS_TO_REG(axis) (FXAS21002C_REG_OUT_X_MSB + ((axis) * 2))
  44
  45static const struct reg_field fxas21002c_reg_fields[] = {
  46	[F_DR_STATUS]		= REG_FIELD(FXAS21002C_REG_STATUS, 0, 7),
  47	[F_OUT_X_MSB]		= REG_FIELD(FXAS21002C_REG_OUT_X_MSB, 0, 7),
  48	[F_OUT_X_LSB]		= REG_FIELD(FXAS21002C_REG_OUT_X_LSB, 0, 7),
  49	[F_OUT_Y_MSB]		= REG_FIELD(FXAS21002C_REG_OUT_Y_MSB, 0, 7),
  50	[F_OUT_Y_LSB]		= REG_FIELD(FXAS21002C_REG_OUT_Y_LSB, 0, 7),
  51	[F_OUT_Z_MSB]		= REG_FIELD(FXAS21002C_REG_OUT_Z_MSB, 0, 7),
  52	[F_OUT_Z_LSB]		= REG_FIELD(FXAS21002C_REG_OUT_Z_LSB, 0, 7),
  53	[F_ZYX_OW]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 7, 7),
  54	[F_Z_OW]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 6, 6),
  55	[F_Y_OW]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 5, 5),
  56	[F_X_OW]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 4, 4),
  57	[F_ZYX_DR]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 3, 3),
  58	[F_Z_DR]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 2, 2),
  59	[F_Y_DR]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 1, 1),
  60	[F_X_DR]		= REG_FIELD(FXAS21002C_REG_DR_STATUS, 0, 0),
  61	[F_OVF]			= REG_FIELD(FXAS21002C_REG_F_STATUS, 7, 7),
  62	[F_WMKF]		= REG_FIELD(FXAS21002C_REG_F_STATUS, 6, 6),
  63	[F_CNT]			= REG_FIELD(FXAS21002C_REG_F_STATUS, 0, 5),
  64	[F_MODE]		= REG_FIELD(FXAS21002C_REG_F_SETUP, 6, 7),
  65	[F_WMRK]		= REG_FIELD(FXAS21002C_REG_F_SETUP, 0, 5),
  66	[F_EVENT]		= REG_FIELD(FXAS21002C_REG_F_EVENT, 5, 5),
  67	[FE_TIME]		= REG_FIELD(FXAS21002C_REG_F_EVENT, 0, 4),
  68	[F_BOOTEND]		= REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 3, 3),
  69	[F_SRC_FIFO]		= REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 2, 2),
  70	[F_SRC_RT]		= REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 1, 1),
  71	[F_SRC_DRDY]		= REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 0, 0),
  72	[F_WHO_AM_I]		= REG_FIELD(FXAS21002C_REG_WHO_AM_I, 0, 7),
  73	[F_BW]			= REG_FIELD(FXAS21002C_REG_CTRL0, 6, 7),
  74	[F_SPIW]		= REG_FIELD(FXAS21002C_REG_CTRL0, 5, 5),
  75	[F_SEL]			= REG_FIELD(FXAS21002C_REG_CTRL0, 3, 4),
  76	[F_HPF_EN]		= REG_FIELD(FXAS21002C_REG_CTRL0, 2, 2),
  77	[F_FS]			= REG_FIELD(FXAS21002C_REG_CTRL0, 0, 1),
  78	[F_ELE]			= REG_FIELD(FXAS21002C_REG_RT_CFG, 3, 3),
  79	[F_ZTEFE]		= REG_FIELD(FXAS21002C_REG_RT_CFG, 2, 2),
  80	[F_YTEFE]		= REG_FIELD(FXAS21002C_REG_RT_CFG, 1, 1),
  81	[F_XTEFE]		= REG_FIELD(FXAS21002C_REG_RT_CFG, 0, 0),
  82	[F_EA]			= REG_FIELD(FXAS21002C_REG_RT_SRC, 6, 6),
  83	[F_ZRT]			= REG_FIELD(FXAS21002C_REG_RT_SRC, 5, 5),
  84	[F_ZRT_POL]		= REG_FIELD(FXAS21002C_REG_RT_SRC, 4, 4),
  85	[F_YRT]			= REG_FIELD(FXAS21002C_REG_RT_SRC, 3, 3),
  86	[F_YRT_POL]		= REG_FIELD(FXAS21002C_REG_RT_SRC, 2, 2),
  87	[F_XRT]			= REG_FIELD(FXAS21002C_REG_RT_SRC, 1, 1),
  88	[F_XRT_POL]		= REG_FIELD(FXAS21002C_REG_RT_SRC, 0, 0),
  89	[F_DBCNTM]		= REG_FIELD(FXAS21002C_REG_RT_THS, 7, 7),
  90	[F_THS]			= REG_FIELD(FXAS21002C_REG_RT_SRC, 0, 6),
  91	[F_RT_COUNT]		= REG_FIELD(FXAS21002C_REG_RT_COUNT, 0, 7),
  92	[F_TEMP]		= REG_FIELD(FXAS21002C_REG_TEMP, 0, 7),
  93	[F_RST]			= REG_FIELD(FXAS21002C_REG_CTRL1, 6, 6),
  94	[F_ST]			= REG_FIELD(FXAS21002C_REG_CTRL1, 5, 5),
  95	[F_DR]			= REG_FIELD(FXAS21002C_REG_CTRL1, 2, 4),
  96	[F_ACTIVE]		= REG_FIELD(FXAS21002C_REG_CTRL1, 1, 1),
  97	[F_READY]		= REG_FIELD(FXAS21002C_REG_CTRL1, 0, 0),
  98	[F_INT_CFG_FIFO]	= REG_FIELD(FXAS21002C_REG_CTRL2, 7, 7),
  99	[F_INT_EN_FIFO]		= REG_FIELD(FXAS21002C_REG_CTRL2, 6, 6),
 100	[F_INT_CFG_RT]		= REG_FIELD(FXAS21002C_REG_CTRL2, 5, 5),
 101	[F_INT_EN_RT]		= REG_FIELD(FXAS21002C_REG_CTRL2, 4, 4),
 102	[F_INT_CFG_DRDY]	= REG_FIELD(FXAS21002C_REG_CTRL2, 3, 3),
 103	[F_INT_EN_DRDY]		= REG_FIELD(FXAS21002C_REG_CTRL2, 2, 2),
 104	[F_IPOL]		= REG_FIELD(FXAS21002C_REG_CTRL2, 1, 1),
 105	[F_PP_OD]		= REG_FIELD(FXAS21002C_REG_CTRL2, 0, 0),
 106	[F_WRAPTOONE]		= REG_FIELD(FXAS21002C_REG_CTRL3, 3, 3),
 107	[F_EXTCTRLEN]		= REG_FIELD(FXAS21002C_REG_CTRL3, 2, 2),
 108	[F_FS_DOUBLE]		= REG_FIELD(FXAS21002C_REG_CTRL3, 0, 0),
 109};
 110
 111static const int fxas21002c_odr_values[] = {
 112	800, 400, 200, 100, 50, 25, 12, 12
 113};
 114
 115/*
 116 * These values are taken from the low-pass filter cutoff frequency calculated
 117 * ODR * 0.lpf_values. So, for ODR = 800Hz with a lpf value = 0.32
 118 * => LPF cutoff frequency = 800 * 0.32 = 256 Hz
 119 */
 120static const int fxas21002c_lpf_values[] = {
 121	32, 16, 8
 122};
 123
 124/*
 125 * These values are taken from the high-pass filter cutoff frequency calculated
 126 * ODR * 0.0hpf_values. So, for ODR = 800Hz with a hpf value = 0.018750
 127 * => HPF cutoff frequency = 800 * 0.018750 = 15 Hz
 128 */
 129static const int fxas21002c_hpf_values[] = {
 130	18750, 9625, 4875, 2475
 131};
 132
 133static const int fxas21002c_range_values[] = {
 134	4000, 2000, 1000, 500, 250
 135};
 136
 137struct fxas21002c_data {
 138	u8 chip_id;
 139	enum fxas21002c_mode_state mode;
 140	enum fxas21002c_mode_state prev_mode;
 141
 142	struct mutex lock;		/* serialize data access */
 143	struct regmap *regmap;
 144	struct regmap_field *regmap_fields[F_MAX_FIELDS];
 145	struct iio_trigger *dready_trig;
 146	s64 timestamp;
 147	int irq;
 148
 149	struct regulator *vdd;
 150	struct regulator *vddio;
 151
 152	/*
 153	 * DMA (thus cache coherency maintenance) may require the
 154	 * transfer buffers live in their own cache lines.
 155	 */
 156	s16 buffer[8] __aligned(IIO_DMA_MINALIGN);
 157};
 158
 159enum fxas21002c_channel_index {
 160	CHANNEL_SCAN_INDEX_X,
 161	CHANNEL_SCAN_INDEX_Y,
 162	CHANNEL_SCAN_INDEX_Z,
 163	CHANNEL_SCAN_MAX,
 164};
 165
 166static int fxas21002c_odr_hz_from_value(struct fxas21002c_data *data, u8 value)
 167{
 168	int odr_value_max = ARRAY_SIZE(fxas21002c_odr_values) - 1;
 169
 170	value = min_t(u8, value, odr_value_max);
 171
 172	return fxas21002c_odr_values[value];
 173}
 174
 175static int fxas21002c_odr_value_from_hz(struct fxas21002c_data *data,
 176					unsigned int hz)
 177{
 178	int odr_table_size = ARRAY_SIZE(fxas21002c_odr_values);
 179	int i;
 180
 181	for (i = 0; i < odr_table_size; i++)
 182		if (fxas21002c_odr_values[i] == hz)
 183			return i;
 184
 185	return -EINVAL;
 186}
 187
 188static int fxas21002c_lpf_bw_from_value(struct fxas21002c_data *data, u8 value)
 189{
 190	int lpf_value_max = ARRAY_SIZE(fxas21002c_lpf_values) - 1;
 191
 192	value = min_t(u8, value, lpf_value_max);
 193
 194	return fxas21002c_lpf_values[value];
 195}
 196
 197static int fxas21002c_lpf_value_from_bw(struct fxas21002c_data *data,
 198					unsigned int hz)
 199{
 200	int lpf_table_size = ARRAY_SIZE(fxas21002c_lpf_values);
 201	int i;
 202
 203	for (i = 0; i < lpf_table_size; i++)
 204		if (fxas21002c_lpf_values[i] == hz)
 205			return i;
 206
 207	return -EINVAL;
 208}
 209
 210static int fxas21002c_hpf_sel_from_value(struct fxas21002c_data *data, u8 value)
 211{
 212	int hpf_value_max = ARRAY_SIZE(fxas21002c_hpf_values) - 1;
 213
 214	value = min_t(u8, value, hpf_value_max);
 215
 216	return fxas21002c_hpf_values[value];
 217}
 218
 219static int fxas21002c_hpf_value_from_sel(struct fxas21002c_data *data,
 220					 unsigned int hz)
 221{
 222	int hpf_table_size = ARRAY_SIZE(fxas21002c_hpf_values);
 223	int i;
 224
 225	for (i = 0; i < hpf_table_size; i++)
 226		if (fxas21002c_hpf_values[i] == hz)
 227			return i;
 228
 229	return -EINVAL;
 230}
 231
 232static int fxas21002c_range_fs_from_value(struct fxas21002c_data *data,
 233					  u8 value)
 234{
 235	int range_value_max = ARRAY_SIZE(fxas21002c_range_values) - 1;
 236	unsigned int fs_double;
 237	int ret;
 238
 239	/* We need to check if FS_DOUBLE is enabled to offset the value */
 240	ret = regmap_field_read(data->regmap_fields[F_FS_DOUBLE], &fs_double);
 241	if (ret < 0)
 242		return ret;
 243
 244	if (!fs_double)
 245		value += 1;
 246
 247	value = min_t(u8, value, range_value_max);
 248
 249	return fxas21002c_range_values[value];
 250}
 251
 252static int fxas21002c_range_value_from_fs(struct fxas21002c_data *data,
 253					  unsigned int range)
 254{
 255	int range_table_size = ARRAY_SIZE(fxas21002c_range_values);
 256	bool found = false;
 257	int fs_double = 0;
 258	int ret;
 259	int i;
 260
 261	for (i = 0; i < range_table_size; i++)
 262		if (fxas21002c_range_values[i] == range) {
 263			found = true;
 264			break;
 265		}
 266
 267	if (!found)
 268		return -EINVAL;
 269
 270	if (range > FXAS21002C_RANGE_LIMIT_DOUBLE)
 271		fs_double = 1;
 272
 273	ret = regmap_field_write(data->regmap_fields[F_FS_DOUBLE], fs_double);
 274	if (ret < 0)
 275		return ret;
 276
 277	return i;
 278}
 279
 280static int fxas21002c_mode_get(struct fxas21002c_data *data)
 281{
 282	unsigned int active;
 283	unsigned int ready;
 284	int ret;
 285
 286	ret = regmap_field_read(data->regmap_fields[F_ACTIVE], &active);
 287	if (ret < 0)
 288		return ret;
 289	if (active)
 290		return FXAS21002C_MODE_ACTIVE;
 291
 292	ret = regmap_field_read(data->regmap_fields[F_READY], &ready);
 293	if (ret < 0)
 294		return ret;
 295	if (ready)
 296		return FXAS21002C_MODE_READY;
 297
 298	return FXAS21002C_MODE_STANDBY;
 299}
 300
 301static int fxas21002c_mode_set(struct fxas21002c_data *data,
 302			       enum fxas21002c_mode_state mode)
 303{
 304	int ret;
 305
 306	if (mode == data->mode)
 307		return 0;
 308
 309	if (mode == FXAS21002C_MODE_READY)
 310		ret = regmap_field_write(data->regmap_fields[F_READY], 1);
 311	else
 312		ret = regmap_field_write(data->regmap_fields[F_READY], 0);
 313	if (ret < 0)
 314		return ret;
 315
 316	if (mode == FXAS21002C_MODE_ACTIVE)
 317		ret = regmap_field_write(data->regmap_fields[F_ACTIVE], 1);
 318	else
 319		ret = regmap_field_write(data->regmap_fields[F_ACTIVE], 0);
 320	if (ret < 0)
 321		return ret;
 322
 323	/* if going to active wait the setup times */
 324	if (mode == FXAS21002C_MODE_ACTIVE &&
 325	    data->mode == FXAS21002C_MODE_STANDBY)
 326		msleep_interruptible(FXAS21002C_STANDBY_ACTIVE_TIME_MS);
 327
 328	if (data->mode == FXAS21002C_MODE_READY)
 329		msleep_interruptible(FXAS21002C_READY_ACTIVE_TIME_MS);
 330
 331	data->prev_mode = data->mode;
 332	data->mode = mode;
 333
 334	return ret;
 335}
 336
 337static int fxas21002c_write(struct fxas21002c_data *data,
 338			    enum fxas21002c_fields field, int bits)
 339{
 340	int actual_mode;
 341	int ret;
 342
 343	mutex_lock(&data->lock);
 344
 345	actual_mode = fxas21002c_mode_get(data);
 346	if (actual_mode < 0) {
 347		ret = actual_mode;
 348		goto out_unlock;
 349	}
 350
 351	ret = fxas21002c_mode_set(data, FXAS21002C_MODE_READY);
 352	if (ret < 0)
 353		goto out_unlock;
 354
 355	ret = regmap_field_write(data->regmap_fields[field], bits);
 356	if (ret < 0)
 357		goto out_unlock;
 358
 359	ret = fxas21002c_mode_set(data, data->prev_mode);
 360
 361out_unlock:
 362	mutex_unlock(&data->lock);
 363
 364	return ret;
 365}
 366
 367static int  fxas21002c_pm_get(struct fxas21002c_data *data)
 368{
 369	return pm_runtime_resume_and_get(regmap_get_device(data->regmap));
 370}
 371
 372static int  fxas21002c_pm_put(struct fxas21002c_data *data)
 373{
 374	struct device *dev = regmap_get_device(data->regmap);
 375
 376	return pm_runtime_put_autosuspend(dev);
 377}
 378
 379static int fxas21002c_temp_get(struct fxas21002c_data *data, int *val)
 380{
 381	struct device *dev = regmap_get_device(data->regmap);
 382	unsigned int temp;
 383	int ret;
 384
 385	mutex_lock(&data->lock);
 386	ret = fxas21002c_pm_get(data);
 387	if (ret < 0)
 388		goto data_unlock;
 389
 390	ret = regmap_field_read(data->regmap_fields[F_TEMP], &temp);
 391	if (ret < 0) {
 392		dev_err(dev, "failed to read temp: %d\n", ret);
 393		fxas21002c_pm_put(data);
 394		goto data_unlock;
 395	}
 396
 397	*val = sign_extend32(temp, 7);
 398
 399	ret = fxas21002c_pm_put(data);
 400	if (ret < 0)
 401		goto data_unlock;
 402
 403	ret = IIO_VAL_INT;
 404
 405data_unlock:
 406	mutex_unlock(&data->lock);
 407
 408	return ret;
 409}
 410
 411static int fxas21002c_axis_get(struct fxas21002c_data *data,
 412			       int index, int *val)
 413{
 414	struct device *dev = regmap_get_device(data->regmap);
 415	__be16 axis_be;
 416	int ret;
 417
 418	mutex_lock(&data->lock);
 419	ret = fxas21002c_pm_get(data);
 420	if (ret < 0)
 421		goto data_unlock;
 422
 423	ret = regmap_bulk_read(data->regmap, FXAS21002C_AXIS_TO_REG(index),
 424			       &axis_be, sizeof(axis_be));
 425	if (ret < 0) {
 426		dev_err(dev, "failed to read axis: %d: %d\n", index, ret);
 427		fxas21002c_pm_put(data);
 428		goto data_unlock;
 429	}
 430
 431	*val = sign_extend32(be16_to_cpu(axis_be), 15);
 432
 433	ret = fxas21002c_pm_put(data);
 434	if (ret < 0)
 435		goto data_unlock;
 436
 437	ret = IIO_VAL_INT;
 438
 439data_unlock:
 440	mutex_unlock(&data->lock);
 441
 442	return ret;
 443}
 444
 445static int fxas21002c_odr_get(struct fxas21002c_data *data, int *odr)
 446{
 447	unsigned int odr_bits;
 448	int ret;
 449
 450	mutex_lock(&data->lock);
 451	ret = regmap_field_read(data->regmap_fields[F_DR], &odr_bits);
 452	if (ret < 0)
 453		goto data_unlock;
 454
 455	*odr = fxas21002c_odr_hz_from_value(data, odr_bits);
 456
 457	ret = IIO_VAL_INT;
 458
 459data_unlock:
 460	mutex_unlock(&data->lock);
 461
 462	return ret;
 463}
 464
 465static int fxas21002c_odr_set(struct fxas21002c_data *data, int odr)
 466{
 467	int odr_bits;
 468
 469	odr_bits = fxas21002c_odr_value_from_hz(data, odr);
 470	if (odr_bits < 0)
 471		return odr_bits;
 472
 473	return fxas21002c_write(data, F_DR, odr_bits);
 474}
 475
 476static int fxas21002c_lpf_get(struct fxas21002c_data *data, int *val2)
 477{
 478	unsigned int bw_bits;
 479	int ret;
 480
 481	mutex_lock(&data->lock);
 482	ret = regmap_field_read(data->regmap_fields[F_BW], &bw_bits);
 483	if (ret < 0)
 484		goto data_unlock;
 485
 486	*val2 = fxas21002c_lpf_bw_from_value(data, bw_bits) * 10000;
 487
 488	ret = IIO_VAL_INT_PLUS_MICRO;
 489
 490data_unlock:
 491	mutex_unlock(&data->lock);
 492
 493	return ret;
 494}
 495
 496static int fxas21002c_lpf_set(struct fxas21002c_data *data, int bw)
 497{
 498	int bw_bits;
 499	int odr;
 500	int ret;
 501
 502	bw_bits = fxas21002c_lpf_value_from_bw(data, bw);
 503	if (bw_bits < 0)
 504		return bw_bits;
 505
 506	/*
 507	 * From table 33 of the device spec, for ODR = 25Hz and 12.5 value 0.08
 508	 * is not allowed and for ODR = 12.5 value 0.16 is also not allowed
 509	 */
 510	ret = fxas21002c_odr_get(data, &odr);
 511	if (ret < 0)
 512		return -EINVAL;
 513
 514	if ((odr == 25 && bw_bits > 0x01) || (odr == 12 && bw_bits > 0))
 515		return -EINVAL;
 516
 517	return fxas21002c_write(data, F_BW, bw_bits);
 518}
 519
 520static int fxas21002c_hpf_get(struct fxas21002c_data *data, int *val2)
 521{
 522	unsigned int sel_bits;
 523	int ret;
 524
 525	mutex_lock(&data->lock);
 526	ret = regmap_field_read(data->regmap_fields[F_SEL], &sel_bits);
 527	if (ret < 0)
 528		goto data_unlock;
 529
 530	*val2 = fxas21002c_hpf_sel_from_value(data, sel_bits);
 531
 532	ret = IIO_VAL_INT_PLUS_MICRO;
 533
 534data_unlock:
 535	mutex_unlock(&data->lock);
 536
 537	return ret;
 538}
 539
 540static int fxas21002c_hpf_set(struct fxas21002c_data *data, int sel)
 541{
 542	int sel_bits;
 543
 544	sel_bits = fxas21002c_hpf_value_from_sel(data, sel);
 545	if (sel_bits < 0)
 546		return sel_bits;
 547
 548	return fxas21002c_write(data, F_SEL, sel_bits);
 549}
 550
 551static int fxas21002c_scale_get(struct fxas21002c_data *data, int *val)
 552{
 553	int fs_bits;
 554	int scale;
 555	int ret;
 556
 557	mutex_lock(&data->lock);
 558	ret = regmap_field_read(data->regmap_fields[F_FS], &fs_bits);
 559	if (ret < 0)
 560		goto data_unlock;
 561
 562	scale = fxas21002c_range_fs_from_value(data, fs_bits);
 563	if (scale < 0) {
 564		ret = scale;
 565		goto data_unlock;
 566	}
 567
 568	*val = scale;
 569
 570data_unlock:
 571	mutex_unlock(&data->lock);
 572
 573	return ret;
 574}
 575
 576static int fxas21002c_scale_set(struct fxas21002c_data *data, int range)
 577{
 578	int fs_bits;
 579
 580	fs_bits = fxas21002c_range_value_from_fs(data, range);
 581	if (fs_bits < 0)
 582		return fs_bits;
 583
 584	return fxas21002c_write(data, F_FS, fs_bits);
 585}
 586
 587static int fxas21002c_read_raw(struct iio_dev *indio_dev,
 588			       struct iio_chan_spec const *chan, int *val,
 589			       int *val2, long mask)
 590{
 591	struct fxas21002c_data *data = iio_priv(indio_dev);
 592	int ret;
 593
 594	switch (mask) {
 595	case IIO_CHAN_INFO_RAW:
 596		switch (chan->type) {
 597		case IIO_TEMP:
 598			return fxas21002c_temp_get(data, val);
 599		case IIO_ANGL_VEL:
 600			return fxas21002c_axis_get(data, chan->scan_index, val);
 601		default:
 602			return -EINVAL;
 603		}
 604	case IIO_CHAN_INFO_SCALE:
 605		switch (chan->type) {
 606		case IIO_ANGL_VEL:
 607			*val2 = FXAS21002C_SCALE_FRACTIONAL;
 608			ret = fxas21002c_scale_get(data, val);
 609			if (ret < 0)
 610				return ret;
 611
 612			return IIO_VAL_FRACTIONAL;
 613		default:
 614			return -EINVAL;
 615		}
 616	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 617		*val = 0;
 618		return fxas21002c_lpf_get(data, val2);
 619	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
 620		*val = 0;
 621		return fxas21002c_hpf_get(data, val2);
 622	case IIO_CHAN_INFO_SAMP_FREQ:
 623		*val2 = 0;
 624		return fxas21002c_odr_get(data, val);
 625	default:
 626		return -EINVAL;
 627	}
 628}
 629
 630static int fxas21002c_write_raw(struct iio_dev *indio_dev,
 631				struct iio_chan_spec const *chan, int val,
 632				int val2, long mask)
 633{
 634	struct fxas21002c_data *data = iio_priv(indio_dev);
 635	int range;
 636
 637	switch (mask) {
 638	case IIO_CHAN_INFO_SAMP_FREQ:
 639		if (val2)
 640			return -EINVAL;
 641
 642		return fxas21002c_odr_set(data, val);
 643	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 644		if (val)
 645			return -EINVAL;
 646
 647		val2 = val2 / 10000;
 648		return fxas21002c_lpf_set(data, val2);
 649	case IIO_CHAN_INFO_SCALE:
 650		switch (chan->type) {
 651		case IIO_ANGL_VEL:
 652			range = (((val * 1000 + val2 / 1000) *
 653				  FXAS21002C_SCALE_FRACTIONAL) / 1000);
 654			return fxas21002c_scale_set(data, range);
 655		default:
 656			return -EINVAL;
 657		}
 658	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
 659		return fxas21002c_hpf_set(data, val2);
 660	default:
 661		return -EINVAL;
 662	}
 663}
 664
 665static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("12.5 25 50 100 200 400 800");
 666
 667static IIO_CONST_ATTR(in_anglvel_filter_low_pass_3db_frequency_available,
 668		      "0.32 0.16 0.08");
 669
 670static IIO_CONST_ATTR(in_anglvel_filter_high_pass_3db_frequency_available,
 671		      "0.018750 0.009625 0.004875 0.002475");
 672
 673static IIO_CONST_ATTR(in_anglvel_scale_available,
 674		      "125.0 62.5 31.25 15.625 7.8125");
 675
 676static struct attribute *fxas21002c_attributes[] = {
 677	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 678	&iio_const_attr_in_anglvel_filter_low_pass_3db_frequency_available.dev_attr.attr,
 679	&iio_const_attr_in_anglvel_filter_high_pass_3db_frequency_available.dev_attr.attr,
 680	&iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
 681	NULL,
 682};
 683
 684static const struct attribute_group fxas21002c_attrs_group = {
 685	.attrs = fxas21002c_attributes,
 686};
 687
 688#define FXAS21002C_CHANNEL(_axis) {					\
 689	.type = IIO_ANGL_VEL,						\
 690	.modified = 1,							\
 691	.channel2 = IIO_MOD_##_axis,					\
 692	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
 693	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
 694		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) |	\
 695		BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY) |	\
 696		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
 697	.scan_index = CHANNEL_SCAN_INDEX_##_axis,			\
 698	.scan_type = {							\
 699		.sign = 's',						\
 700		.realbits = 16,						\
 701		.storagebits = 16,					\
 702		.endianness = IIO_BE,					\
 703	},								\
 704}
 705
 706static const struct iio_chan_spec fxas21002c_channels[] = {
 707	{
 708		.type = IIO_TEMP,
 709		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 710		.scan_index = -1,
 711	},
 712	FXAS21002C_CHANNEL(X),
 713	FXAS21002C_CHANNEL(Y),
 714	FXAS21002C_CHANNEL(Z),
 715};
 716
 717static const struct iio_info fxas21002c_info = {
 718	.attrs			= &fxas21002c_attrs_group,
 719	.read_raw		= &fxas21002c_read_raw,
 720	.write_raw		= &fxas21002c_write_raw,
 721};
 722
 723static irqreturn_t fxas21002c_trigger_handler(int irq, void *p)
 724{
 725	struct iio_poll_func *pf = p;
 726	struct iio_dev *indio_dev = pf->indio_dev;
 727	struct fxas21002c_data *data = iio_priv(indio_dev);
 728	int ret;
 729
 730	mutex_lock(&data->lock);
 731	ret = fxas21002c_pm_get(data);
 732	if (ret < 0)
 733		goto out_unlock;
 734
 735	ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB,
 736			       data->buffer, CHANNEL_SCAN_MAX * sizeof(s16));
 737	if (ret < 0)
 738		goto out_pm_put;
 739
 740	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
 741					   data->timestamp);
 742
 743out_pm_put:
 744	fxas21002c_pm_put(data);
 745
 746out_unlock:
 747	mutex_unlock(&data->lock);
 748
 749	iio_trigger_notify_done(indio_dev->trig);
 750
 751	return IRQ_HANDLED;
 752}
 753
 754static int fxas21002c_chip_init(struct fxas21002c_data *data)
 755{
 756	struct device *dev = regmap_get_device(data->regmap);
 757	unsigned int chip_id;
 758	int ret;
 759
 760	ret = regmap_field_read(data->regmap_fields[F_WHO_AM_I], &chip_id);
 761	if (ret < 0)
 762		return ret;
 763
 764	if (chip_id != FXAS21002C_CHIP_ID_1 &&
 765	    chip_id != FXAS21002C_CHIP_ID_2) {
 766		dev_err(dev, "chip id 0x%02x is not supported\n", chip_id);
 767		return -EINVAL;
 768	}
 769
 770	data->chip_id = chip_id;
 771
 772	ret = fxas21002c_mode_set(data, FXAS21002C_MODE_STANDBY);
 773	if (ret < 0)
 774		return ret;
 775
 776	/* Set ODR to 200HZ as default */
 777	ret = fxas21002c_odr_set(data, 200);
 778	if (ret < 0)
 779		dev_err(dev, "failed to set ODR: %d\n", ret);
 780
 781	return ret;
 782}
 783
 784static int fxas21002c_data_rdy_trigger_set_state(struct iio_trigger *trig,
 785						 bool state)
 786{
 787	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
 788	struct fxas21002c_data *data = iio_priv(indio_dev);
 789
 790	return regmap_field_write(data->regmap_fields[F_INT_EN_DRDY], state);
 791}
 792
 793static const struct iio_trigger_ops fxas21002c_trigger_ops = {
 794	.set_trigger_state = &fxas21002c_data_rdy_trigger_set_state,
 795};
 796
 797static irqreturn_t fxas21002c_data_rdy_handler(int irq, void *private)
 798{
 799	struct iio_dev *indio_dev = private;
 800	struct fxas21002c_data *data = iio_priv(indio_dev);
 801
 802	data->timestamp = iio_get_time_ns(indio_dev);
 803
 804	return IRQ_WAKE_THREAD;
 805}
 806
 807static irqreturn_t fxas21002c_data_rdy_thread(int irq, void *private)
 808{
 809	struct iio_dev *indio_dev = private;
 810	struct fxas21002c_data *data = iio_priv(indio_dev);
 811	unsigned int data_ready;
 812	int ret;
 813
 814	ret = regmap_field_read(data->regmap_fields[F_SRC_DRDY], &data_ready);
 815	if (ret < 0)
 816		return IRQ_NONE;
 817
 818	if (!data_ready)
 819		return IRQ_NONE;
 820
 821	iio_trigger_poll_nested(data->dready_trig);
 822
 823	return IRQ_HANDLED;
 824}
 825
 826static int fxas21002c_trigger_probe(struct fxas21002c_data *data)
 827{
 828	struct device *dev = regmap_get_device(data->regmap);
 829	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 830	unsigned long irq_trig;
 831	bool irq_open_drain;
 832	int irq1;
 833	int ret;
 834
 835	if (!data->irq)
 836		return 0;
 837
 838	irq1 = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
 839	if (irq1 == data->irq) {
 840		dev_info(dev, "using interrupt line INT1\n");
 841		ret = regmap_field_write(data->regmap_fields[F_INT_CFG_DRDY],
 842					 1);
 843		if (ret < 0)
 844			return ret;
 845	}
 846
 847	dev_info(dev, "using interrupt line INT2\n");
 848
 849	irq_open_drain = device_property_read_bool(dev, "drive-open-drain");
 850
 851	data->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
 852						   indio_dev->name,
 853						   iio_device_id(indio_dev));
 854	if (!data->dready_trig)
 855		return -ENOMEM;
 856
 857	irq_trig = irq_get_trigger_type(data->irq);
 858	if (irq_trig == IRQF_TRIGGER_RISING) {
 859		ret = regmap_field_write(data->regmap_fields[F_IPOL], 1);
 860		if (ret < 0)
 861			return ret;
 862	}
 863
 864	if (irq_open_drain)
 865		irq_trig |= IRQF_SHARED;
 866
 867	ret = devm_request_threaded_irq(dev, data->irq,
 868					fxas21002c_data_rdy_handler,
 869					fxas21002c_data_rdy_thread,
 870					irq_trig, "fxas21002c_data_ready",
 871					indio_dev);
 872	if (ret < 0)
 873		return ret;
 874
 875	data->dready_trig->ops = &fxas21002c_trigger_ops;
 876	iio_trigger_set_drvdata(data->dready_trig, indio_dev);
 877
 878	return devm_iio_trigger_register(dev, data->dready_trig);
 879}
 880
 881static int fxas21002c_power_enable(struct fxas21002c_data *data)
 882{
 883	int ret;
 884
 885	ret = regulator_enable(data->vdd);
 886	if (ret < 0)
 887		return ret;
 888
 889	ret = regulator_enable(data->vddio);
 890	if (ret < 0) {
 891		regulator_disable(data->vdd);
 892		return ret;
 893	}
 894
 895	return 0;
 896}
 897
 898static void fxas21002c_power_disable(struct fxas21002c_data *data)
 899{
 900	regulator_disable(data->vdd);
 901	regulator_disable(data->vddio);
 902}
 903
 904static void fxas21002c_power_disable_action(void *_data)
 905{
 906	struct fxas21002c_data *data = _data;
 907
 908	fxas21002c_power_disable(data);
 909}
 910
 911static int fxas21002c_regulators_get(struct fxas21002c_data *data)
 912{
 913	struct device *dev = regmap_get_device(data->regmap);
 914
 915	data->vdd = devm_regulator_get(dev->parent, "vdd");
 916	if (IS_ERR(data->vdd))
 917		return PTR_ERR(data->vdd);
 918
 919	data->vddio = devm_regulator_get(dev->parent, "vddio");
 920
 921	return PTR_ERR_OR_ZERO(data->vddio);
 922}
 923
 924int fxas21002c_core_probe(struct device *dev, struct regmap *regmap, int irq,
 925			  const char *name)
 926{
 927	struct fxas21002c_data *data;
 928	struct iio_dev *indio_dev;
 929	struct regmap_field *f;
 930	int i;
 931	int ret;
 932
 933	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 934	if (!indio_dev)
 935		return -ENOMEM;
 936
 937	data = iio_priv(indio_dev);
 938	dev_set_drvdata(dev, indio_dev);
 939	data->irq = irq;
 940	data->regmap = regmap;
 941
 942	for (i = 0; i < F_MAX_FIELDS; i++) {
 943		f = devm_regmap_field_alloc(dev, data->regmap,
 944					    fxas21002c_reg_fields[i]);
 945		if (IS_ERR(f))
 946			return PTR_ERR(f);
 947
 948		data->regmap_fields[i] = f;
 949	}
 950
 951	mutex_init(&data->lock);
 952
 953	ret = fxas21002c_regulators_get(data);
 954	if (ret < 0)
 955		return ret;
 956
 957	ret = fxas21002c_power_enable(data);
 958	if (ret < 0)
 959		return ret;
 960
 961	ret = devm_add_action_or_reset(dev, fxas21002c_power_disable_action,
 962				       data);
 963	if (ret < 0)
 964		return ret;
 965
 966	ret = fxas21002c_chip_init(data);
 967	if (ret < 0)
 968		return ret;
 969
 970	indio_dev->channels = fxas21002c_channels;
 971	indio_dev->num_channels = ARRAY_SIZE(fxas21002c_channels);
 972	indio_dev->name = name;
 973	indio_dev->modes = INDIO_DIRECT_MODE;
 974	indio_dev->info = &fxas21002c_info;
 975
 976	ret = fxas21002c_trigger_probe(data);
 977	if (ret < 0)
 978		return ret;
 979
 980	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
 981					      fxas21002c_trigger_handler, NULL);
 982	if (ret < 0)
 983		return ret;
 984
 985	ret = pm_runtime_set_active(dev);
 986	if (ret)
 987		return ret;
 988
 989	pm_runtime_enable(dev);
 990	pm_runtime_set_autosuspend_delay(dev, 2000);
 991	pm_runtime_use_autosuspend(dev);
 992
 993	ret = iio_device_register(indio_dev);
 994	if (ret < 0)
 995		goto pm_disable;
 996
 997	return 0;
 998
 999pm_disable:
1000	pm_runtime_disable(dev);
1001	pm_runtime_set_suspended(dev);
1002
1003	return ret;
1004}
1005EXPORT_SYMBOL_NS_GPL(fxas21002c_core_probe, "IIO_FXAS21002C");
1006
1007void fxas21002c_core_remove(struct device *dev)
1008{
1009	struct iio_dev *indio_dev = dev_get_drvdata(dev);
1010
1011	iio_device_unregister(indio_dev);
1012
1013	pm_runtime_disable(dev);
1014	pm_runtime_set_suspended(dev);
1015}
1016EXPORT_SYMBOL_NS_GPL(fxas21002c_core_remove, "IIO_FXAS21002C");
1017
1018static int fxas21002c_suspend(struct device *dev)
1019{
1020	struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev));
1021
1022	fxas21002c_mode_set(data, FXAS21002C_MODE_STANDBY);
1023	fxas21002c_power_disable(data);
1024
1025	return 0;
1026}
1027
1028static int fxas21002c_resume(struct device *dev)
1029{
1030	struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev));
1031	int ret;
1032
1033	ret = fxas21002c_power_enable(data);
1034	if (ret < 0)
1035		return ret;
1036
1037	return fxas21002c_mode_set(data, data->prev_mode);
1038}
1039
1040static int fxas21002c_runtime_suspend(struct device *dev)
1041{
1042	struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev));
1043
1044	return fxas21002c_mode_set(data, FXAS21002C_MODE_READY);
1045}
1046
1047static int fxas21002c_runtime_resume(struct device *dev)
1048{
1049	struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev));
1050
1051	return fxas21002c_mode_set(data, FXAS21002C_MODE_ACTIVE);
1052}
1053
1054EXPORT_NS_GPL_DEV_PM_OPS(fxas21002c_pm_ops, IIO_FXAS21002C) = {
1055	SYSTEM_SLEEP_PM_OPS(fxas21002c_suspend, fxas21002c_resume)
1056	RUNTIME_PM_OPS(fxas21002c_runtime_suspend, fxas21002c_runtime_resume,
1057		       NULL)
1058};
1059
1060MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>");
1061MODULE_LICENSE("GPL v2");
1062MODULE_DESCRIPTION("FXAS21002C Gyro driver");
~/ Read-only file preview.