cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

st_lsm9ds0_core.c (3835B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * STMicroelectronics LSM9DS0 IMU driver
      4 *
      5 * Copyright (C) 2021, Intel Corporation
      6 *
      7 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
      8 */
      9
     10#include <linux/device.h>
     11#include <linux/err.h>
     12#include <linux/module.h>
     13#include <linux/regmap.h>
     14#include <linux/regulator/consumer.h>
     15
     16#include <linux/iio/common/st_sensors.h>
     17#include <linux/iio/iio.h>
     18
     19#include "st_lsm9ds0.h"
     20
     21static int st_lsm9ds0_power_enable(struct device *dev, struct st_lsm9ds0 *lsm9ds0)
     22{
     23	int ret;
     24
     25	/* Regulators not mandatory, but if requested we should enable them. */
     26	lsm9ds0->vdd = devm_regulator_get(dev, "vdd");
     27	if (IS_ERR(lsm9ds0->vdd))
     28		return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd),
     29				     "unable to get Vdd supply\n");
     30
     31	ret = regulator_enable(lsm9ds0->vdd);
     32	if (ret) {
     33		dev_warn(dev, "Failed to enable specified Vdd supply\n");
     34		return ret;
     35	}
     36
     37	lsm9ds0->vdd_io = devm_regulator_get(dev, "vddio");
     38	if (IS_ERR(lsm9ds0->vdd_io)) {
     39		regulator_disable(lsm9ds0->vdd);
     40		return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd_io),
     41				     "unable to get Vdd_IO supply\n");
     42	}
     43	ret = regulator_enable(lsm9ds0->vdd_io);
     44	if (ret) {
     45		dev_warn(dev, "Failed to enable specified Vdd_IO supply\n");
     46		regulator_disable(lsm9ds0->vdd);
     47		return ret;
     48	}
     49
     50	return 0;
     51}
     52
     53static void st_lsm9ds0_power_disable(void *data)
     54{
     55	struct st_lsm9ds0 *lsm9ds0 = data;
     56
     57	regulator_disable(lsm9ds0->vdd_io);
     58	regulator_disable(lsm9ds0->vdd);
     59}
     60
     61static int devm_st_lsm9ds0_power_enable(struct st_lsm9ds0 *lsm9ds0)
     62{
     63	struct device *dev = lsm9ds0->dev;
     64	int ret;
     65
     66	ret = st_lsm9ds0_power_enable(dev, lsm9ds0);
     67	if (ret)
     68		return ret;
     69
     70	return devm_add_action_or_reset(dev, st_lsm9ds0_power_disable, lsm9ds0);
     71}
     72
     73static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap)
     74{
     75	const struct st_sensor_settings *settings;
     76	struct device *dev = lsm9ds0->dev;
     77	struct st_sensor_data *data;
     78
     79	settings = st_accel_get_settings(lsm9ds0->name);
     80	if (!settings) {
     81		dev_err(dev, "device name %s not recognized.\n", lsm9ds0->name);
     82		return -ENODEV;
     83	}
     84
     85	lsm9ds0->accel = devm_iio_device_alloc(dev, sizeof(*data));
     86	if (!lsm9ds0->accel)
     87		return -ENOMEM;
     88
     89	lsm9ds0->accel->name = lsm9ds0->name;
     90
     91	data = iio_priv(lsm9ds0->accel);
     92	data->sensor_settings = (struct st_sensor_settings *)settings;
     93	data->irq = lsm9ds0->irq;
     94	data->regmap = regmap;
     95	data->vdd = lsm9ds0->vdd;
     96	data->vdd_io = lsm9ds0->vdd_io;
     97
     98	return st_accel_common_probe(lsm9ds0->accel);
     99}
    100
    101static int st_lsm9ds0_probe_magn(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap)
    102{
    103	const struct st_sensor_settings *settings;
    104	struct device *dev = lsm9ds0->dev;
    105	struct st_sensor_data *data;
    106
    107	settings = st_magn_get_settings(lsm9ds0->name);
    108	if (!settings) {
    109		dev_err(dev, "device name %s not recognized.\n", lsm9ds0->name);
    110		return -ENODEV;
    111	}
    112
    113	lsm9ds0->magn = devm_iio_device_alloc(dev, sizeof(*data));
    114	if (!lsm9ds0->magn)
    115		return -ENOMEM;
    116
    117	lsm9ds0->magn->name = lsm9ds0->name;
    118
    119	data = iio_priv(lsm9ds0->magn);
    120	data->sensor_settings = (struct st_sensor_settings *)settings;
    121	data->irq = lsm9ds0->irq;
    122	data->regmap = regmap;
    123	data->vdd = lsm9ds0->vdd;
    124	data->vdd_io = lsm9ds0->vdd_io;
    125
    126	return st_magn_common_probe(lsm9ds0->magn);
    127}
    128
    129int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap)
    130{
    131	int ret;
    132
    133	ret = devm_st_lsm9ds0_power_enable(lsm9ds0);
    134	if (ret)
    135		return ret;
    136
    137	/* Setup accelerometer device */
    138	ret = st_lsm9ds0_probe_accel(lsm9ds0, regmap);
    139	if (ret)
    140		return ret;
    141
    142	/* Setup magnetometer device */
    143	return st_lsm9ds0_probe_magn(lsm9ds0, regmap);
    144}
    145EXPORT_SYMBOL_NS_GPL(st_lsm9ds0_probe, IIO_ST_SENSORS);
    146
    147MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
    148MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU core driver");
    149MODULE_LICENSE("GPL v2");
    150MODULE_IMPORT_NS(IIO_ST_SENSORS);