Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / iio / gyro / st_gyro_core.c
blob7fd82cd707c7658cefd616778f6e4374155d34c3
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * STMicroelectronics gyroscopes driver
5 * Copyright 2012-2013 STMicroelectronics Inc.
7 * Denis Ciocca <denis.ciocca@st.com>
8 */
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>
19 #include <linux/iio/common/st_sensors.h>
20 #include "st_gyro.h"
22 #define ST_GYRO_NUMBER_DATA_CHANNELS 3
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
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
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)
39 struct st_sensor_data *gdata = iio_priv(indio_dev);
41 return &gdata->mount_matrix;
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 { }
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)
68 static const struct st_sensor_settings st_gyro_sensors_settings[] = {
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,
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, },
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,
93 .enable_axis = {
94 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
95 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
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),
106 [1] = {
107 .num = ST_GYRO_FS_AVL_500DPS,
108 .value = 0x01,
109 .gain = IIO_DEGREE_TO_RAD(17500),
111 [2] = {
112 .num = ST_GYRO_FS_AVL_2000DPS,
113 .value = 0x02,
114 .gain = IIO_DEGREE_TO_RAD(70000),
118 .bdu = {
119 .addr = 0x23,
120 .mask = 0x80,
122 .drdy_irq = {
123 .int2 = {
124 .addr = 0x22,
125 .mask = 0x08,
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.
132 .stat_drdy = {
133 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
134 .mask = 0x07,
137 .sim = {
138 .addr = 0x23,
139 .value = BIT(0),
141 .multi_read_bit = true,
142 .bootime = 2,
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,
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, },
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,
171 .enable_axis = {
172 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
173 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
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),
184 [1] = {
185 .num = ST_GYRO_FS_AVL_500DPS,
186 .value = 0x01,
187 .gain = IIO_DEGREE_TO_RAD(17500),
189 [2] = {
190 .num = ST_GYRO_FS_AVL_2000DPS,
191 .value = 0x02,
192 .gain = IIO_DEGREE_TO_RAD(70000),
196 .bdu = {
197 .addr = 0x23,
198 .mask = 0x80,
200 .drdy_irq = {
201 .int2 = {
202 .addr = 0x22,
203 .mask = 0x08,
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.
210 .stat_drdy = {
211 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
212 .mask = 0x07,
215 .sim = {
216 .addr = 0x23,
217 .value = BIT(0),
219 .multi_read_bit = true,
220 .bootime = 2,
223 .wai = 0xd4,
224 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
225 .sensors_supported = {
226 [0] = LSM9DS0_GYRO_DEV_NAME,
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, },
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,
245 .enable_axis = {
246 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
247 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
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),
258 [1] = {
259 .num = ST_GYRO_FS_AVL_500DPS,
260 .value = 0x01,
261 .gain = IIO_DEGREE_TO_RAD(17500),
263 [2] = {
264 .num = ST_GYRO_FS_AVL_2000DPS,
265 .value = 0x02,
266 .gain = IIO_DEGREE_TO_RAD(70000),
270 .bdu = {
271 .addr = 0x23,
272 .mask = BIT(7),
274 .drdy_irq = {
275 .int2 = {
276 .addr = 0x22,
277 .mask = BIT(3),
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.
284 .stat_drdy = {
285 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
286 .mask = GENMASK(2, 0),
289 .sim = {
290 .addr = 0x23,
291 .value = BIT(0),
293 .multi_read_bit = true,
294 .bootime = 2,
297 .wai = 0xd7,
298 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
299 .sensors_supported = {
300 [0] = L3GD20H_GYRO_DEV_NAME,
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, },
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,
319 .enable_axis = {
320 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
321 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
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),
332 [1] = {
333 .num = ST_GYRO_FS_AVL_500DPS,
334 .value = 0x01,
335 .gain = IIO_DEGREE_TO_RAD(17500),
337 [2] = {
338 .num = ST_GYRO_FS_AVL_2000DPS,
339 .value = 0x02,
340 .gain = IIO_DEGREE_TO_RAD(70000),
344 .bdu = {
345 .addr = 0x23,
346 .mask = 0x80,
348 .drdy_irq = {
349 .int2 = {
350 .addr = 0x22,
351 .mask = 0x08,
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.
358 .stat_drdy = {
359 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
360 .mask = 0x07,
363 .sim = {
364 .addr = 0x23,
365 .value = BIT(0),
367 .multi_read_bit = true,
368 .bootime = 2,
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,
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)
381 int err;
382 struct st_sensor_data *gdata = iio_priv(indio_dev);
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;
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;
402 read_error:
403 return err;
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)
409 switch (mask) {
410 case IIO_CHAN_INFO_SCALE:
411 return st_sensors_set_fullscale_by_gain(indio_dev, val2);
412 case IIO_CHAN_INFO_SAMP_FREQ:
413 if (val2)
414 return -EINVAL;
416 return st_sensors_set_odr(indio_dev, val);
417 default:
418 return -EINVAL;
422 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
423 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
425 static struct attribute *st_gyro_attributes[] = {
426 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
427 &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
428 NULL,
431 static const struct attribute_group st_gyro_attribute_group = {
432 .attrs = st_gyro_attributes,
435 static const struct iio_info gyro_info = {
436 .attrs = &st_gyro_attribute_group,
437 .read_raw = &st_gyro_read_raw,
438 .write_raw = &st_gyro_write_raw,
439 .debugfs_reg_access = &st_sensors_debugfs_reg_access,
442 #ifdef CONFIG_IIO_TRIGGER
443 static const struct iio_trigger_ops st_gyro_trigger_ops = {
444 .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
445 .validate_device = st_sensors_validate_device,
447 #define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
448 #else
449 #define ST_GYRO_TRIGGER_OPS NULL
450 #endif
453 * st_gyro_get_settings() - get sensor settings from device name
454 * @name: device name buffer reference.
456 * Return: valid reference on success, NULL otherwise.
458 const struct st_sensor_settings *st_gyro_get_settings(const char *name)
460 int index = st_sensors_get_settings_index(name,
461 st_gyro_sensors_settings,
462 ARRAY_SIZE(st_gyro_sensors_settings));
463 if (index < 0)
464 return NULL;
466 return &st_gyro_sensors_settings[index];
468 EXPORT_SYMBOL_NS(st_gyro_get_settings, "IIO_ST_SENSORS");
470 int st_gyro_common_probe(struct iio_dev *indio_dev)
472 struct st_sensor_data *gdata = iio_priv(indio_dev);
473 struct st_sensors_platform_data *pdata;
474 struct device *parent = indio_dev->dev.parent;
475 int err;
477 indio_dev->modes = INDIO_DIRECT_MODE;
478 indio_dev->info = &gyro_info;
480 err = st_sensors_verify_id(indio_dev);
481 if (err < 0)
482 return err;
484 gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
485 indio_dev->channels = gdata->sensor_settings->ch;
486 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
488 err = iio_read_mount_matrix(parent, &gdata->mount_matrix);
489 if (err)
490 return err;
492 gdata->current_fullscale = &gdata->sensor_settings->fs.fs_avl[0];
493 gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
495 pdata = (struct st_sensors_platform_data *)&gyro_pdata;
497 err = st_sensors_init_sensor(indio_dev, pdata);
498 if (err < 0)
499 return err;
501 err = st_gyro_allocate_ring(indio_dev);
502 if (err < 0)
503 return err;
505 if (gdata->irq > 0) {
506 err = st_sensors_allocate_trigger(indio_dev,
507 ST_GYRO_TRIGGER_OPS);
508 if (err < 0)
509 return err;
512 return devm_iio_device_register(parent, indio_dev);
514 EXPORT_SYMBOL_NS(st_gyro_common_probe, "IIO_ST_SENSORS");
516 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
517 MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
518 MODULE_LICENSE("GPL v2");
519 MODULE_IMPORT_NS("IIO_ST_SENSORS");