pds_core: devlink params for enabling VIF support
[linux-block.git] / drivers / iio / gyro / st_gyro_core.c
CommitLineData
fda8d26e 1// SPDX-License-Identifier: GPL-2.0-only
7be56a8f
DC
2/*
3 * STMicroelectronics gyroscopes driver
4 *
5 * Copyright 2012-2013 STMicroelectronics Inc.
6 *
7 * Denis Ciocca <denis.ciocca@st.com>
7be56a8f
DC
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
9c6cd755 12#include <linux/mutex.h>
7be56a8f 13#include <linux/interrupt.h>
9c6cd755 14#include <linux/sysfs.h>
7be56a8f
DC
15#include <linux/iio/iio.h>
16#include <linux/iio/sysfs.h>
8ce4a56a 17#include <linux/iio/trigger.h>
7be56a8f
DC
18
19#include <linux/iio/common/st_sensors.h>
20#include "st_gyro.h"
21
607a568a
DC
22#define ST_GYRO_NUMBER_DATA_CHANNELS 3
23
7be56a8f
DC
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 */
45a4e422 30#define ST_GYRO_FS_AVL_245DPS 245
7be56a8f
DC
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
e1c5d708
LW
35static const struct iio_mount_matrix *
36st_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
44static 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
7be56a8f 49static const struct iio_chan_spec st_gyro_16bit_channels[] = {
e1c5d708 50 ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
762011d6
DC
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,
e1c5d708
LW
53 ST_GYRO_DEFAULT_OUT_X_L_ADDR,
54 st_gyro_mount_matrix_ext_info),
55 ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
762011d6
DC
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,
e1c5d708
LW
58 ST_GYRO_DEFAULT_OUT_Y_L_ADDR,
59 st_gyro_mount_matrix_ext_info),
60 ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
762011d6
DC
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,
e1c5d708
LW
63 ST_GYRO_DEFAULT_OUT_Z_L_ADDR,
64 st_gyro_mount_matrix_ext_info),
7be56a8f
DC
65 IIO_CHAN_SOFT_TIMESTAMP(3)
66};
67
a7ee8839 68static const struct st_sensor_settings st_gyro_sensors_settings[] = {
7be56a8f 69 {
d8594fa2 70 .wai = 0xd3,
bc27381e 71 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
7be56a8f
DC
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 = {
d8594fa2
LW
78 .addr = 0x20,
79 .mask = 0xc0,
7be56a8f 80 .odr_avl = {
d8594fa2
LW
81 { .hz = 100, .value = 0x00, },
82 { .hz = 200, .value = 0x01, },
83 { .hz = 400, .value = 0x02, },
84 { .hz = 800, .value = 0x03, },
7be56a8f
DC
85 },
86 },
87 .pw = {
d8594fa2
LW
88 .addr = 0x20,
89 .mask = 0x08,
7be56a8f
DC
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 = {
d8594fa2
LW
98 .addr = 0x23,
99 .mask = 0x30,
7be56a8f
DC
100 .fs_avl = {
101 [0] = {
102 .num = ST_GYRO_FS_AVL_250DPS,
d8594fa2
LW
103 .value = 0x00,
104 .gain = IIO_DEGREE_TO_RAD(8750),
7be56a8f
DC
105 },
106 [1] = {
107 .num = ST_GYRO_FS_AVL_500DPS,
d8594fa2
LW
108 .value = 0x01,
109 .gain = IIO_DEGREE_TO_RAD(17500),
7be56a8f
DC
110 },
111 [2] = {
112 .num = ST_GYRO_FS_AVL_2000DPS,
d8594fa2
LW
113 .value = 0x02,
114 .gain = IIO_DEGREE_TO_RAD(70000),
7be56a8f
DC
115 },
116 },
117 },
118 .bdu = {
d8594fa2
LW
119 .addr = 0x23,
120 .mask = 0x80,
7be56a8f
DC
121 },
122 .drdy_irq = {
75d4c6d2
LB
123 .int2 = {
124 .addr = 0x22,
125 .mask = 0x08,
126 },
a9fd053b
LW
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 */
e72a0601
LB
132 .stat_drdy = {
133 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
134 .mask = 0x07,
135 },
7be56a8f 136 },
281dbadb
LB
137 .sim = {
138 .addr = 0x23,
139 .value = BIT(0),
140 },
d8594fa2 141 .multi_read_bit = true,
7be56a8f
DC
142 .bootime = 2,
143 },
144 {
d8594fa2 145 .wai = 0xd4,
bc27381e 146 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
7be56a8f
DC
147 .sensors_supported = {
148 [0] = L3GD20_GYRO_DEV_NAME,
a0657716
DC
149 [1] = LSM330D_GYRO_DEV_NAME,
150 [2] = LSM330DLC_GYRO_DEV_NAME,
151 [3] = L3G4IS_GYRO_DEV_NAME,
152 [4] = LSM330_GYRO_DEV_NAME,
7be56a8f
DC
153 },
154 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
155 .odr = {
d8594fa2
LW
156 .addr = 0x20,
157 .mask = 0xc0,
7be56a8f 158 .odr_avl = {
d8594fa2
LW
159 { .hz = 95, .value = 0x00, },
160 { .hz = 190, .value = 0x01, },
161 { .hz = 380, .value = 0x02, },
162 { .hz = 760, .value = 0x03, },
7be56a8f
DC
163 },
164 },
165 .pw = {
d8594fa2
LW
166 .addr = 0x20,
167 .mask = 0x08,
7be56a8f
DC
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 = {
d8594fa2
LW
176 .addr = 0x23,
177 .mask = 0x30,
7be56a8f
DC
178 .fs_avl = {
179 [0] = {
180 .num = ST_GYRO_FS_AVL_250DPS,
d8594fa2
LW
181 .value = 0x00,
182 .gain = IIO_DEGREE_TO_RAD(8750),
7be56a8f
DC
183 },
184 [1] = {
185 .num = ST_GYRO_FS_AVL_500DPS,
d8594fa2
LW
186 .value = 0x01,
187 .gain = IIO_DEGREE_TO_RAD(17500),
7be56a8f
DC
188 },
189 [2] = {
190 .num = ST_GYRO_FS_AVL_2000DPS,
d8594fa2
LW
191 .value = 0x02,
192 .gain = IIO_DEGREE_TO_RAD(70000),
7be56a8f
DC
193 },
194 },
195 },
196 .bdu = {
d8594fa2
LW
197 .addr = 0x23,
198 .mask = 0x80,
7be56a8f
DC
199 },
200 .drdy_irq = {
75d4c6d2
LB
201 .int2 = {
202 .addr = 0x22,
203 .mask = 0x08,
204 },
a9fd053b
LW
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 */
e72a0601
LB
210 .stat_drdy = {
211 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
212 .mask = 0x07,
213 },
7be56a8f 214 },
281dbadb
LB
215 .sim = {
216 .addr = 0x23,
217 .value = BIT(0),
218 },
d8594fa2 219 .multi_read_bit = true,
7be56a8f
DC
220 .bootime = 2,
221 },
e825070f
AS
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 },
9444a300 296 {
d8594fa2 297 .wai = 0xd7,
bc27381e 298 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
9444a300 299 .sensors_supported = {
45a4e422 300 [0] = L3GD20H_GYRO_DEV_NAME,
9444a300
RD
301 },
302 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
303 .odr = {
d8594fa2
LW
304 .addr = 0x20,
305 .mask = 0xc0,
9444a300 306 .odr_avl = {
45a4e422
LB
307 { .hz = 100, .value = 0x00, },
308 { .hz = 200, .value = 0x01, },
309 { .hz = 400, .value = 0x02, },
310 { .hz = 800, .value = 0x03, },
9444a300
RD
311 },
312 },
313 .pw = {
d8594fa2
LW
314 .addr = 0x20,
315 .mask = 0x08,
9444a300
RD
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 = {
d8594fa2
LW
324 .addr = 0x23,
325 .mask = 0x30,
9444a300
RD
326 .fs_avl = {
327 [0] = {
45a4e422 328 .num = ST_GYRO_FS_AVL_245DPS,
d8594fa2
LW
329 .value = 0x00,
330 .gain = IIO_DEGREE_TO_RAD(8750),
9444a300
RD
331 },
332 [1] = {
333 .num = ST_GYRO_FS_AVL_500DPS,
d8594fa2
LW
334 .value = 0x01,
335 .gain = IIO_DEGREE_TO_RAD(17500),
9444a300
RD
336 },
337 [2] = {
338 .num = ST_GYRO_FS_AVL_2000DPS,
d8594fa2
LW
339 .value = 0x02,
340 .gain = IIO_DEGREE_TO_RAD(70000),
9444a300
RD
341 },
342 },
343 },
344 .bdu = {
d8594fa2
LW
345 .addr = 0x23,
346 .mask = 0x80,
9444a300
RD
347 },
348 .drdy_irq = {
75d4c6d2
LB
349 .int2 = {
350 .addr = 0x22,
351 .mask = 0x08,
352 },
a9fd053b
LW
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 */
e72a0601
LB
358 .stat_drdy = {
359 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
360 .mask = 0x07,
361 },
9444a300 362 },
281dbadb
LB
363 .sim = {
364 .addr = 0x23,
365 .value = BIT(0),
366 },
d8594fa2 367 .multi_read_bit = true,
9444a300
RD
368 .bootime = 2,
369 },
7be56a8f
DC
370};
371
dffdd756
AS
372/* DRDY on gyros is available only on INT2 pin */
373static const struct st_sensors_platform_data gyro_pdata = {
374 .drdy_int_pin = 2,
375};
376
7be56a8f
DC
377static 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;
2d239c9e
JC
395 case IIO_CHAN_INFO_SAMP_FREQ:
396 *val = gdata->odr;
397 return IIO_VAL_INT;
7be56a8f
DC
398 default:
399 return -EINVAL;
400 }
401
402read_error:
403 return err;
404}
405
406static int st_gyro_write_raw(struct iio_dev *indio_dev,
407 struct iio_chan_spec const *chan, int val, int val2, long mask)
408{
7be56a8f
DC
409 switch (mask) {
410 case IIO_CHAN_INFO_SCALE:
69c98879 411 return st_sensors_set_fullscale_by_gain(indio_dev, val2);
2d239c9e
JC
412 case IIO_CHAN_INFO_SAMP_FREQ:
413 if (val2)
414 return -EINVAL;
12345968
MR
415
416 return st_sensors_set_odr(indio_dev, val);
7be56a8f 417 default:
69c98879 418 return -EINVAL;
7be56a8f 419 }
7be56a8f
DC
420}
421
7be56a8f
DC
422static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
423static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
424
425static 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,
7be56a8f
DC
428 NULL,
429};
430
431static const struct attribute_group st_gyro_attribute_group = {
432 .attrs = st_gyro_attributes,
433};
434
435static const struct iio_info gyro_info = {
7be56a8f
DC
436 .attrs = &st_gyro_attribute_group,
437 .read_raw = &st_gyro_read_raw,
438 .write_raw = &st_gyro_write_raw,
a0175b9c 439 .debugfs_reg_access = &st_sensors_debugfs_reg_access,
7be56a8f
DC
440};
441
8ce4a56a 442#ifdef CONFIG_IIO_TRIGGER
7be56a8f 443static const struct iio_trigger_ops st_gyro_trigger_ops = {
7be56a8f 444 .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
65925b65 445 .validate_device = st_sensors_validate_device,
7be56a8f 446};
8ce4a56a
JC
447#define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
448#else
449#define ST_GYRO_TRIGGER_OPS NULL
450#endif
7be56a8f 451
2acca26b
DC
452/*
453 * st_gyro_get_settings() - get sensor settings from device name
454 * @name: device name buffer reference.
455 *
456 * Return: valid reference on success, NULL otherwise.
457 */
458const struct st_sensor_settings *st_gyro_get_settings(const char *name)
459{
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;
465
466 return &st_gyro_sensors_settings[index];
467}
0805b512 468EXPORT_SYMBOL_NS(st_gyro_get_settings, IIO_ST_SENSORS);
2acca26b 469
ef67b341 470int st_gyro_common_probe(struct iio_dev *indio_dev)
7be56a8f 471{
7be56a8f 472 struct st_sensor_data *gdata = iio_priv(indio_dev);
1f38527d 473 struct st_sensors_platform_data *pdata;
6b658c31 474 struct device *parent = indio_dev->dev.parent;
f01a140a 475 int err;
7be56a8f
DC
476
477 indio_dev->modes = INDIO_DIRECT_MODE;
478 indio_dev->info = &gyro_info;
479
1ecd245e 480 err = st_sensors_verify_id(indio_dev);
7be56a8f 481 if (err < 0)
7db4f2ca 482 return err;
7be56a8f 483
607a568a 484 gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
a7ee8839 485 indio_dev->channels = gdata->sensor_settings->ch;
7be56a8f
DC
486 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
487
e4269651 488 err = iio_read_mount_matrix(parent, &gdata->mount_matrix);
e1c5d708
LW
489 if (err)
490 return err;
491
1f38527d 492 gdata->current_fullscale = &gdata->sensor_settings->fs.fs_avl[0];
a7ee8839 493 gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
7be56a8f 494
1f38527d
AS
495 pdata = (struct st_sensors_platform_data *)&gyro_pdata;
496
497 err = st_sensors_init_sensor(indio_dev, pdata);
7be56a8f 498 if (err < 0)
7db4f2ca 499 return err;
7be56a8f 500
fb4ea1f8
DC
501 err = st_gyro_allocate_ring(indio_dev);
502 if (err < 0)
7db4f2ca 503 return err;
7be56a8f 504
9cd15d52 505 if (gdata->irq > 0) {
7be56a8f 506 err = st_sensors_allocate_trigger(indio_dev,
8ce4a56a 507 ST_GYRO_TRIGGER_OPS);
7be56a8f 508 if (err < 0)
a574e68f 509 return err;
7be56a8f
DC
510 }
511
6b658c31 512 return devm_iio_device_register(parent, indio_dev);
7be56a8f 513}
0805b512 514EXPORT_SYMBOL_NS(st_gyro_common_probe, IIO_ST_SENSORS);
7be56a8f 515
7be56a8f
DC
516MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
517MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
518MODULE_LICENSE("GPL v2");
0805b512 519MODULE_IMPORT_NS(IIO_ST_SENSORS);