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/array_size.h> 11 #include <linux/dev_printk.h> 12 #include <linux/err.h> 13 #include <linux/module.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 21 static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) 22 { 23 const struct st_sensor_settings *settings; 24 struct device *dev = lsm9ds0->dev; 25 struct st_sensor_data *data; 26 27 settings = st_accel_get_settings(lsm9ds0->name); 28 if (!settings) 29 return dev_err_probe(dev, -ENODEV, "device name %s not recognized.\n", 30 lsm9ds0->name); 31 32 lsm9ds0->accel = devm_iio_device_alloc(dev, sizeof(*data)); 33 if (!lsm9ds0->accel) 34 return -ENOMEM; 35 36 lsm9ds0->accel->name = lsm9ds0->name; 37 38 data = iio_priv(lsm9ds0->accel); 39 data->sensor_settings = (struct st_sensor_settings *)settings; 40 data->irq = lsm9ds0->irq; 41 data->regmap = regmap; 42 43 return st_accel_common_probe(lsm9ds0->accel); 44 } 45 46 static int st_lsm9ds0_probe_magn(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) 47 { 48 const struct st_sensor_settings *settings; 49 struct device *dev = lsm9ds0->dev; 50 struct st_sensor_data *data; 51 52 settings = st_magn_get_settings(lsm9ds0->name); 53 if (!settings) 54 return dev_err_probe(dev, -ENODEV, "device name %s not recognized.\n", 55 lsm9ds0->name); 56 57 lsm9ds0->magn = devm_iio_device_alloc(dev, sizeof(*data)); 58 if (!lsm9ds0->magn) 59 return -ENOMEM; 60 61 lsm9ds0->magn->name = lsm9ds0->name; 62 63 data = iio_priv(lsm9ds0->magn); 64 data->sensor_settings = (struct st_sensor_settings *)settings; 65 data->irq = lsm9ds0->irq; 66 data->regmap = regmap; 67 68 return st_magn_common_probe(lsm9ds0->magn); 69 } 70 71 int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) 72 { 73 struct device *dev = lsm9ds0->dev; 74 static const char * const regulator_names[] = { "vdd", "vddio" }; 75 int ret; 76 77 /* Regulators not mandatory, but if requested we should enable them. */ 78 ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), 79 regulator_names); 80 if (ret) 81 return dev_err_probe(dev, ret, "unable to enable Vdd supply\n"); 82 83 /* Setup accelerometer device */ 84 ret = st_lsm9ds0_probe_accel(lsm9ds0, regmap); 85 if (ret) 86 return ret; 87 88 /* Setup magnetometer device */ 89 return st_lsm9ds0_probe_magn(lsm9ds0, regmap); 90 } 91 EXPORT_SYMBOL_NS_GPL(st_lsm9ds0_probe, IIO_ST_SENSORS); 92 93 MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); 94 MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU core driver"); 95 MODULE_LICENSE("GPL v2"); 96 MODULE_IMPORT_NS(IIO_ST_SENSORS); 97