1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2020 Invensense, Inc.
6 #include <linux/kernel.h>
7 #include <linux/device.h>
8 #include <linux/mutex.h>
9 #include <linux/pm_runtime.h>
10 #include <linux/regmap.h>
11 #include <linux/iio/iio.h>
13 #include "inv_icm42600.h"
14 #include "inv_icm42600_temp.h"
16 static int inv_icm42600_temp_read(struct inv_icm42600_state
*st
, int16_t *temp
)
18 struct device
*dev
= regmap_get_device(st
->map
);
22 pm_runtime_get_sync(dev
);
23 mutex_lock(&st
->lock
);
25 ret
= inv_icm42600_set_temp_conf(st
, true, NULL
);
29 raw
= (__be16
*)&st
->buffer
[0];
30 ret
= regmap_bulk_read(st
->map
, INV_ICM42600_REG_TEMP_DATA
, raw
, sizeof(*raw
));
34 *temp
= (int16_t)be16_to_cpup(raw
);
35 if (*temp
== INV_ICM42600_DATA_INVALID
)
39 mutex_unlock(&st
->lock
);
40 pm_runtime_mark_last_busy(dev
);
41 pm_runtime_put_autosuspend(dev
);
46 int inv_icm42600_temp_read_raw(struct iio_dev
*indio_dev
,
47 struct iio_chan_spec
const *chan
,
48 int *val
, int *val2
, long mask
)
50 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
54 if (chan
->type
!= IIO_TEMP
)
58 case IIO_CHAN_INFO_RAW
:
59 ret
= iio_device_claim_direct_mode(indio_dev
);
62 ret
= inv_icm42600_temp_read(st
, &temp
);
63 iio_device_release_direct_mode(indio_dev
);
69 * T°C = (temp / 132.48) + 25
70 * Tm°C = 1000 * ((temp * 100 / 13248) + 25)
71 * scale: 100000 / 13248 ~= 7.548309
74 case IIO_CHAN_INFO_SCALE
:
77 return IIO_VAL_INT_PLUS_MICRO
;
78 case IIO_CHAN_INFO_OFFSET
: