blob: 9d9ee200da9276fad0a653c6bb40f0aa388138a4 [file] [log] [blame]
Mario Tesic6a86652018-04-24 11:49:14 +02001/*
2 * STMicroelectronics st_asm330lhh sensor driver
3 *
4 * Copyright 2018 STMicroelectronics Inc.
5 *
6 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
7 *
8 * Licensed under the GPL-2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/iio/iio.h>
15#include <linux/iio/sysfs.h>
16#include <linux/pm.h>
17#include <linux/version.h>
18#include <linux/of.h>
19
20#include <linux/platform_data/st_sensors_pdata.h>
21
22#include "st_asm330lhh.h"
23
24#define ST_ASM330LHH_REG_INT1_ADDR 0x0d
25#define ST_ASM330LHH_REG_INT2_ADDR 0x0e
26#define ST_ASM330LHH_REG_FIFO_CTRL4_ADDR 0x0a
27#define ST_ASM330LHH_REG_FIFO_FTH_IRQ_MASK BIT(3)
28#define ST_ASM330LHH_REG_WHOAMI_ADDR 0x0f
29#define ST_ASM330LHH_WHOAMI_VAL 0x6b
30#define ST_ASM330LHH_REG_CTRL1_XL_ADDR 0x10
31#define ST_ASM330LHH_REG_CTRL2_G_ADDR 0x11
32#define ST_ASM330LHH_REG_RESET_ADDR 0x12
33#define ST_ASM330LHH_REG_RESET_MASK BIT(0)
34#define ST_ASM330LHH_REG_BDU_ADDR 0x12
35#define ST_ASM330LHH_REG_BDU_MASK BIT(6)
36#define ST_ASM330LHH_REG_INT2_ON_INT1_ADDR 0x13
37#define ST_ASM330LHH_REG_INT2_ON_INT1_MASK BIT(5)
38#define ST_ASM330LHH_REG_ROUNDING_ADDR 0x14
39#define ST_ASM330LHH_REG_ROUNDING_MASK GENMASK(6, 5)
40#define ST_ASM330LHH_REG_TIMESTAMP_EN_ADDR 0x19
41#define ST_ASM330LHH_REG_TIMESTAMP_EN_MASK BIT(5)
42
43#define ST_ASM330LHH_REG_GYRO_OUT_X_L_ADDR 0x22
44#define ST_ASM330LHH_REG_GYRO_OUT_Y_L_ADDR 0x24
45#define ST_ASM330LHH_REG_GYRO_OUT_Z_L_ADDR 0x26
46
47#define ST_ASM330LHH_REG_ACC_OUT_X_L_ADDR 0x28
48#define ST_ASM330LHH_REG_ACC_OUT_Y_L_ADDR 0x2a
49#define ST_ASM330LHH_REG_ACC_OUT_Z_L_ADDR 0x2c
50
51#define ST_ASM330LHH_REG_LIR_ADDR 0x56
52#define ST_ASM330LHH_REG_LIR_MASK BIT(0)
53
54#define ST_ASM330LHH_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61)
55#define ST_ASM330LHH_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122)
56#define ST_ASM330LHH_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244)
57#define ST_ASM330LHH_ACC_FS_16G_GAIN IIO_G_TO_M_S_2(488)
58
59#define ST_ASM330LHH_GYRO_FS_125_GAIN IIO_DEGREE_TO_RAD(4375)
60#define ST_ASM330LHH_GYRO_FS_250_GAIN IIO_DEGREE_TO_RAD(8750)
61#define ST_ASM330LHH_GYRO_FS_500_GAIN IIO_DEGREE_TO_RAD(17500)
62#define ST_ASM330LHH_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000)
63#define ST_ASM330LHH_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000)
64#define ST_ASM330LHH_GYRO_FS_4000_GAIN IIO_DEGREE_TO_RAD(140000)
65
66/* Temperature in uC */
67#define ST_ASM330LHH_TEMP_GAIN 256
68#define ST_ASM330LHH_TEMP_FS_GAIN (1000000 / ST_ASM330LHH_TEMP_GAIN)
69#define ST_ASM330LHH_OFFSET (6400)
70
71struct st_asm330lhh_std_entry {
72 u16 odr;
73 u8 val;
74};
75
76/* Minimal number of sample to be discarded */
77struct st_asm330lhh_std_entry st_asm330lhh_std_table[] = {
78 { 13, 2 },
79 { 26, 3 },
80 { 52, 4 },
81 { 104, 6 },
82 { 208, 8 },
83 { 416, 18 },
84};
85
86static const struct st_asm330lhh_odr_table_entry st_asm330lhh_odr_table[] = {
87 [ST_ASM330LHH_ID_ACC] = {
88 .reg = {
89 .addr = ST_ASM330LHH_REG_CTRL1_XL_ADDR,
90 .mask = GENMASK(7, 4),
91 },
92 .odr_avl[0] = { 0, 0x00 },
93 .odr_avl[1] = { 13, 0x01 },
94 .odr_avl[2] = { 26, 0x02 },
95 .odr_avl[3] = { 52, 0x03 },
96 .odr_avl[4] = { 104, 0x04 },
97 .odr_avl[5] = { 208, 0x05 },
98 .odr_avl[6] = { 416, 0x06 },
99 },
100 [ST_ASM330LHH_ID_GYRO] = {
101 .reg = {
102 .addr = ST_ASM330LHH_REG_CTRL2_G_ADDR,
103 .mask = GENMASK(7, 4),
104 },
105 .odr_avl[0] = { 0, 0x00 },
106 .odr_avl[1] = { 13, 0x01 },
107 .odr_avl[2] = { 26, 0x02 },
108 .odr_avl[3] = { 52, 0x03 },
109 .odr_avl[4] = { 104, 0x04 },
110 .odr_avl[5] = { 208, 0x05 },
111 .odr_avl[6] = { 416, 0x06 },
112 },
113 [ST_ASM330LHH_ID_TEMP] = {
114 .odr_avl[0] = { 0, 0x00 },
115 .odr_avl[1] = { 52, 0x01 },
116 }
117};
118
119static const struct st_asm330lhh_fs_table_entry st_asm330lhh_fs_table[] = {
120 [ST_ASM330LHH_ID_ACC] = {
121 .reg = {
122 .addr = ST_ASM330LHH_REG_CTRL1_XL_ADDR,
123 .mask = GENMASK(3, 2),
124 },
125 .size = ST_ASM330LHH_FS_ACC_LIST_SIZE,
126 .fs_avl[0] = { ST_ASM330LHH_ACC_FS_2G_GAIN, 0x0 },
127 .fs_avl[1] = { ST_ASM330LHH_ACC_FS_4G_GAIN, 0x2 },
128 .fs_avl[2] = { ST_ASM330LHH_ACC_FS_8G_GAIN, 0x3 },
129 .fs_avl[3] = { ST_ASM330LHH_ACC_FS_16G_GAIN, 0x1 },
130 },
131 [ST_ASM330LHH_ID_GYRO] = {
132 .reg = {
133 .addr = ST_ASM330LHH_REG_CTRL2_G_ADDR,
134 .mask = GENMASK(3, 0),
135 },
136 .size = ST_ASM330LHH_FS_GYRO_LIST_SIZE,
137 .fs_avl[0] = { ST_ASM330LHH_GYRO_FS_125_GAIN, 0x2 },
138 .fs_avl[1] = { ST_ASM330LHH_GYRO_FS_250_GAIN, 0x0 },
139 .fs_avl[2] = { ST_ASM330LHH_GYRO_FS_500_GAIN, 0x4 },
140 .fs_avl[3] = { ST_ASM330LHH_GYRO_FS_1000_GAIN, 0x8 },
141 .fs_avl[4] = { ST_ASM330LHH_GYRO_FS_2000_GAIN, 0xC },
142 .fs_avl[5] = { ST_ASM330LHH_GYRO_FS_4000_GAIN, 0x1 },
143 },
144 [ST_ASM330LHH_ID_TEMP] = {
145 .size = ST_ASM330LHH_FS_TEMP_LIST_SIZE,
146 .fs_avl[0] = { ST_ASM330LHH_TEMP_FS_GAIN, 0x0 },
147 }
148};
149
150static const struct iio_chan_spec st_asm330lhh_acc_channels[] = {
151 ST_ASM330LHH_CHANNEL(IIO_ACCEL, ST_ASM330LHH_REG_ACC_OUT_X_L_ADDR,
152 1, IIO_MOD_X, 0, 16, 16, 's'),
153 ST_ASM330LHH_CHANNEL(IIO_ACCEL, ST_ASM330LHH_REG_ACC_OUT_Y_L_ADDR,
154 1, IIO_MOD_Y, 1, 16, 16, 's'),
155 ST_ASM330LHH_CHANNEL(IIO_ACCEL, ST_ASM330LHH_REG_ACC_OUT_Z_L_ADDR,
156 1, IIO_MOD_Z, 2, 16, 16, 's'),
157 ST_ASM330LHH_FLUSH_CHANNEL(IIO_ACCEL),
158 IIO_CHAN_SOFT_TIMESTAMP(3),
159};
160
161static const struct iio_chan_spec st_asm330lhh_gyro_channels[] = {
162 ST_ASM330LHH_CHANNEL(IIO_ANGL_VEL, ST_ASM330LHH_REG_GYRO_OUT_X_L_ADDR,
163 1, IIO_MOD_X, 0, 16, 16, 's'),
164 ST_ASM330LHH_CHANNEL(IIO_ANGL_VEL, ST_ASM330LHH_REG_GYRO_OUT_Y_L_ADDR,
165 1, IIO_MOD_Y, 1, 16, 16, 's'),
166 ST_ASM330LHH_CHANNEL(IIO_ANGL_VEL, ST_ASM330LHH_REG_GYRO_OUT_Z_L_ADDR,
167 1, IIO_MOD_Z, 2, 16, 16, 's'),
168 ST_ASM330LHH_FLUSH_CHANNEL(IIO_ANGL_VEL),
169 IIO_CHAN_SOFT_TIMESTAMP(3),
170};
171
172static const struct iio_chan_spec st_asm330lhh_temp_channels[] = {
173 {
174 .type = IIO_TEMP,
175 .address = ST_ASM330LHH_REG_OUT_TEMP_L_ADDR,
176 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
177 | BIT(IIO_CHAN_INFO_OFFSET)
178 | BIT(IIO_CHAN_INFO_SCALE),
179 .scan_index = -1,
180 },
181};
182
183int st_asm330lhh_write_with_mask(struct st_asm330lhh_hw *hw, u8 addr, u8 mask,
184 u8 val)
185{
186 u8 data;
187 int err;
188
189 mutex_lock(&hw->lock);
190
191 err = hw->tf->read(hw->dev, addr, sizeof(data), &data);
192 if (err < 0) {
193 dev_err(hw->dev, "failed to read %02x register\n", addr);
194 goto out;
195 }
196
197 data = (data & ~mask) | ((val << __ffs(mask)) & mask);
198
199 err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
200 if (err < 0)
201 dev_err(hw->dev, "failed to write %02x register\n", addr);
202
203out:
204 mutex_unlock(&hw->lock);
205
206 return err;
207}
208
209static int st_asm330lhh_check_whoami(struct st_asm330lhh_hw *hw)
210{
211 int err;
212 u8 data;
213
214 err = hw->tf->read(hw->dev, ST_ASM330LHH_REG_WHOAMI_ADDR, sizeof(data),
215 &data);
216 if (err < 0) {
217 dev_err(hw->dev, "failed to read whoami register\n");
218 return err;
219 }
220
221 if (data != ST_ASM330LHH_WHOAMI_VAL) {
222 dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
223 return -ENODEV;
224 }
225
226 return 0;
227}
228
229static int st_asm330lhh_set_full_scale(struct st_asm330lhh_sensor *sensor,
230 u32 gain)
231{
232 enum st_asm330lhh_sensor_id id = sensor->id;
233 int i, err;
234 u8 val;
235
236 for (i = 0; i < st_asm330lhh_fs_table[id].size; i++)
237 if (st_asm330lhh_fs_table[id].fs_avl[i].gain == gain)
238 break;
239
240 if (i == st_asm330lhh_fs_table[id].size)
241 return -EINVAL;
242
243 val = st_asm330lhh_fs_table[id].fs_avl[i].val;
244 err = st_asm330lhh_write_with_mask(sensor->hw,
245 st_asm330lhh_fs_table[id].reg.addr,
246 st_asm330lhh_fs_table[id].reg.mask,
247 val);
248 if (err < 0)
249 return err;
250
251 sensor->gain = gain;
252
253 return 0;
254}
255
256int st_asm330lhh_get_odr_val(enum st_asm330lhh_sensor_id id, u16 odr, u8 *val)
257{
258 int i;
259
260 for (i = 0; i < ST_ASM330LHH_ODR_LIST_SIZE; i++)
261 if (st_asm330lhh_odr_table[id].odr_avl[i].hz >= odr)
262 break;
263
264 if (i == ST_ASM330LHH_ODR_LIST_SIZE)
265 return -EINVAL;
266
267 *val = st_asm330lhh_odr_table[id].odr_avl[i].val;
268
269 return 0;
270}
271
272static int st_asm330lhh_set_std_level(struct st_asm330lhh_sensor *sensor,
273 u16 odr)
274{
275 int i;
276
277 for (i = 0; i < ARRAY_SIZE(st_asm330lhh_std_table); i++)
278 if (st_asm330lhh_std_table[i].odr == odr)
279 break;
280
281 if (i == ARRAY_SIZE(st_asm330lhh_std_table))
282 return -EINVAL;
283
284 sensor->std_level = st_asm330lhh_std_table[i].val;
285 sensor->std_samples = 0;
286
287 return 0;
288}
289
290static int st_asm330lhh_set_odr(struct st_asm330lhh_sensor *sensor, u16 odr)
291{
292 struct st_asm330lhh_hw *hw = sensor->hw;
293 u8 val;
294
295 if (st_asm330lhh_get_odr_val(sensor->id, odr, &val) < 0)
296 return -EINVAL;
297
298 return st_asm330lhh_write_with_mask(hw,
299 st_asm330lhh_odr_table[sensor->id].reg.addr,
300 st_asm330lhh_odr_table[sensor->id].reg.mask, val);
301}
302
303int st_asm330lhh_sensor_set_enable(struct st_asm330lhh_sensor *sensor,
304 bool enable)
305{
306 u16 odr = enable ? sensor->odr : 0;
307 int err;
308
309 if (sensor->id != ST_ASM330LHH_ID_TEMP) {
310 err = st_asm330lhh_set_odr(sensor, odr);
311 if (err < 0)
312 return err;
313 }
314
315 if (enable)
316 sensor->hw->enable_mask |= BIT(sensor->id);
317 else
318 sensor->hw->enable_mask &= ~BIT(sensor->id);
319
320 return 0;
321}
322
323static int st_asm330lhh_read_oneshot(struct st_asm330lhh_sensor *sensor,
324 u8 addr, int *val)
325{
326 int err, delay;
327 __le16 data;
328
329 if (sensor->id == ST_ASM330LHH_ID_TEMP) {
330 u8 status;
331
332 mutex_lock(&sensor->hw->fifo_lock);
333 err = sensor->hw->tf->read(sensor->hw->dev,
334 ST_ASM330LHH_REG_STATUS_ADDR, sizeof(status), &status);
335 if (err < 0)
336 goto unlock;
337
338 if (status & ST_ASM330LHH_REG_STATUS_TDA) {
339 err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data),
340 (u8 *)&data);
341 if (err < 0)
342 goto unlock;
343
344 sensor->old_data = data;
345 } else
346 data = sensor->old_data;
347unlock:
348 mutex_unlock(&sensor->hw->fifo_lock);
349
350 } else {
351 err = st_asm330lhh_sensor_set_enable(sensor, true);
352 if (err < 0)
353 return err;
354
355 delay = 1000000 / sensor->odr;
356 usleep_range(delay, 2 * delay);
357
358 err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data),
359 (u8 *)&data);
360 if (err < 0)
361 return err;
362
363 st_asm330lhh_sensor_set_enable(sensor, false);
364 }
365
366 *val = (s16)data;
367
368 return IIO_VAL_INT;
369}
370
371static int st_asm330lhh_read_raw(struct iio_dev *iio_dev,
372 struct iio_chan_spec const *ch,
373 int *val, int *val2, long mask)
374{
375 struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
376 int ret;
377
378 switch (mask) {
379 case IIO_CHAN_INFO_RAW:
380 mutex_lock(&iio_dev->mlock);
381 if (iio_buffer_enabled(iio_dev)) {
382 ret = -EBUSY;
383 mutex_unlock(&iio_dev->mlock);
384 break;
385 }
386 ret = st_asm330lhh_read_oneshot(sensor, ch->address, val);
387 mutex_unlock(&iio_dev->mlock);
388 break;
389 case IIO_CHAN_INFO_OFFSET:
390 switch (ch->type) {
391 case IIO_TEMP:
392 *val = sensor->offset;
393 ret = IIO_VAL_INT;
394 break;
395 default:
396 return -EINVAL;
397 }
398 break;
399 case IIO_CHAN_INFO_SAMP_FREQ:
400 *val = sensor->odr;
401 ret = IIO_VAL_INT;
402 break;
403 case IIO_CHAN_INFO_SCALE:
404 switch (ch->type) {
405 case IIO_TEMP:
406 *val = 1;
407 *val2 = ST_ASM330LHH_TEMP_GAIN;
408 ret = IIO_VAL_FRACTIONAL;
409 break;
410 case IIO_ACCEL:
411 case IIO_ANGL_VEL:
412 *val = 0;
413 *val2 = sensor->gain;
414 ret = IIO_VAL_INT_PLUS_MICRO;
415 break;
416 default:
417 return -EINVAL;
418 }
419 break;
420 default:
421 ret = -EINVAL;
422 break;
423 }
424
425 return ret;
426}
427
428static int st_asm330lhh_write_raw(struct iio_dev *iio_dev,
429 struct iio_chan_spec const *chan,
430 int val, int val2, long mask)
431{
432 struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
433 int err;
434
435 mutex_lock(&iio_dev->mlock);
436
437 switch (mask) {
438 case IIO_CHAN_INFO_SCALE:
439 err = st_asm330lhh_set_full_scale(sensor, val2);
440 break;
441 case IIO_CHAN_INFO_SAMP_FREQ: {
442 u8 data;
443
444 err = st_asm330lhh_set_std_level(sensor, val);
445 if (err < 0)
446 break;
447
448 err = st_asm330lhh_get_odr_val(sensor->id, val, &data);
449 if (!err)
450 sensor->odr = val;
451
452 err = st_asm330lhh_set_odr(sensor, sensor->odr);
453 break;
454 }
455 default:
456 err = -EINVAL;
457 break;
458 }
459
460 mutex_unlock(&iio_dev->mlock);
461
462 return err;
463}
464
465static ssize_t
466st_asm330lhh_sysfs_sampling_frequency_avail(struct device *dev,
467 struct device_attribute *attr,
468 char *buf)
469{
470 struct st_asm330lhh_sensor *sensor = iio_priv(dev_get_drvdata(dev));
471 enum st_asm330lhh_sensor_id id = sensor->id;
472 int i, len = 0;
473
474 for (i = 1; i < ST_ASM330LHH_ODR_LIST_SIZE; i++)
475 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
476 st_asm330lhh_odr_table[id].odr_avl[i].hz);
477 buf[len - 1] = '\n';
478
479 return len;
480}
481
482static ssize_t st_asm330lhh_sysfs_scale_avail(struct device *dev,
483 struct device_attribute *attr,
484 char *buf)
485{
486 struct st_asm330lhh_sensor *sensor = iio_priv(dev_get_drvdata(dev));
487 enum st_asm330lhh_sensor_id id = sensor->id;
488 int i, len = 0;
489
490 for (i = 0; i < st_asm330lhh_fs_table[id].size; i++)
491 len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
492 st_asm330lhh_fs_table[id].fs_avl[i].gain);
493 buf[len - 1] = '\n';
494
495 return len;
496}
497
498static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_asm330lhh_sysfs_sampling_frequency_avail);
499static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
500 st_asm330lhh_sysfs_scale_avail, NULL, 0);
501static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
502 st_asm330lhh_sysfs_scale_avail, NULL, 0);
503static IIO_DEVICE_ATTR(in_temp_scale_available, 0444,
504 st_asm330lhh_sysfs_scale_avail, NULL, 0);
505static IIO_DEVICE_ATTR(hwfifo_watermark_max, 0444,
506 st_asm330lhh_get_max_watermark, NULL, 0);
507static IIO_DEVICE_ATTR(hwfifo_flush, 0200, NULL, st_asm330lhh_flush_fifo, 0);
508static IIO_DEVICE_ATTR(hwfifo_watermark, 0644, st_asm330lhh_get_watermark,
509 st_asm330lhh_set_watermark, 0);
510
511static struct attribute *st_asm330lhh_acc_attributes[] = {
512 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
513 &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
514 &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
515 &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
516 &iio_dev_attr_hwfifo_flush.dev_attr.attr,
517 NULL,
518};
519
520static const struct attribute_group st_asm330lhh_acc_attribute_group = {
521 .attrs = st_asm330lhh_acc_attributes,
522};
523
524static const struct iio_info st_asm330lhh_acc_info = {
525 .driver_module = THIS_MODULE,
526 .attrs = &st_asm330lhh_acc_attribute_group,
527 .read_raw = st_asm330lhh_read_raw,
528 .write_raw = st_asm330lhh_write_raw,
529};
530
531static struct attribute *st_asm330lhh_gyro_attributes[] = {
532 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
533 &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
534 &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
535 &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
536 &iio_dev_attr_hwfifo_flush.dev_attr.attr,
537 NULL,
538};
539
540static const struct attribute_group st_asm330lhh_gyro_attribute_group = {
541 .attrs = st_asm330lhh_gyro_attributes,
542};
543
544static const struct iio_info st_asm330lhh_gyro_info = {
545 .driver_module = THIS_MODULE,
546 .attrs = &st_asm330lhh_gyro_attribute_group,
547 .read_raw = st_asm330lhh_read_raw,
548 .write_raw = st_asm330lhh_write_raw,
549};
550
551static struct attribute *st_asm330lhh_temp_attributes[] = {
552 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
553 &iio_dev_attr_in_temp_scale_available.dev_attr.attr,
554 &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
555 &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
556 &iio_dev_attr_hwfifo_flush.dev_attr.attr,
557 NULL,
558};
559
560static const struct attribute_group st_asm330lhh_temp_attribute_group = {
561 .attrs = st_asm330lhh_temp_attributes,
562};
563
564static const struct iio_info st_asm330lhh_temp_info = {
565 .driver_module = THIS_MODULE,
566 .attrs = &st_asm330lhh_temp_attribute_group,
567 .read_raw = st_asm330lhh_read_raw,
568 .write_raw = st_asm330lhh_write_raw,
569};
570
571static const unsigned long st_asm330lhh_available_scan_masks[] = { 0x7, 0x0 };
572
573static int st_asm330lhh_of_get_drdy_pin(struct st_asm330lhh_hw *hw, int *drdy_pin)
574{
575 struct device_node *np = hw->dev->of_node;
576
577 if (!np)
578 return -EINVAL;
579
580 return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
581}
582
583static int st_asm330lhh_get_drdy_reg(struct st_asm330lhh_hw *hw, u8 *drdy_reg)
584{
585 int err = 0, drdy_pin;
586
587 if (st_asm330lhh_of_get_drdy_pin(hw, &drdy_pin) < 0) {
588 struct st_sensors_platform_data *pdata;
589 struct device *dev = hw->dev;
590
591 pdata = (struct st_sensors_platform_data *)dev->platform_data;
592 drdy_pin = pdata ? pdata->drdy_int_pin : 1;
593 }
594
595 switch (drdy_pin) {
596 case 1:
597 *drdy_reg = ST_ASM330LHH_REG_INT1_ADDR;
598 break;
599 case 2:
600 *drdy_reg = ST_ASM330LHH_REG_INT2_ADDR;
601 break;
602 default:
603 dev_err(hw->dev, "unsupported data ready pin\n");
604 err = -EINVAL;
605 break;
606 }
607
608 return err;
609}
610
611static int st_asm330lhh_init_device(struct st_asm330lhh_hw *hw)
612{
613 u8 drdy_int_reg;
614 int err;
615
616 err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_RESET_ADDR,
617 ST_ASM330LHH_REG_RESET_MASK, 1);
618 if (err < 0)
619 return err;
620
621 msleep(200);
622
623 /* latch interrupts */
624 err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_LIR_ADDR,
625 ST_ASM330LHH_REG_LIR_MASK, 1);
626 if (err < 0)
627 return err;
628
629 /* enable Block Data Update */
630 err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_BDU_ADDR,
631 ST_ASM330LHH_REG_BDU_MASK, 1);
632 if (err < 0)
633 return err;
634
635 err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_ROUNDING_ADDR,
636 ST_ASM330LHH_REG_ROUNDING_MASK, 3);
637 if (err < 0)
638 return err;
639
640 /* init timestamp engine */
641 err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_TIMESTAMP_EN_ADDR,
642 ST_ASM330LHH_REG_TIMESTAMP_EN_MASK, 1);
643 if (err < 0)
644 return err;
645
646 /* enable FIFO watermak interrupt */
647 err = st_asm330lhh_get_drdy_reg(hw, &drdy_int_reg);
648 if (err < 0)
649 return err;
650
651 return st_asm330lhh_write_with_mask(hw, drdy_int_reg,
652 ST_ASM330LHH_REG_FIFO_FTH_IRQ_MASK, 1);
653}
654
655static struct iio_dev *st_asm330lhh_alloc_iiodev(struct st_asm330lhh_hw *hw,
656 enum st_asm330lhh_sensor_id id)
657{
658 struct st_asm330lhh_sensor *sensor;
659 struct iio_dev *iio_dev;
660
661 iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
662 if (!iio_dev)
663 return NULL;
664
665 iio_dev->modes = INDIO_DIRECT_MODE;
666 iio_dev->dev.parent = hw->dev;
667 iio_dev->available_scan_masks = st_asm330lhh_available_scan_masks;
668
669 sensor = iio_priv(iio_dev);
670 sensor->id = id;
671 sensor->hw = hw;
672 sensor->odr = st_asm330lhh_odr_table[id].odr_avl[1].hz;
673 sensor->gain = st_asm330lhh_fs_table[id].fs_avl[0].gain;
674 sensor->watermark = 1;
675 sensor->old_data = 0;
676
677 switch (id) {
678 case ST_ASM330LHH_ID_ACC:
679 iio_dev->channels = st_asm330lhh_acc_channels;
680 iio_dev->num_channels = ARRAY_SIZE(st_asm330lhh_acc_channels);
681 iio_dev->name = "asm330lhh_accel";
682 iio_dev->info = &st_asm330lhh_acc_info;
683 sensor->batch_addr = ST_ASM330LHH_REG_FIFO_BATCH_ADDR;
684 sensor->batch_mask = GENMASK(3, 0);
685 sensor->offset = 0;
686 break;
687 case ST_ASM330LHH_ID_GYRO:
688 iio_dev->channels = st_asm330lhh_gyro_channels;
689 iio_dev->num_channels = ARRAY_SIZE(st_asm330lhh_gyro_channels);
690 iio_dev->name = "asm330lhh_gyro";
691 iio_dev->info = &st_asm330lhh_gyro_info;
692 sensor->batch_addr = ST_ASM330LHH_REG_FIFO_BATCH_ADDR;
693 sensor->batch_mask = GENMASK(7, 4);
694 sensor->offset = 0;
695 break;
696 case ST_ASM330LHH_ID_TEMP:
697 iio_dev->channels = st_asm330lhh_temp_channels;
698 iio_dev->num_channels = ARRAY_SIZE(st_asm330lhh_temp_channels);
699 iio_dev->name = "asm330lhh_temp";
700 iio_dev->info = &st_asm330lhh_temp_info;
701 sensor->offset = ST_ASM330LHH_OFFSET;
702 break;
703 default:
704 return NULL;
705 }
706
707 return iio_dev;
708}
709
710int st_asm330lhh_probe(struct device *dev, int irq,
711 const struct st_asm330lhh_transfer_function *tf_ops)
712{
713 struct st_asm330lhh_hw *hw;
714 int i, err;
715
716 hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
717 if (!hw)
718 return -ENOMEM;
719
720 dev_set_drvdata(dev, (void *)hw);
721
722 mutex_init(&hw->lock);
723 mutex_init(&hw->fifo_lock);
724
725 hw->dev = dev;
726 hw->irq = irq;
727 hw->tf = tf_ops;
728
729 dev_info(hw->dev, "Ver: %s\n", ST_ASM330LHH_VERSION);
730 err = st_asm330lhh_check_whoami(hw);
731 if (err < 0)
732 return err;
733
734 err = st_asm330lhh_init_device(hw);
735 if (err < 0)
736 return err;
737
738 for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
739 hw->iio_devs[i] = st_asm330lhh_alloc_iiodev(hw, i);
740 if (!hw->iio_devs[i])
741 return -ENOMEM;
742 }
743
744 if (hw->irq > 0) {
745 err = st_asm330lhh_fifo_setup(hw);
746 if (err < 0)
747 return err;
748 }
749
750 for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
751 if (!hw->iio_devs[i])
752 continue;
753
754 err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
755 if (err)
756 return err;
757 }
758
759 dev_info(hw->dev, "probe ok\n");
760
761 return 0;
762}
763EXPORT_SYMBOL(st_asm330lhh_probe);
764
765static int __maybe_unused st_asm330lhh_suspend(struct device *dev)
766{
767 struct st_asm330lhh_hw *hw = dev_get_drvdata(dev);
768 struct st_asm330lhh_sensor *sensor;
769 int i, err = 0;
770
771 for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
772 if (!hw->iio_devs[i])
773 continue;
774
775 sensor = iio_priv(hw->iio_devs[i]);
776
777 if (!(hw->enable_mask & BIT(sensor->id)))
778 continue;
779
780 err = st_asm330lhh_set_odr(sensor, 0);
781 if (err < 0)
782 return err;
783 }
784
785 if (hw->enable_mask)
786 err = st_asm330lhh_suspend_fifo(hw);
787
788 return err;
789}
790
791static int __maybe_unused st_asm330lhh_resume(struct device *dev)
792{
793 struct st_asm330lhh_hw *hw = dev_get_drvdata(dev);
794 struct st_asm330lhh_sensor *sensor;
795 int i, err = 0;
796
797 for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
798 if (!hw->iio_devs[i])
799 continue;
800
801 sensor = iio_priv(hw->iio_devs[i]);
802 if (!(hw->enable_mask & BIT(sensor->id)))
803 continue;
804
805 err = st_asm330lhh_set_odr(sensor, sensor->odr);
806 if (err < 0)
807 return err;
808 }
809
810 if (hw->enable_mask)
811 err = st_asm330lhh_set_fifo_mode(hw, ST_ASM330LHH_FIFO_CONT);
812
813 return err;
814}
815
816const struct dev_pm_ops st_asm330lhh_pm_ops = {
817 SET_SYSTEM_SLEEP_PM_OPS(st_asm330lhh_suspend, st_asm330lhh_resume)
818};
819EXPORT_SYMBOL(st_asm330lhh_pm_ops);
820
821MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
822MODULE_DESCRIPTION("STMicroelectronics st_asm330lhh driver");
823MODULE_LICENSE("GPL v2");
824MODULE_VERSION(ST_ASM330LHH_VERSION);