xref: /linux/drivers/iio/gyro/st_gyro_core.c (revision 0ad53fe3ae82443c74ff8cfd7bd13377cc1134a3)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * STMicroelectronics gyroscopes driver
4  *
5  * Copyright 2012-2013 STMicroelectronics Inc.
6  *
7  * Denis Ciocca <denis.ciocca@st.com>
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/mutex.h>
13 #include <linux/interrupt.h>
14 #include <linux/sysfs.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17 #include <linux/iio/trigger.h>
18 
19 #include <linux/iio/common/st_sensors.h>
20 #include "st_gyro.h"
21 
22 #define ST_GYRO_NUMBER_DATA_CHANNELS		3
23 
24 /* DEFAULT VALUE FOR SENSORS */
25 #define ST_GYRO_DEFAULT_OUT_X_L_ADDR		0x28
26 #define ST_GYRO_DEFAULT_OUT_Y_L_ADDR		0x2a
27 #define ST_GYRO_DEFAULT_OUT_Z_L_ADDR		0x2c
28 
29 /* FULLSCALE */
30 #define ST_GYRO_FS_AVL_245DPS			245
31 #define ST_GYRO_FS_AVL_250DPS			250
32 #define ST_GYRO_FS_AVL_500DPS			500
33 #define ST_GYRO_FS_AVL_2000DPS			2000
34 
35 static const struct iio_mount_matrix *
36 st_gyro_get_mount_matrix(const struct iio_dev *indio_dev,
37 			 const struct iio_chan_spec *chan)
38 {
39 	struct st_sensor_data *gdata = iio_priv(indio_dev);
40 
41 	return &gdata->mount_matrix;
42 }
43 
44 static const struct iio_chan_spec_ext_info st_gyro_mount_matrix_ext_info[] = {
45 	IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_gyro_get_mount_matrix),
46 	{ }
47 };
48 
49 static const struct iio_chan_spec st_gyro_16bit_channels[] = {
50 	ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
51 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
52 			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
53 			ST_GYRO_DEFAULT_OUT_X_L_ADDR,
54 			st_gyro_mount_matrix_ext_info),
55 	ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
56 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
57 			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
58 			ST_GYRO_DEFAULT_OUT_Y_L_ADDR,
59 			st_gyro_mount_matrix_ext_info),
60 	ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
61 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
62 			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
63 			ST_GYRO_DEFAULT_OUT_Z_L_ADDR,
64 			st_gyro_mount_matrix_ext_info),
65 	IIO_CHAN_SOFT_TIMESTAMP(3)
66 };
67 
68 static const struct st_sensor_settings st_gyro_sensors_settings[] = {
69 	{
70 		.wai = 0xd3,
71 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
72 		.sensors_supported = {
73 			[0] = L3G4200D_GYRO_DEV_NAME,
74 			[1] = LSM330DL_GYRO_DEV_NAME,
75 		},
76 		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
77 		.odr = {
78 			.addr = 0x20,
79 			.mask = 0xc0,
80 			.odr_avl = {
81 				{ .hz = 100, .value = 0x00, },
82 				{ .hz = 200, .value = 0x01, },
83 				{ .hz = 400, .value = 0x02, },
84 				{ .hz = 800, .value = 0x03, },
85 			},
86 		},
87 		.pw = {
88 			.addr = 0x20,
89 			.mask = 0x08,
90 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
91 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
92 		},
93 		.enable_axis = {
94 			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
95 			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
96 		},
97 		.fs = {
98 			.addr = 0x23,
99 			.mask = 0x30,
100 			.fs_avl = {
101 				[0] = {
102 					.num = ST_GYRO_FS_AVL_250DPS,
103 					.value = 0x00,
104 					.gain = IIO_DEGREE_TO_RAD(8750),
105 				},
106 				[1] = {
107 					.num = ST_GYRO_FS_AVL_500DPS,
108 					.value = 0x01,
109 					.gain = IIO_DEGREE_TO_RAD(17500),
110 				},
111 				[2] = {
112 					.num = ST_GYRO_FS_AVL_2000DPS,
113 					.value = 0x02,
114 					.gain = IIO_DEGREE_TO_RAD(70000),
115 				},
116 			},
117 		},
118 		.bdu = {
119 			.addr = 0x23,
120 			.mask = 0x80,
121 		},
122 		.drdy_irq = {
123 			.int2 = {
124 				.addr = 0x22,
125 				.mask = 0x08,
126 			},
127 			/*
128 			 * The sensor has IHL (active low) and open
129 			 * drain settings, but only for INT1 and not
130 			 * for the DRDY line on INT2.
131 			 */
132 			.stat_drdy = {
133 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
134 				.mask = 0x07,
135 			},
136 		},
137 		.sim = {
138 			.addr = 0x23,
139 			.value = BIT(0),
140 		},
141 		.multi_read_bit = true,
142 		.bootime = 2,
143 	},
144 	{
145 		.wai = 0xd4,
146 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
147 		.sensors_supported = {
148 			[0] = L3GD20_GYRO_DEV_NAME,
149 			[1] = LSM330D_GYRO_DEV_NAME,
150 			[2] = LSM330DLC_GYRO_DEV_NAME,
151 			[3] = L3G4IS_GYRO_DEV_NAME,
152 			[4] = LSM330_GYRO_DEV_NAME,
153 		},
154 		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
155 		.odr = {
156 			.addr = 0x20,
157 			.mask = 0xc0,
158 			.odr_avl = {
159 				{ .hz = 95, .value = 0x00, },
160 				{ .hz = 190, .value = 0x01, },
161 				{ .hz = 380, .value = 0x02, },
162 				{ .hz = 760, .value = 0x03, },
163 			},
164 		},
165 		.pw = {
166 			.addr = 0x20,
167 			.mask = 0x08,
168 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
169 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
170 		},
171 		.enable_axis = {
172 			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
173 			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
174 		},
175 		.fs = {
176 			.addr = 0x23,
177 			.mask = 0x30,
178 			.fs_avl = {
179 				[0] = {
180 					.num = ST_GYRO_FS_AVL_250DPS,
181 					.value = 0x00,
182 					.gain = IIO_DEGREE_TO_RAD(8750),
183 				},
184 				[1] = {
185 					.num = ST_GYRO_FS_AVL_500DPS,
186 					.value = 0x01,
187 					.gain = IIO_DEGREE_TO_RAD(17500),
188 				},
189 				[2] = {
190 					.num = ST_GYRO_FS_AVL_2000DPS,
191 					.value = 0x02,
192 					.gain = IIO_DEGREE_TO_RAD(70000),
193 				},
194 			},
195 		},
196 		.bdu = {
197 			.addr = 0x23,
198 			.mask = 0x80,
199 		},
200 		.drdy_irq = {
201 			.int2 = {
202 				.addr = 0x22,
203 				.mask = 0x08,
204 			},
205 			/*
206 			 * The sensor has IHL (active low) and open
207 			 * drain settings, but only for INT1 and not
208 			 * for the DRDY line on INT2.
209 			 */
210 			.stat_drdy = {
211 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
212 				.mask = 0x07,
213 			},
214 		},
215 		.sim = {
216 			.addr = 0x23,
217 			.value = BIT(0),
218 		},
219 		.multi_read_bit = true,
220 		.bootime = 2,
221 	},
222 	{
223 		.wai = 0xd4,
224 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
225 		.sensors_supported = {
226 			[0] = LSM9DS0_GYRO_DEV_NAME,
227 		},
228 		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
229 		.odr = {
230 			.addr = 0x20,
231 			.mask = GENMASK(7, 6),
232 			.odr_avl = {
233 				{ .hz = 95, .value = 0x00, },
234 				{ .hz = 190, .value = 0x01, },
235 				{ .hz = 380, .value = 0x02, },
236 				{ .hz = 760, .value = 0x03, },
237 			},
238 		},
239 		.pw = {
240 			.addr = 0x20,
241 			.mask = BIT(3),
242 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
243 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
244 		},
245 		.enable_axis = {
246 			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
247 			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
248 		},
249 		.fs = {
250 			.addr = 0x23,
251 			.mask = GENMASK(5, 4),
252 			.fs_avl = {
253 				[0] = {
254 					.num = ST_GYRO_FS_AVL_245DPS,
255 					.value = 0x00,
256 					.gain = IIO_DEGREE_TO_RAD(8750),
257 				},
258 				[1] = {
259 					.num = ST_GYRO_FS_AVL_500DPS,
260 					.value = 0x01,
261 					.gain = IIO_DEGREE_TO_RAD(17500),
262 				},
263 				[2] = {
264 					.num = ST_GYRO_FS_AVL_2000DPS,
265 					.value = 0x02,
266 					.gain = IIO_DEGREE_TO_RAD(70000),
267 				},
268 			},
269 		},
270 		.bdu = {
271 			.addr = 0x23,
272 			.mask = BIT(7),
273 		},
274 		.drdy_irq = {
275 			.int2 = {
276 				.addr = 0x22,
277 				.mask = BIT(3),
278 			},
279 			/*
280 			 * The sensor has IHL (active low) and open
281 			 * drain settings, but only for INT1 and not
282 			 * for the DRDY line on INT2.
283 			 */
284 			.stat_drdy = {
285 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
286 				.mask = GENMASK(2, 0),
287 			},
288 		},
289 		.sim = {
290 			.addr = 0x23,
291 			.value = BIT(0),
292 		},
293 		.multi_read_bit = true,
294 		.bootime = 2,
295 	},
296 	{
297 		.wai = 0xd7,
298 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
299 		.sensors_supported = {
300 			[0] = L3GD20H_GYRO_DEV_NAME,
301 		},
302 		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
303 		.odr = {
304 			.addr = 0x20,
305 			.mask = 0xc0,
306 			.odr_avl = {
307 				{ .hz = 100, .value = 0x00, },
308 				{ .hz = 200, .value = 0x01, },
309 				{ .hz = 400, .value = 0x02, },
310 				{ .hz = 800, .value = 0x03, },
311 			},
312 		},
313 		.pw = {
314 			.addr = 0x20,
315 			.mask = 0x08,
316 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
317 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
318 		},
319 		.enable_axis = {
320 			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
321 			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
322 		},
323 		.fs = {
324 			.addr = 0x23,
325 			.mask = 0x30,
326 			.fs_avl = {
327 				[0] = {
328 					.num = ST_GYRO_FS_AVL_245DPS,
329 					.value = 0x00,
330 					.gain = IIO_DEGREE_TO_RAD(8750),
331 				},
332 				[1] = {
333 					.num = ST_GYRO_FS_AVL_500DPS,
334 					.value = 0x01,
335 					.gain = IIO_DEGREE_TO_RAD(17500),
336 				},
337 				[2] = {
338 					.num = ST_GYRO_FS_AVL_2000DPS,
339 					.value = 0x02,
340 					.gain = IIO_DEGREE_TO_RAD(70000),
341 				},
342 			},
343 		},
344 		.bdu = {
345 			.addr = 0x23,
346 			.mask = 0x80,
347 		},
348 		.drdy_irq = {
349 			.int2 = {
350 				.addr = 0x22,
351 				.mask = 0x08,
352 			},
353 			/*
354 			 * The sensor has IHL (active low) and open
355 			 * drain settings, but only for INT1 and not
356 			 * for the DRDY line on INT2.
357 			 */
358 			.stat_drdy = {
359 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
360 				.mask = 0x07,
361 			},
362 		},
363 		.sim = {
364 			.addr = 0x23,
365 			.value = BIT(0),
366 		},
367 		.multi_read_bit = true,
368 		.bootime = 2,
369 	},
370 };
371 
372 /* DRDY on gyros is available only on INT2 pin */
373 static const struct st_sensors_platform_data gyro_pdata = {
374 	.drdy_int_pin = 2,
375 };
376 
377 static int st_gyro_read_raw(struct iio_dev *indio_dev,
378 			struct iio_chan_spec const *ch, int *val,
379 							int *val2, long mask)
380 {
381 	int err;
382 	struct st_sensor_data *gdata = iio_priv(indio_dev);
383 
384 	switch (mask) {
385 	case IIO_CHAN_INFO_RAW:
386 		err = st_sensors_read_info_raw(indio_dev, ch, val);
387 		if (err < 0)
388 			goto read_error;
389 
390 		return IIO_VAL_INT;
391 	case IIO_CHAN_INFO_SCALE:
392 		*val = 0;
393 		*val2 = gdata->current_fullscale->gain;
394 		return IIO_VAL_INT_PLUS_MICRO;
395 	case IIO_CHAN_INFO_SAMP_FREQ:
396 		*val = gdata->odr;
397 		return IIO_VAL_INT;
398 	default:
399 		return -EINVAL;
400 	}
401 
402 read_error:
403 	return err;
404 }
405 
406 static int st_gyro_write_raw(struct iio_dev *indio_dev,
407 		struct iio_chan_spec const *chan, int val, int val2, long mask)
408 {
409 	int err;
410 
411 	switch (mask) {
412 	case IIO_CHAN_INFO_SCALE:
413 		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
414 		break;
415 	case IIO_CHAN_INFO_SAMP_FREQ:
416 		if (val2)
417 			return -EINVAL;
418 		mutex_lock(&indio_dev->mlock);
419 		err = st_sensors_set_odr(indio_dev, val);
420 		mutex_unlock(&indio_dev->mlock);
421 		return err;
422 	default:
423 		err = -EINVAL;
424 	}
425 
426 	return err;
427 }
428 
429 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
430 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
431 
432 static struct attribute *st_gyro_attributes[] = {
433 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
434 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
435 	NULL,
436 };
437 
438 static const struct attribute_group st_gyro_attribute_group = {
439 	.attrs = st_gyro_attributes,
440 };
441 
442 static const struct iio_info gyro_info = {
443 	.attrs = &st_gyro_attribute_group,
444 	.read_raw = &st_gyro_read_raw,
445 	.write_raw = &st_gyro_write_raw,
446 	.debugfs_reg_access = &st_sensors_debugfs_reg_access,
447 };
448 
449 #ifdef CONFIG_IIO_TRIGGER
450 static const struct iio_trigger_ops st_gyro_trigger_ops = {
451 	.set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
452 	.validate_device = st_sensors_validate_device,
453 };
454 #define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
455 #else
456 #define ST_GYRO_TRIGGER_OPS NULL
457 #endif
458 
459 /*
460  * st_gyro_get_settings() - get sensor settings from device name
461  * @name: device name buffer reference.
462  *
463  * Return: valid reference on success, NULL otherwise.
464  */
465 const struct st_sensor_settings *st_gyro_get_settings(const char *name)
466 {
467 	int index = st_sensors_get_settings_index(name,
468 					st_gyro_sensors_settings,
469 					ARRAY_SIZE(st_gyro_sensors_settings));
470 	if (index < 0)
471 		return NULL;
472 
473 	return &st_gyro_sensors_settings[index];
474 }
475 EXPORT_SYMBOL(st_gyro_get_settings);
476 
477 int st_gyro_common_probe(struct iio_dev *indio_dev)
478 {
479 	struct st_sensor_data *gdata = iio_priv(indio_dev);
480 	struct st_sensors_platform_data *pdata;
481 	int err;
482 
483 	indio_dev->modes = INDIO_DIRECT_MODE;
484 	indio_dev->info = &gyro_info;
485 
486 	err = st_sensors_verify_id(indio_dev);
487 	if (err < 0)
488 		return err;
489 
490 	gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
491 	indio_dev->channels = gdata->sensor_settings->ch;
492 	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
493 
494 	err = iio_read_mount_matrix(gdata->dev, &gdata->mount_matrix);
495 	if (err)
496 		return err;
497 
498 	gdata->current_fullscale = &gdata->sensor_settings->fs.fs_avl[0];
499 	gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
500 
501 	pdata = (struct st_sensors_platform_data *)&gyro_pdata;
502 
503 	err = st_sensors_init_sensor(indio_dev, pdata);
504 	if (err < 0)
505 		return err;
506 
507 	err = st_gyro_allocate_ring(indio_dev);
508 	if (err < 0)
509 		return err;
510 
511 	if (gdata->irq > 0) {
512 		err = st_sensors_allocate_trigger(indio_dev,
513 						  ST_GYRO_TRIGGER_OPS);
514 		if (err < 0)
515 			return err;
516 	}
517 
518 	err = iio_device_register(indio_dev);
519 	if (err)
520 		goto st_gyro_device_register_error;
521 
522 	dev_info(&indio_dev->dev, "registered gyroscope %s\n",
523 		 indio_dev->name);
524 
525 	return 0;
526 
527 st_gyro_device_register_error:
528 	if (gdata->irq > 0)
529 		st_sensors_deallocate_trigger(indio_dev);
530 	return err;
531 }
532 EXPORT_SYMBOL(st_gyro_common_probe);
533 
534 void st_gyro_common_remove(struct iio_dev *indio_dev)
535 {
536 	struct st_sensor_data *gdata = iio_priv(indio_dev);
537 
538 	iio_device_unregister(indio_dev);
539 	if (gdata->irq > 0)
540 		st_sensors_deallocate_trigger(indio_dev);
541 }
542 EXPORT_SYMBOL(st_gyro_common_remove);
543 
544 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
545 MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
546 MODULE_LICENSE("GPL v2");
547