Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2020 Invensense, Inc.
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      * T°C = (temp / 132.48) + 25
0070      * Tm°C = 1000 * ((temp * 100 / 13248) + 25)
0071      * scale: 100000 / 13248 ~= 7.548309
0072      * offset: 25000
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 }