0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/device.h>
0008 #include <linux/mutex.h>
0009 #include <linux/pm_runtime.h>
0010 #include <linux/regmap.h>
0011 #include <linux/iio/iio.h>
0012
0013 #include "inv_icm42600.h"
0014 #include "inv_icm42600_temp.h"
0015
0016 static int inv_icm42600_temp_read(struct inv_icm42600_state *st, int16_t *temp)
0017 {
0018 struct device *dev = regmap_get_device(st->map);
0019 __be16 *raw;
0020 int ret;
0021
0022 pm_runtime_get_sync(dev);
0023 mutex_lock(&st->lock);
0024
0025 ret = inv_icm42600_set_temp_conf(st, true, NULL);
0026 if (ret)
0027 goto exit;
0028
0029 raw = (__be16 *)&st->buffer[0];
0030 ret = regmap_bulk_read(st->map, INV_ICM42600_REG_TEMP_DATA, raw, sizeof(*raw));
0031 if (ret)
0032 goto exit;
0033
0034 *temp = (int16_t)be16_to_cpup(raw);
0035 if (*temp == INV_ICM42600_DATA_INVALID)
0036 ret = -EINVAL;
0037
0038 exit:
0039 mutex_unlock(&st->lock);
0040 pm_runtime_mark_last_busy(dev);
0041 pm_runtime_put_autosuspend(dev);
0042
0043 return ret;
0044 }
0045
0046 int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev,
0047 struct iio_chan_spec const *chan,
0048 int *val, int *val2, long mask)
0049 {
0050 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0051 int16_t temp;
0052 int ret;
0053
0054 if (chan->type != IIO_TEMP)
0055 return -EINVAL;
0056
0057 switch (mask) {
0058 case IIO_CHAN_INFO_RAW:
0059 ret = iio_device_claim_direct_mode(indio_dev);
0060 if (ret)
0061 return ret;
0062 ret = inv_icm42600_temp_read(st, &temp);
0063 iio_device_release_direct_mode(indio_dev);
0064 if (ret)
0065 return ret;
0066 *val = temp;
0067 return IIO_VAL_INT;
0068
0069
0070
0071
0072
0073
0074 case IIO_CHAN_INFO_SCALE:
0075 *val = 7;
0076 *val2 = 548309;
0077 return IIO_VAL_INT_PLUS_MICRO;
0078 case IIO_CHAN_INFO_OFFSET:
0079 *val = 25000;
0080 return IIO_VAL_INT;
0081 default:
0082 return -EINVAL;
0083 }
0084 }