xref: /linux/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2020 Invensense, Inc.
4  */
5 
6 #include <linux/kernel.h>
7 #include <linux/device.h>
8 #include <linux/module.h>
9 #include <linux/slab.h>
10 #include <linux/delay.h>
11 #include <linux/mutex.h>
12 #include <linux/interrupt.h>
13 #include <linux/irq.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/property.h>
17 #include <linux/regmap.h>
18 
19 #include <linux/iio/iio.h>
20 
21 #include "inv_icm42600.h"
22 #include "inv_icm42600_buffer.h"
23 
24 static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = {
25 	{
26 		.name = "user banks",
27 		.range_min = 0x0000,
28 		.range_max = 0x4FFF,
29 		.selector_reg = INV_ICM42600_REG_BANK_SEL,
30 		.selector_mask = INV_ICM42600_BANK_SEL_MASK,
31 		.selector_shift = 0,
32 		.window_start = 0,
33 		.window_len = 0x1000,
34 	},
35 };
36 
37 static const struct regmap_range inv_icm42600_regmap_volatile_yes_ranges[] = {
38 	/* Sensor data registers */
39 	regmap_reg_range(0x001D, 0x002A),
40 	/* INT status, FIFO, APEX data */
41 	regmap_reg_range(0x002D, 0x0038),
42 	/* Signal path reset */
43 	regmap_reg_range(0x004B, 0x004B),
44 	/* FIFO lost packets */
45 	regmap_reg_range(0x006C, 0x006D),
46 	/* Timestamp value */
47 	regmap_reg_range(0x1062, 0x1064),
48 };
49 
50 static const struct regmap_range inv_icm42600_regmap_volatile_no_ranges[] = {
51 	regmap_reg_range(0x0000, 0x001C),
52 	regmap_reg_range(0x006E, 0x1061),
53 	regmap_reg_range(0x1065, 0x4FFF),
54 };
55 
56 static const struct regmap_access_table inv_icm42600_regmap_volatile_accesses[] = {
57 	{
58 		.yes_ranges = inv_icm42600_regmap_volatile_yes_ranges,
59 		.n_yes_ranges = ARRAY_SIZE(inv_icm42600_regmap_volatile_yes_ranges),
60 		.no_ranges = inv_icm42600_regmap_volatile_no_ranges,
61 		.n_no_ranges = ARRAY_SIZE(inv_icm42600_regmap_volatile_no_ranges),
62 	},
63 };
64 
65 static const struct regmap_range inv_icm42600_regmap_rd_noinc_no_ranges[] = {
66 	regmap_reg_range(0x0000, INV_ICM42600_REG_FIFO_DATA - 1),
67 	regmap_reg_range(INV_ICM42600_REG_FIFO_DATA + 1, 0x4FFF),
68 };
69 
70 static const struct regmap_access_table inv_icm42600_regmap_rd_noinc_accesses[] = {
71 	{
72 		.no_ranges = inv_icm42600_regmap_rd_noinc_no_ranges,
73 		.n_no_ranges = ARRAY_SIZE(inv_icm42600_regmap_rd_noinc_no_ranges),
74 	},
75 };
76 
77 const struct regmap_config inv_icm42600_regmap_config = {
78 	.name = "inv_icm42600",
79 	.reg_bits = 8,
80 	.val_bits = 8,
81 	.max_register = 0x4FFF,
82 	.ranges = inv_icm42600_regmap_ranges,
83 	.num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
84 	.volatile_table = inv_icm42600_regmap_volatile_accesses,
85 	.rd_noinc_table = inv_icm42600_regmap_rd_noinc_accesses,
86 	.cache_type = REGCACHE_MAPLE,
87 };
88 EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, "IIO_ICM42600");
89 
90 /* define specific regmap for SPI not supporting burst write */
91 const struct regmap_config inv_icm42600_spi_regmap_config = {
92 	.name = "inv_icm42600",
93 	.reg_bits = 8,
94 	.val_bits = 8,
95 	.max_register = 0x4FFF,
96 	.ranges = inv_icm42600_regmap_ranges,
97 	.num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
98 	.volatile_table = inv_icm42600_regmap_volatile_accesses,
99 	.rd_noinc_table = inv_icm42600_regmap_rd_noinc_accesses,
100 	.cache_type = REGCACHE_MAPLE,
101 	.use_single_write = true,
102 };
103 EXPORT_SYMBOL_NS_GPL(inv_icm42600_spi_regmap_config, "IIO_ICM42600");
104 
105 struct inv_icm42600_hw {
106 	u8 whoami;
107 	const char *name;
108 	const struct inv_icm42600_conf *conf;
109 };
110 
111 /* chip initial default configuration */
112 static const struct inv_icm42600_conf inv_icm42600_default_conf = {
113 	.gyro = {
114 		.mode = INV_ICM42600_SENSOR_MODE_OFF,
115 		.fs = INV_ICM42600_GYRO_FS_2000DPS,
116 		.odr = INV_ICM42600_ODR_50HZ,
117 		.filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
118 	},
119 	.accel = {
120 		.mode = INV_ICM42600_SENSOR_MODE_OFF,
121 		.fs = INV_ICM42600_ACCEL_FS_16G,
122 		.odr = INV_ICM42600_ODR_50HZ,
123 		.filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
124 	},
125 	.temp_en = false,
126 };
127 
128 static const struct inv_icm42600_conf inv_icm42686_default_conf = {
129 	.gyro = {
130 		.mode = INV_ICM42600_SENSOR_MODE_OFF,
131 		.fs = INV_ICM42686_GYRO_FS_4000DPS,
132 		.odr = INV_ICM42600_ODR_50HZ,
133 		.filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
134 	},
135 	.accel = {
136 		.mode = INV_ICM42600_SENSOR_MODE_OFF,
137 		.fs = INV_ICM42686_ACCEL_FS_32G,
138 		.odr = INV_ICM42600_ODR_50HZ,
139 		.filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
140 	},
141 	.temp_en = false,
142 };
143 
144 static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
145 	[INV_CHIP_ICM42600] = {
146 		.whoami = INV_ICM42600_WHOAMI_ICM42600,
147 		.name = "icm42600",
148 		.conf = &inv_icm42600_default_conf,
149 	},
150 	[INV_CHIP_ICM42602] = {
151 		.whoami = INV_ICM42600_WHOAMI_ICM42602,
152 		.name = "icm42602",
153 		.conf = &inv_icm42600_default_conf,
154 	},
155 	[INV_CHIP_ICM42605] = {
156 		.whoami = INV_ICM42600_WHOAMI_ICM42605,
157 		.name = "icm42605",
158 		.conf = &inv_icm42600_default_conf,
159 	},
160 	[INV_CHIP_ICM42686] = {
161 		.whoami = INV_ICM42600_WHOAMI_ICM42686,
162 		.name = "icm42686",
163 		.conf = &inv_icm42686_default_conf,
164 	},
165 	[INV_CHIP_ICM42622] = {
166 		.whoami = INV_ICM42600_WHOAMI_ICM42622,
167 		.name = "icm42622",
168 		.conf = &inv_icm42600_default_conf,
169 	},
170 	[INV_CHIP_ICM42688] = {
171 		.whoami = INV_ICM42600_WHOAMI_ICM42688,
172 		.name = "icm42688",
173 		.conf = &inv_icm42600_default_conf,
174 	},
175 	[INV_CHIP_ICM42631] = {
176 		.whoami = INV_ICM42600_WHOAMI_ICM42631,
177 		.name = "icm42631",
178 		.conf = &inv_icm42600_default_conf,
179 	},
180 };
181 
182 const struct iio_mount_matrix *
inv_icm42600_get_mount_matrix(const struct iio_dev * indio_dev,const struct iio_chan_spec * chan)183 inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev,
184 			      const struct iio_chan_spec *chan)
185 {
186 	const struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
187 
188 	return &st->orientation;
189 }
190 
inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)191 u32 inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)
192 {
193 	static u32 odr_periods[INV_ICM42600_ODR_NB] = {
194 		/* reserved values */
195 		0, 0, 0,
196 		/* 8kHz */
197 		125000,
198 		/* 4kHz */
199 		250000,
200 		/* 2kHz */
201 		500000,
202 		/* 1kHz */
203 		1000000,
204 		/* 200Hz */
205 		5000000,
206 		/* 100Hz */
207 		10000000,
208 		/* 50Hz */
209 		20000000,
210 		/* 25Hz */
211 		40000000,
212 		/* 12.5Hz */
213 		80000000,
214 		/* 6.25Hz */
215 		160000000,
216 		/* 3.125Hz */
217 		320000000,
218 		/* 1.5625Hz */
219 		640000000,
220 		/* 500Hz */
221 		2000000,
222 	};
223 
224 	return odr_periods[odr];
225 }
226 
inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state * st,enum inv_icm42600_sensor_mode gyro,enum inv_icm42600_sensor_mode accel,bool temp,unsigned int * sleep_ms)227 static int inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state *st,
228 				      enum inv_icm42600_sensor_mode gyro,
229 				      enum inv_icm42600_sensor_mode accel,
230 				      bool temp, unsigned int *sleep_ms)
231 {
232 	enum inv_icm42600_sensor_mode oldgyro = st->conf.gyro.mode;
233 	enum inv_icm42600_sensor_mode oldaccel = st->conf.accel.mode;
234 	bool oldtemp = st->conf.temp_en;
235 	unsigned int sleepval;
236 	unsigned int val;
237 	int ret;
238 
239 	/* if nothing changed, exit */
240 	if (gyro == oldgyro && accel == oldaccel && temp == oldtemp)
241 		return 0;
242 
243 	val = INV_ICM42600_PWR_MGMT0_GYRO(gyro) |
244 	      INV_ICM42600_PWR_MGMT0_ACCEL(accel);
245 	if (!temp)
246 		val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS;
247 	ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val);
248 	if (ret)
249 		return ret;
250 
251 	st->conf.gyro.mode = gyro;
252 	st->conf.accel.mode = accel;
253 	st->conf.temp_en = temp;
254 
255 	/* compute required wait time for sensors to stabilize */
256 	sleepval = 0;
257 	/* temperature stabilization time */
258 	if (temp && !oldtemp) {
259 		if (sleepval < INV_ICM42600_TEMP_STARTUP_TIME_MS)
260 			sleepval = INV_ICM42600_TEMP_STARTUP_TIME_MS;
261 	}
262 	/* accel startup time */
263 	if (accel != oldaccel && oldaccel == INV_ICM42600_SENSOR_MODE_OFF) {
264 		/* block any register write for at least 200 µs */
265 		usleep_range(200, 300);
266 		if (sleepval < INV_ICM42600_ACCEL_STARTUP_TIME_MS)
267 			sleepval = INV_ICM42600_ACCEL_STARTUP_TIME_MS;
268 	}
269 	if (gyro != oldgyro) {
270 		/* gyro startup time */
271 		if (oldgyro == INV_ICM42600_SENSOR_MODE_OFF) {
272 			/* block any register write for at least 200 µs */
273 			usleep_range(200, 300);
274 			if (sleepval < INV_ICM42600_GYRO_STARTUP_TIME_MS)
275 				sleepval = INV_ICM42600_GYRO_STARTUP_TIME_MS;
276 		/* gyro stop time */
277 		} else if (gyro == INV_ICM42600_SENSOR_MODE_OFF) {
278 			if (sleepval < INV_ICM42600_GYRO_STOP_TIME_MS)
279 				sleepval =  INV_ICM42600_GYRO_STOP_TIME_MS;
280 		}
281 	}
282 
283 	/* deferred sleep value if sleep pointer is provided or direct sleep */
284 	if (sleep_ms)
285 		*sleep_ms = sleepval;
286 	else if (sleepval)
287 		msleep(sleepval);
288 
289 	return 0;
290 }
291 
inv_icm42600_set_accel_conf(struct inv_icm42600_state * st,struct inv_icm42600_sensor_conf * conf,unsigned int * sleep_ms)292 int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st,
293 				struct inv_icm42600_sensor_conf *conf,
294 				unsigned int *sleep_ms)
295 {
296 	struct inv_icm42600_sensor_conf *oldconf = &st->conf.accel;
297 	unsigned int val;
298 	int ret;
299 
300 	/* Sanitize missing values with current values */
301 	if (conf->mode < 0)
302 		conf->mode = oldconf->mode;
303 	if (conf->fs < 0)
304 		conf->fs = oldconf->fs;
305 	if (conf->odr < 0)
306 		conf->odr = oldconf->odr;
307 	if (conf->filter < 0)
308 		conf->filter = oldconf->filter;
309 
310 	/* force power mode against ODR when sensor is on */
311 	switch (conf->mode) {
312 	case INV_ICM42600_SENSOR_MODE_LOW_POWER:
313 	case INV_ICM42600_SENSOR_MODE_LOW_NOISE:
314 		if (conf->odr <= INV_ICM42600_ODR_1KHZ_LN) {
315 			conf->mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE;
316 			conf->filter = INV_ICM42600_FILTER_BW_ODR_DIV_2;
317 		} else if (conf->odr >= INV_ICM42600_ODR_6_25HZ_LP &&
318 			   conf->odr <= INV_ICM42600_ODR_1_5625HZ_LP) {
319 			conf->mode = INV_ICM42600_SENSOR_MODE_LOW_POWER;
320 			conf->filter = INV_ICM42600_FILTER_AVG_16X;
321 		}
322 		break;
323 	default:
324 		break;
325 	}
326 
327 	/* set ACCEL_CONFIG0 register (accel fullscale & odr) */
328 	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
329 		val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->fs) |
330 		      INV_ICM42600_ACCEL_CONFIG0_ODR(conf->odr);
331 		ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val);
332 		if (ret)
333 			return ret;
334 		oldconf->fs = conf->fs;
335 		oldconf->odr = conf->odr;
336 	}
337 
338 	/* set GYRO_ACCEL_CONFIG0 register (accel filter) */
339 	if (conf->filter != oldconf->filter) {
340 		val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->filter) |
341 		      INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(st->conf.gyro.filter);
342 		ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
343 		if (ret)
344 			return ret;
345 		oldconf->filter = conf->filter;
346 	}
347 
348 	/* set PWR_MGMT0 register (accel sensor mode) */
349 	return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode,
350 					  st->conf.temp_en, sleep_ms);
351 }
352 
inv_icm42600_set_gyro_conf(struct inv_icm42600_state * st,struct inv_icm42600_sensor_conf * conf,unsigned int * sleep_ms)353 int inv_icm42600_set_gyro_conf(struct inv_icm42600_state *st,
354 			       struct inv_icm42600_sensor_conf *conf,
355 			       unsigned int *sleep_ms)
356 {
357 	struct inv_icm42600_sensor_conf *oldconf = &st->conf.gyro;
358 	unsigned int val;
359 	int ret;
360 
361 	/* sanitize missing values with current values */
362 	if (conf->mode < 0)
363 		conf->mode = oldconf->mode;
364 	if (conf->fs < 0)
365 		conf->fs = oldconf->fs;
366 	if (conf->odr < 0)
367 		conf->odr = oldconf->odr;
368 	if (conf->filter < 0)
369 		conf->filter = oldconf->filter;
370 
371 	/* set GYRO_CONFIG0 register (gyro fullscale & odr) */
372 	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
373 		val = INV_ICM42600_GYRO_CONFIG0_FS(conf->fs) |
374 		      INV_ICM42600_GYRO_CONFIG0_ODR(conf->odr);
375 		ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val);
376 		if (ret)
377 			return ret;
378 		oldconf->fs = conf->fs;
379 		oldconf->odr = conf->odr;
380 	}
381 
382 	/* set GYRO_ACCEL_CONFIG0 register (gyro filter) */
383 	if (conf->filter != oldconf->filter) {
384 		val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(st->conf.accel.filter) |
385 		      INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->filter);
386 		ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
387 		if (ret)
388 			return ret;
389 		oldconf->filter = conf->filter;
390 	}
391 
392 	/* set PWR_MGMT0 register (gyro sensor mode) */
393 	return inv_icm42600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode,
394 					  st->conf.temp_en, sleep_ms);
395 
396 	return 0;
397 }
398 
inv_icm42600_set_temp_conf(struct inv_icm42600_state * st,bool enable,unsigned int * sleep_ms)399 int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable,
400 			       unsigned int *sleep_ms)
401 {
402 	return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode,
403 					  st->conf.accel.mode, enable,
404 					  sleep_ms);
405 }
406 
inv_icm42600_enable_wom(struct inv_icm42600_state * st)407 int inv_icm42600_enable_wom(struct inv_icm42600_state *st)
408 {
409 	int ret;
410 
411 	/* enable WoM hardware */
412 	ret = regmap_write(st->map, INV_ICM42600_REG_SMD_CONFIG,
413 			   INV_ICM42600_SMD_CONFIG_SMD_MODE_WOM |
414 			   INV_ICM42600_SMD_CONFIG_WOM_MODE);
415 	if (ret)
416 		return ret;
417 
418 	/* enable WoM interrupt */
419 	return regmap_set_bits(st->map, INV_ICM42600_REG_INT_SOURCE1,
420 			      INV_ICM42600_INT_SOURCE1_WOM_INT1_EN);
421 }
422 
inv_icm42600_disable_wom(struct inv_icm42600_state * st)423 int inv_icm42600_disable_wom(struct inv_icm42600_state *st)
424 {
425 	int ret;
426 
427 	/* disable WoM interrupt */
428 	ret = regmap_clear_bits(st->map, INV_ICM42600_REG_INT_SOURCE1,
429 				INV_ICM42600_INT_SOURCE1_WOM_INT1_EN);
430 	if (ret)
431 		return ret;
432 
433 	/* disable WoM hardware */
434 	return regmap_write(st->map, INV_ICM42600_REG_SMD_CONFIG,
435 			    INV_ICM42600_SMD_CONFIG_SMD_MODE_OFF);
436 }
437 
inv_icm42600_debugfs_reg(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)438 int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,
439 			     unsigned int writeval, unsigned int *readval)
440 {
441 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
442 	int ret;
443 
444 	mutex_lock(&st->lock);
445 
446 	if (readval)
447 		ret = regmap_read(st->map, reg, readval);
448 	else
449 		ret = regmap_write(st->map, reg, writeval);
450 
451 	mutex_unlock(&st->lock);
452 
453 	return ret;
454 }
455 
inv_icm42600_set_conf(struct inv_icm42600_state * st,const struct inv_icm42600_conf * conf)456 static int inv_icm42600_set_conf(struct inv_icm42600_state *st,
457 				 const struct inv_icm42600_conf *conf)
458 {
459 	unsigned int val;
460 	int ret;
461 
462 	/* set PWR_MGMT0 register (gyro & accel sensor mode, temp enabled) */
463 	val = INV_ICM42600_PWR_MGMT0_GYRO(conf->gyro.mode) |
464 	      INV_ICM42600_PWR_MGMT0_ACCEL(conf->accel.mode);
465 	if (!conf->temp_en)
466 		val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS;
467 	ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val);
468 	if (ret)
469 		return ret;
470 
471 	/* set GYRO_CONFIG0 register (gyro fullscale & odr) */
472 	val = INV_ICM42600_GYRO_CONFIG0_FS(conf->gyro.fs) |
473 	      INV_ICM42600_GYRO_CONFIG0_ODR(conf->gyro.odr);
474 	ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val);
475 	if (ret)
476 		return ret;
477 
478 	/* set ACCEL_CONFIG0 register (accel fullscale & odr) */
479 	val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->accel.fs) |
480 	      INV_ICM42600_ACCEL_CONFIG0_ODR(conf->accel.odr);
481 	ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val);
482 	if (ret)
483 		return ret;
484 
485 	/* set GYRO_ACCEL_CONFIG0 register (gyro & accel filters) */
486 	val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->accel.filter) |
487 	      INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->gyro.filter);
488 	ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
489 	if (ret)
490 		return ret;
491 
492 	/* update internal conf */
493 	st->conf = *conf;
494 
495 	return 0;
496 }
497 
498 /**
499  *  inv_icm42600_setup() - check and setup chip
500  *  @st:	driver internal state
501  *  @bus_setup:	callback for setting up bus specific registers
502  *
503  *  Returns 0 on success, a negative error code otherwise.
504  */
inv_icm42600_setup(struct inv_icm42600_state * st,inv_icm42600_bus_setup bus_setup)505 static int inv_icm42600_setup(struct inv_icm42600_state *st,
506 			      inv_icm42600_bus_setup bus_setup)
507 {
508 	const struct inv_icm42600_hw *hw = &inv_icm42600_hw[st->chip];
509 	const struct device *dev = regmap_get_device(st->map);
510 	unsigned int val;
511 	int ret;
512 
513 	/* check chip self-identification value */
514 	ret = regmap_read(st->map, INV_ICM42600_REG_WHOAMI, &val);
515 	if (ret)
516 		return ret;
517 	if (val != hw->whoami) {
518 		dev_err(dev, "invalid whoami %#02x expected %#02x (%s)\n",
519 			val, hw->whoami, hw->name);
520 		return -ENODEV;
521 	}
522 	st->name = hw->name;
523 
524 	/* reset to make sure previous state are not there */
525 	ret = regmap_write(st->map, INV_ICM42600_REG_DEVICE_CONFIG,
526 			   INV_ICM42600_DEVICE_CONFIG_SOFT_RESET);
527 	if (ret)
528 		return ret;
529 	msleep(INV_ICM42600_RESET_TIME_MS);
530 
531 	ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &val);
532 	if (ret)
533 		return ret;
534 	if (!(val & INV_ICM42600_INT_STATUS_RESET_DONE)) {
535 		dev_err(dev, "reset error, reset done bit not set\n");
536 		return -ENODEV;
537 	}
538 
539 	/* set chip bus configuration */
540 	ret = bus_setup(st);
541 	if (ret)
542 		return ret;
543 
544 	/* sensor data in big-endian (default) */
545 	ret = regmap_set_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
546 			      INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN);
547 	if (ret)
548 		return ret;
549 
550 	/*
551 	 * Use RC clock for accel low-power to fix glitches when switching
552 	 * gyro on/off while accel low-power is on.
553 	 */
554 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG1,
555 				 INV_ICM42600_INTF_CONFIG1_ACCEL_LP_CLK_RC,
556 				 INV_ICM42600_INTF_CONFIG1_ACCEL_LP_CLK_RC);
557 	if (ret)
558 		return ret;
559 
560 	return inv_icm42600_set_conf(st, hw->conf);
561 }
562 
inv_icm42600_irq_timestamp(int irq,void * _data)563 static irqreturn_t inv_icm42600_irq_timestamp(int irq, void *_data)
564 {
565 	struct inv_icm42600_state *st = _data;
566 
567 	st->timestamp.gyro = iio_get_time_ns(st->indio_gyro);
568 	st->timestamp.accel = iio_get_time_ns(st->indio_accel);
569 
570 	return IRQ_WAKE_THREAD;
571 }
572 
inv_icm42600_irq_handler(int irq,void * _data)573 static irqreturn_t inv_icm42600_irq_handler(int irq, void *_data)
574 {
575 	struct inv_icm42600_state *st = _data;
576 	struct device *dev = regmap_get_device(st->map);
577 	unsigned int status;
578 	int ret;
579 
580 	mutex_lock(&st->lock);
581 
582 	if (st->apex.on) {
583 		unsigned int status2, status3;
584 
585 		/* read INT_STATUS2 and INT_STATUS3 in 1 operation */
586 		ret = regmap_bulk_read(st->map, INV_ICM42600_REG_INT_STATUS2, st->buffer, 2);
587 		if (ret)
588 			goto out_unlock;
589 		status2 = st->buffer[0];
590 		status3 = st->buffer[1];
591 		inv_icm42600_accel_handle_events(st->indio_accel, status2, status3,
592 						 st->timestamp.accel);
593 	}
594 
595 	ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &status);
596 	if (ret)
597 		goto out_unlock;
598 
599 	/* FIFO full */
600 	if (status & INV_ICM42600_INT_STATUS_FIFO_FULL)
601 		dev_warn(dev, "FIFO full data lost!\n");
602 
603 	/* FIFO threshold reached */
604 	if (status & INV_ICM42600_INT_STATUS_FIFO_THS) {
605 		ret = inv_icm42600_buffer_fifo_read(st, 0);
606 		if (ret) {
607 			dev_err(dev, "FIFO read error %d\n", ret);
608 			goto out_unlock;
609 		}
610 		ret = inv_icm42600_buffer_fifo_parse(st);
611 		if (ret)
612 			dev_err(dev, "FIFO parsing error %d\n", ret);
613 	}
614 
615 out_unlock:
616 	mutex_unlock(&st->lock);
617 	return IRQ_HANDLED;
618 }
619 
620 /**
621  * inv_icm42600_irq_init() - initialize int pin and interrupt handler
622  * @st:		driver internal state
623  * @irq:	irq number
624  * @irq_type:	irq trigger type
625  * @open_drain:	true if irq is open drain, false for push-pull
626  *
627  * Returns 0 on success, a negative error code otherwise.
628  */
inv_icm42600_irq_init(struct inv_icm42600_state * st,int irq,int irq_type,bool open_drain)629 static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq,
630 				 int irq_type, bool open_drain)
631 {
632 	struct device *dev = regmap_get_device(st->map);
633 	unsigned int val;
634 	int ret;
635 
636 	/* configure INT1 interrupt: default is active low on edge */
637 	switch (irq_type) {
638 	case IRQF_TRIGGER_RISING:
639 	case IRQF_TRIGGER_HIGH:
640 		val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_HIGH;
641 		break;
642 	default:
643 		val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW;
644 		break;
645 	}
646 
647 	switch (irq_type) {
648 	case IRQF_TRIGGER_LOW:
649 	case IRQF_TRIGGER_HIGH:
650 		val |= INV_ICM42600_INT_CONFIG_INT1_LATCHED;
651 		break;
652 	default:
653 		break;
654 	}
655 
656 	if (!open_drain)
657 		val |= INV_ICM42600_INT_CONFIG_INT1_PUSH_PULL;
658 
659 	ret = regmap_write(st->map, INV_ICM42600_REG_INT_CONFIG, val);
660 	if (ret)
661 		return ret;
662 
663 	/* Deassert async reset for proper INT pin operation (cf datasheet) */
664 	ret = regmap_clear_bits(st->map, INV_ICM42600_REG_INT_CONFIG1,
665 				INV_ICM42600_INT_CONFIG1_ASYNC_RESET);
666 	if (ret)
667 		return ret;
668 
669 	irq_type |= IRQF_ONESHOT;
670 	return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
671 					 inv_icm42600_irq_handler, irq_type,
672 					 "inv_icm42600", st);
673 }
674 
inv_icm42600_timestamp_setup(struct inv_icm42600_state * st)675 static int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st)
676 {
677 	unsigned int val;
678 
679 	/* enable timestamp register */
680 	val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN |
681 	      INV_ICM42600_TMST_CONFIG_TMST_EN;
682 	return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG,
683 				  INV_ICM42600_TMST_CONFIG_MASK, val);
684 }
685 
inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state * st)686 static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st)
687 {
688 	int ret;
689 
690 	ret = regulator_enable(st->vddio_supply);
691 	if (ret)
692 		return ret;
693 
694 	/* wait a little for supply ramp */
695 	usleep_range(3000, 4000);
696 
697 	return 0;
698 }
699 
inv_icm42600_disable_vdd_reg(void * _data)700 static void inv_icm42600_disable_vdd_reg(void *_data)
701 {
702 	struct inv_icm42600_state *st = _data;
703 	const struct device *dev = regmap_get_device(st->map);
704 	int ret;
705 
706 	ret = regulator_disable(st->vdd_supply);
707 	if (ret)
708 		dev_err(dev, "failed to disable vdd error %d\n", ret);
709 }
710 
inv_icm42600_disable_vddio_reg(void * _data)711 static void inv_icm42600_disable_vddio_reg(void *_data)
712 {
713 	struct inv_icm42600_state *st = _data;
714 	const struct device *dev = regmap_get_device(st->map);
715 	int ret;
716 
717 	ret = regulator_disable(st->vddio_supply);
718 	if (ret)
719 		dev_err(dev, "failed to disable vddio error %d\n", ret);
720 }
721 
inv_icm42600_disable_pm(void * _data)722 static void inv_icm42600_disable_pm(void *_data)
723 {
724 	struct device *dev = _data;
725 
726 	pm_runtime_put_sync(dev);
727 	pm_runtime_disable(dev);
728 }
729 
inv_icm42600_core_probe(struct regmap * regmap,int chip,inv_icm42600_bus_setup bus_setup)730 int inv_icm42600_core_probe(struct regmap *regmap, int chip,
731 			    inv_icm42600_bus_setup bus_setup)
732 {
733 	struct device *dev = regmap_get_device(regmap);
734 	struct fwnode_handle *fwnode = dev_fwnode(dev);
735 	struct inv_icm42600_state *st;
736 	int irq, irq_type;
737 	bool open_drain;
738 	int ret;
739 
740 	if (chip <= INV_CHIP_INVALID || chip >= INV_CHIP_NB) {
741 		dev_err(dev, "invalid chip = %d\n", chip);
742 		return -ENODEV;
743 	}
744 
745 	/* get INT1 only supported interrupt or fallback to first interrupt */
746 	irq = fwnode_irq_get_byname(fwnode, "INT1");
747 	if (irq < 0 && irq != -EPROBE_DEFER) {
748 		dev_info(dev, "no INT1 interrupt defined, fallback to first interrupt\n");
749 		irq = fwnode_irq_get(fwnode, 0);
750 	}
751 	if (irq < 0)
752 		return dev_err_probe(dev, irq, "error missing INT1 interrupt\n");
753 
754 	irq_type = irq_get_trigger_type(irq);
755 	if (!irq_type)
756 		irq_type = IRQF_TRIGGER_FALLING;
757 
758 	open_drain = device_property_read_bool(dev, "drive-open-drain");
759 
760 	st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
761 	if (!st)
762 		return -ENOMEM;
763 
764 	dev_set_drvdata(dev, st);
765 	mutex_init(&st->lock);
766 	st->chip = chip;
767 	st->map = regmap;
768 	st->irq = irq;
769 
770 	ret = iio_read_mount_matrix(dev, &st->orientation);
771 	if (ret) {
772 		dev_err(dev, "failed to retrieve mounting matrix %d\n", ret);
773 		return ret;
774 	}
775 
776 	st->vdd_supply = devm_regulator_get(dev, "vdd");
777 	if (IS_ERR(st->vdd_supply))
778 		return PTR_ERR(st->vdd_supply);
779 
780 	st->vddio_supply = devm_regulator_get(dev, "vddio");
781 	if (IS_ERR(st->vddio_supply))
782 		return PTR_ERR(st->vddio_supply);
783 
784 	ret = regulator_enable(st->vdd_supply);
785 	if (ret)
786 		return ret;
787 	msleep(INV_ICM42600_POWER_UP_TIME_MS);
788 
789 	ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vdd_reg, st);
790 	if (ret)
791 		return ret;
792 
793 	ret = inv_icm42600_enable_regulator_vddio(st);
794 	if (ret)
795 		return ret;
796 
797 	ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vddio_reg, st);
798 	if (ret)
799 		return ret;
800 
801 	/* setup chip registers */
802 	ret = inv_icm42600_setup(st, bus_setup);
803 	if (ret)
804 		return ret;
805 
806 	ret = inv_icm42600_timestamp_setup(st);
807 	if (ret)
808 		return ret;
809 
810 	ret = inv_icm42600_buffer_init(st);
811 	if (ret)
812 		return ret;
813 
814 	st->indio_gyro = inv_icm42600_gyro_init(st);
815 	if (IS_ERR(st->indio_gyro))
816 		return PTR_ERR(st->indio_gyro);
817 
818 	st->indio_accel = inv_icm42600_accel_init(st);
819 	if (IS_ERR(st->indio_accel))
820 		return PTR_ERR(st->indio_accel);
821 
822 	ret = inv_icm42600_irq_init(st, irq, irq_type, open_drain);
823 	if (ret)
824 		return ret;
825 
826 	/* setup runtime power management */
827 	ret = pm_runtime_set_active(dev);
828 	if (ret)
829 		return ret;
830 	pm_runtime_get_noresume(dev);
831 	pm_runtime_enable(dev);
832 	pm_runtime_set_autosuspend_delay(dev, INV_ICM42600_SUSPEND_DELAY_MS);
833 	pm_runtime_use_autosuspend(dev);
834 	pm_runtime_put(dev);
835 
836 	return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev);
837 }
838 EXPORT_SYMBOL_NS_GPL(inv_icm42600_core_probe, "IIO_ICM42600");
839 
840 /*
841  * Suspend saves sensors state and turns everything off.
842  * Check first if runtime suspend has not already done the job.
843  */
inv_icm42600_suspend(struct device * dev)844 static int inv_icm42600_suspend(struct device *dev)
845 {
846 	struct inv_icm42600_state *st = dev_get_drvdata(dev);
847 	struct device *accel_dev;
848 	bool wakeup;
849 	int accel_conf;
850 	int ret;
851 
852 	mutex_lock(&st->lock);
853 
854 	st->suspended.gyro = st->conf.gyro.mode;
855 	st->suspended.accel = st->conf.accel.mode;
856 	st->suspended.temp = st->conf.temp_en;
857 	if (pm_runtime_suspended(dev)) {
858 		ret = 0;
859 		goto out_unlock;
860 	}
861 
862 	/* disable FIFO data streaming */
863 	if (st->fifo.on) {
864 		ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
865 				   INV_ICM42600_FIFO_CONFIG_BYPASS);
866 		if (ret)
867 			goto out_unlock;
868 	}
869 
870 	/* keep chip on and wake-up capable if APEX and wakeup on */
871 	accel_dev = &st->indio_accel->dev;
872 	wakeup = st->apex.on && device_may_wakeup(accel_dev);
873 	if (wakeup) {
874 		/* keep accel on and setup irq for wakeup */
875 		accel_conf = st->conf.accel.mode;
876 		enable_irq_wake(st->irq);
877 		disable_irq(st->irq);
878 	} else {
879 		/* disable APEX features and accel if wakeup disabled */
880 		if (st->apex.wom.enable) {
881 			ret = inv_icm42600_disable_wom(st);
882 			if (ret)
883 				goto out_unlock;
884 		}
885 		accel_conf = INV_ICM42600_SENSOR_MODE_OFF;
886 	}
887 
888 	ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
889 					 accel_conf, false, NULL);
890 	if (ret)
891 		goto out_unlock;
892 
893 	/* disable vddio regulator if chip is sleeping */
894 	if (!wakeup)
895 		regulator_disable(st->vddio_supply);
896 
897 out_unlock:
898 	mutex_unlock(&st->lock);
899 	return ret;
900 }
901 
902 /*
903  * System resume gets the system back on and restores the sensors state.
904  * Manually put runtime power management in system active state.
905  */
inv_icm42600_resume(struct device * dev)906 static int inv_icm42600_resume(struct device *dev)
907 {
908 	struct inv_icm42600_state *st = dev_get_drvdata(dev);
909 	struct inv_icm42600_sensor_state *gyro_st = iio_priv(st->indio_gyro);
910 	struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel);
911 	struct device *accel_dev;
912 	bool wakeup;
913 	int ret;
914 
915 	mutex_lock(&st->lock);
916 
917 	/* check wakeup capability */
918 	accel_dev = &st->indio_accel->dev;
919 	wakeup = st->apex.on && device_may_wakeup(accel_dev);
920 	/* restore irq state or vddio if cut off */
921 	if (wakeup) {
922 		enable_irq(st->irq);
923 		disable_irq_wake(st->irq);
924 	} else {
925 		ret = inv_icm42600_enable_regulator_vddio(st);
926 		if (ret)
927 			goto out_unlock;
928 	}
929 
930 	pm_runtime_disable(dev);
931 	pm_runtime_set_active(dev);
932 	pm_runtime_enable(dev);
933 
934 	/* restore sensors state */
935 	ret = inv_icm42600_set_pwr_mgmt0(st, st->suspended.gyro,
936 					 st->suspended.accel,
937 					 st->suspended.temp, NULL);
938 	if (ret)
939 		goto out_unlock;
940 
941 	/* restore APEX features if disabled */
942 	if (!wakeup && st->apex.wom.enable) {
943 		ret = inv_icm42600_enable_wom(st);
944 		if (ret)
945 			goto out_unlock;
946 	}
947 
948 	/* restore FIFO data streaming */
949 	if (st->fifo.on) {
950 		inv_sensors_timestamp_reset(&gyro_st->ts);
951 		inv_sensors_timestamp_reset(&accel_st->ts);
952 		ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
953 				   INV_ICM42600_FIFO_CONFIG_STREAM);
954 	}
955 
956 out_unlock:
957 	mutex_unlock(&st->lock);
958 	return ret;
959 }
960 
961 /* Runtime suspend will turn off sensors that are enabled by iio devices. */
inv_icm42600_runtime_suspend(struct device * dev)962 static int inv_icm42600_runtime_suspend(struct device *dev)
963 {
964 	struct inv_icm42600_state *st = dev_get_drvdata(dev);
965 	int ret;
966 
967 	mutex_lock(&st->lock);
968 
969 	/* disable all sensors */
970 	ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
971 					 INV_ICM42600_SENSOR_MODE_OFF, false,
972 					 NULL);
973 	if (ret)
974 		goto error_unlock;
975 
976 	regulator_disable(st->vddio_supply);
977 
978 error_unlock:
979 	mutex_unlock(&st->lock);
980 	return ret;
981 }
982 
983 /* Sensors are enabled by iio devices, no need to turn them back on here. */
inv_icm42600_runtime_resume(struct device * dev)984 static int inv_icm42600_runtime_resume(struct device *dev)
985 {
986 	struct inv_icm42600_state *st = dev_get_drvdata(dev);
987 	int ret;
988 
989 	mutex_lock(&st->lock);
990 
991 	ret = inv_icm42600_enable_regulator_vddio(st);
992 
993 	mutex_unlock(&st->lock);
994 	return ret;
995 }
996 
997 EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42600_pm_ops, IIO_ICM42600) = {
998 	SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume)
999 	RUNTIME_PM_OPS(inv_icm42600_runtime_suspend,
1000 		       inv_icm42600_runtime_resume, NULL)
1001 };
1002 
1003 MODULE_AUTHOR("InvenSense, Inc.");
1004 MODULE_DESCRIPTION("InvenSense ICM-426xx device driver");
1005 MODULE_LICENSE("GPL");
1006 MODULE_IMPORT_NS("IIO_INV_SENSORS_TIMESTAMP");
1007