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