150276Speter// SPDX-License-Identifier: GPL-2.0-only 2166124Srafan/* 350276Speter * STMicroelectronics accelerometers driver 450276Speter * 550276Speter * Copyright 2012-2013 STMicroelectronics Inc. 650276Speter * 750276Speter * Denis Ciocca <denis.ciocca@st.com> 850276Speter */ 950276Speter 1050276Speter#include <linux/kernel.h> 1150276Speter#include <linux/module.h> 1250276Speter#include <linux/mod_devicetable.h> 1350276Speter#include <linux/spi/spi.h> 1450276Speter#include <linux/iio/iio.h> 1550276Speter 1650276Speter#include <linux/iio/common/st_sensors.h> 1750276Speter#include <linux/iio/common/st_sensors_spi.h> 1850276Speter#include "st_accel.h" 1950276Speter 2050276Speter/* 2150276Speter * For new single-chip sensors use <device_name> as compatible string. 2250276Speter * For old single-chip devices keep <device_name>-accel to maintain 2350276Speter * compatibility 2450276Speter */ 2550276Speterstatic const struct of_device_id st_accel_of_match[] = { 2650276Speter { 2750276Speter /* An older compatible */ 2850276Speter .compatible = "st,lis302dl-spi", 2950276Speter .data = LIS3LV02DL_ACCEL_DEV_NAME, 30166124Srafan }, 3150276Speter { 3250276Speter .compatible = "st,lis3lv02dl-accel", 3350276Speter .data = LIS3LV02DL_ACCEL_DEV_NAME, 3450276Speter }, 3550276Speter { 3650276Speter .compatible = "st,lis3dh-accel", 3750276Speter .data = LIS3DH_ACCEL_DEV_NAME, 3850276Speter }, 3950276Speter { 40166124Srafan .compatible = "st,lsm330d-accel", 4150276Speter .data = LSM330D_ACCEL_DEV_NAME, 4250276Speter }, 4350276Speter { 4450276Speter .compatible = "st,lsm330dl-accel", 4550276Speter .data = LSM330DL_ACCEL_DEV_NAME, 4650276Speter }, 4750276Speter { 4850276Speter .compatible = "st,lsm330dlc-accel", 4950276Speter .data = LSM330DLC_ACCEL_DEV_NAME, 5050276Speter }, 5150276Speter { 5250276Speter .compatible = "st,lis331dlh-accel", 5376726Speter .data = LIS331DLH_ACCEL_DEV_NAME, 54166124Srafan }, 5550276Speter { 56166124Srafan .compatible = "st,lsm330-accel", 57166124Srafan .data = LSM330_ACCEL_DEV_NAME, 58166124Srafan }, 59166124Srafan { 6050276Speter .compatible = "st,lsm303agr-accel", 6150276Speter .data = LSM303AGR_ACCEL_DEV_NAME, 6250276Speter }, 6350276Speter { 6450276Speter .compatible = "st,lis2dh12-accel", 6550276Speter .data = LIS2DH12_ACCEL_DEV_NAME, 6650276Speter }, 6750276Speter { 68166124Srafan .compatible = "st,lis3l02dq", 6950276Speter .data = LIS3L02DQ_ACCEL_DEV_NAME, 70166124Srafan }, 7150276Speter { 72166124Srafan .compatible = "st,lng2dm-accel", 7350276Speter .data = LNG2DM_ACCEL_DEV_NAME, 7450276Speter }, 7550276Speter { 7650276Speter .compatible = "st,h3lis331dl-accel", 7750276Speter .data = H3LIS331DL_ACCEL_DEV_NAME, 78166124Srafan }, 7950276Speter { 80166124Srafan .compatible = "st,lis331dl-accel", 8150276Speter .data = LIS331DL_ACCEL_DEV_NAME, 8250276Speter }, 8350276Speter { 8450276Speter .compatible = "st,lis2dw12", 8550276Speter .data = LIS2DW12_ACCEL_DEV_NAME, 8650276Speter }, 8750276Speter { 8850276Speter .compatible = "st,lis3dhh", 8950276Speter .data = LIS3DHH_ACCEL_DEV_NAME, 9050276Speter }, 9150276Speter { 9250276Speter .compatible = "st,lis3de", 9350276Speter .data = LIS3DE_ACCEL_DEV_NAME, 9476726Speter }, 95166124Srafan { 9650276Speter .compatible = "st,lis302dl", 97166124Srafan .data = LIS302DL_ACCEL_DEV_NAME, 9850276Speter }, 9950276Speter { 100166124Srafan .compatible = "st,lsm303c-accel", 101166124Srafan .data = LSM303C_ACCEL_DEV_NAME, 10250276Speter }, 103166124Srafan { 104166124Srafan .compatible = "st,iis328dq", 10550276Speter .data = IIS328DQ_ACCEL_DEV_NAME, 106166124Srafan }, 10750276Speter {} 10850276Speter}; 10950276SpeterMODULE_DEVICE_TABLE(of, st_accel_of_match); 11050276Speter 11150276Speterstatic int st_accel_spi_probe(struct spi_device *spi) 11250276Speter{ 11350276Speter const struct st_sensor_settings *settings; 11450276Speter struct st_sensor_data *adata; 115 struct iio_dev *indio_dev; 116 int err; 117 118 st_sensors_dev_name_probe(&spi->dev, spi->modalias, sizeof(spi->modalias)); 119 120 settings = st_accel_get_settings(spi->modalias); 121 if (!settings) { 122 dev_err(&spi->dev, "device name %s not recognized.\n", 123 spi->modalias); 124 return -ENODEV; 125 } 126 127 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adata)); 128 if (!indio_dev) 129 return -ENOMEM; 130 131 adata = iio_priv(indio_dev); 132 adata->sensor_settings = (struct st_sensor_settings *)settings; 133 134 err = st_sensors_spi_configure(indio_dev, spi); 135 if (err < 0) 136 return err; 137 138 err = st_sensors_power_enable(indio_dev); 139 if (err) 140 return err; 141 142 return st_accel_common_probe(indio_dev); 143} 144 145static const struct spi_device_id st_accel_id_table[] = { 146 { LIS3DH_ACCEL_DEV_NAME }, 147 { LSM330D_ACCEL_DEV_NAME }, 148 { LSM330DL_ACCEL_DEV_NAME }, 149 { LSM330DLC_ACCEL_DEV_NAME }, 150 { LIS331DLH_ACCEL_DEV_NAME }, 151 { LSM330_ACCEL_DEV_NAME }, 152 { LSM303AGR_ACCEL_DEV_NAME }, 153 { LIS2DH12_ACCEL_DEV_NAME }, 154 { LIS3L02DQ_ACCEL_DEV_NAME }, 155 { LNG2DM_ACCEL_DEV_NAME }, 156 { H3LIS331DL_ACCEL_DEV_NAME }, 157 { LIS331DL_ACCEL_DEV_NAME }, 158 { LIS3LV02DL_ACCEL_DEV_NAME }, 159 { LIS2DW12_ACCEL_DEV_NAME }, 160 { LIS3DHH_ACCEL_DEV_NAME }, 161 { LIS3DE_ACCEL_DEV_NAME }, 162 { LIS302DL_ACCEL_DEV_NAME }, 163 { LSM303C_ACCEL_DEV_NAME }, 164 { IIS328DQ_ACCEL_DEV_NAME }, 165 {}, 166}; 167MODULE_DEVICE_TABLE(spi, st_accel_id_table); 168 169static struct spi_driver st_accel_driver = { 170 .driver = { 171 .name = "st-accel-spi", 172 .of_match_table = st_accel_of_match, 173 }, 174 .probe = st_accel_spi_probe, 175 .id_table = st_accel_id_table, 176}; 177module_spi_driver(st_accel_driver); 178 179MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 180MODULE_DESCRIPTION("STMicroelectronics accelerometers spi driver"); 181MODULE_LICENSE("GPL v2"); 182MODULE_IMPORT_NS(IIO_ST_SENSORS); 183