18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * STMicroelectronics accelerometers driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2012-2013 STMicroelectronics Inc. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Denis Ciocca <denis.ciocca@st.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/kernel.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/slab.h> 138c2ecf20Sopenharmony_ci#include <linux/acpi.h> 148c2ecf20Sopenharmony_ci#include <linux/i2c.h> 158c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 168c2ecf20Sopenharmony_ci#include <linux/property.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/iio/common/st_sensors_i2c.h> 198c2ecf20Sopenharmony_ci#include "st_accel.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic const struct of_device_id st_accel_of_match[] = { 228c2ecf20Sopenharmony_ci { 238c2ecf20Sopenharmony_ci /* An older compatible */ 248c2ecf20Sopenharmony_ci .compatible = "st,lis3lv02d", 258c2ecf20Sopenharmony_ci .data = LIS3LV02DL_ACCEL_DEV_NAME, 268c2ecf20Sopenharmony_ci }, 278c2ecf20Sopenharmony_ci { 288c2ecf20Sopenharmony_ci .compatible = "st,lis3lv02dl-accel", 298c2ecf20Sopenharmony_ci .data = LIS3LV02DL_ACCEL_DEV_NAME, 308c2ecf20Sopenharmony_ci }, 318c2ecf20Sopenharmony_ci { 328c2ecf20Sopenharmony_ci .compatible = "st,lsm303dlh-accel", 338c2ecf20Sopenharmony_ci .data = LSM303DLH_ACCEL_DEV_NAME, 348c2ecf20Sopenharmony_ci }, 358c2ecf20Sopenharmony_ci { 368c2ecf20Sopenharmony_ci .compatible = "st,lsm303dlhc-accel", 378c2ecf20Sopenharmony_ci .data = LSM303DLHC_ACCEL_DEV_NAME, 388c2ecf20Sopenharmony_ci }, 398c2ecf20Sopenharmony_ci { 408c2ecf20Sopenharmony_ci .compatible = "st,lis3dh-accel", 418c2ecf20Sopenharmony_ci .data = LIS3DH_ACCEL_DEV_NAME, 428c2ecf20Sopenharmony_ci }, 438c2ecf20Sopenharmony_ci { 448c2ecf20Sopenharmony_ci .compatible = "st,lsm330d-accel", 458c2ecf20Sopenharmony_ci .data = LSM330D_ACCEL_DEV_NAME, 468c2ecf20Sopenharmony_ci }, 478c2ecf20Sopenharmony_ci { 488c2ecf20Sopenharmony_ci .compatible = "st,lsm330dl-accel", 498c2ecf20Sopenharmony_ci .data = LSM330DL_ACCEL_DEV_NAME, 508c2ecf20Sopenharmony_ci }, 518c2ecf20Sopenharmony_ci { 528c2ecf20Sopenharmony_ci .compatible = "st,lsm330dlc-accel", 538c2ecf20Sopenharmony_ci .data = LSM330DLC_ACCEL_DEV_NAME, 548c2ecf20Sopenharmony_ci }, 558c2ecf20Sopenharmony_ci { 568c2ecf20Sopenharmony_ci .compatible = "st,lis331dl-accel", 578c2ecf20Sopenharmony_ci .data = LIS331DL_ACCEL_DEV_NAME, 588c2ecf20Sopenharmony_ci }, 598c2ecf20Sopenharmony_ci { 608c2ecf20Sopenharmony_ci .compatible = "st,lis331dlh-accel", 618c2ecf20Sopenharmony_ci .data = LIS331DLH_ACCEL_DEV_NAME, 628c2ecf20Sopenharmony_ci }, 638c2ecf20Sopenharmony_ci { 648c2ecf20Sopenharmony_ci .compatible = "st,lsm303dl-accel", 658c2ecf20Sopenharmony_ci .data = LSM303DL_ACCEL_DEV_NAME, 668c2ecf20Sopenharmony_ci }, 678c2ecf20Sopenharmony_ci { 688c2ecf20Sopenharmony_ci .compatible = "st,lsm303dlm-accel", 698c2ecf20Sopenharmony_ci .data = LSM303DLM_ACCEL_DEV_NAME, 708c2ecf20Sopenharmony_ci }, 718c2ecf20Sopenharmony_ci { 728c2ecf20Sopenharmony_ci .compatible = "st,lsm330-accel", 738c2ecf20Sopenharmony_ci .data = LSM330_ACCEL_DEV_NAME, 748c2ecf20Sopenharmony_ci }, 758c2ecf20Sopenharmony_ci { 768c2ecf20Sopenharmony_ci .compatible = "st,lsm303agr-accel", 778c2ecf20Sopenharmony_ci .data = LSM303AGR_ACCEL_DEV_NAME, 788c2ecf20Sopenharmony_ci }, 798c2ecf20Sopenharmony_ci { 808c2ecf20Sopenharmony_ci .compatible = "st,lis2dh12-accel", 818c2ecf20Sopenharmony_ci .data = LIS2DH12_ACCEL_DEV_NAME, 828c2ecf20Sopenharmony_ci }, 838c2ecf20Sopenharmony_ci { 848c2ecf20Sopenharmony_ci .compatible = "st,h3lis331dl-accel", 858c2ecf20Sopenharmony_ci .data = H3LIS331DL_ACCEL_DEV_NAME, 868c2ecf20Sopenharmony_ci }, 878c2ecf20Sopenharmony_ci { 888c2ecf20Sopenharmony_ci .compatible = "st,lis3l02dq", 898c2ecf20Sopenharmony_ci .data = LIS3L02DQ_ACCEL_DEV_NAME, 908c2ecf20Sopenharmony_ci }, 918c2ecf20Sopenharmony_ci { 928c2ecf20Sopenharmony_ci .compatible = "st,lng2dm-accel", 938c2ecf20Sopenharmony_ci .data = LNG2DM_ACCEL_DEV_NAME, 948c2ecf20Sopenharmony_ci }, 958c2ecf20Sopenharmony_ci { 968c2ecf20Sopenharmony_ci .compatible = "st,lis2dw12", 978c2ecf20Sopenharmony_ci .data = LIS2DW12_ACCEL_DEV_NAME, 988c2ecf20Sopenharmony_ci }, 998c2ecf20Sopenharmony_ci { 1008c2ecf20Sopenharmony_ci .compatible = "st,lis3de", 1018c2ecf20Sopenharmony_ci .data = LIS3DE_ACCEL_DEV_NAME, 1028c2ecf20Sopenharmony_ci }, 1038c2ecf20Sopenharmony_ci { 1048c2ecf20Sopenharmony_ci .compatible = "st,lis2de12", 1058c2ecf20Sopenharmony_ci .data = LIS2DE12_ACCEL_DEV_NAME, 1068c2ecf20Sopenharmony_ci }, 1078c2ecf20Sopenharmony_ci { 1088c2ecf20Sopenharmony_ci .compatible = "st,lis2hh12", 1098c2ecf20Sopenharmony_ci .data = LIS2HH12_ACCEL_DEV_NAME, 1108c2ecf20Sopenharmony_ci }, 1118c2ecf20Sopenharmony_ci {}, 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, st_accel_of_match); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci#ifdef CONFIG_ACPI 1168c2ecf20Sopenharmony_cistatic const struct acpi_device_id st_accel_acpi_match[] = { 1178c2ecf20Sopenharmony_ci {"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME}, 1188c2ecf20Sopenharmony_ci {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, 1198c2ecf20Sopenharmony_ci { }, 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, st_accel_acpi_match); 1228c2ecf20Sopenharmony_ci#endif 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic const struct i2c_device_id st_accel_id_table[] = { 1258c2ecf20Sopenharmony_ci { LSM303DLH_ACCEL_DEV_NAME }, 1268c2ecf20Sopenharmony_ci { LSM303DLHC_ACCEL_DEV_NAME }, 1278c2ecf20Sopenharmony_ci { LIS3DH_ACCEL_DEV_NAME }, 1288c2ecf20Sopenharmony_ci { LSM330D_ACCEL_DEV_NAME }, 1298c2ecf20Sopenharmony_ci { LSM330DL_ACCEL_DEV_NAME }, 1308c2ecf20Sopenharmony_ci { LSM330DLC_ACCEL_DEV_NAME }, 1318c2ecf20Sopenharmony_ci { LIS331DLH_ACCEL_DEV_NAME }, 1328c2ecf20Sopenharmony_ci { LSM303DL_ACCEL_DEV_NAME }, 1338c2ecf20Sopenharmony_ci { LSM303DLM_ACCEL_DEV_NAME }, 1348c2ecf20Sopenharmony_ci { LSM330_ACCEL_DEV_NAME }, 1358c2ecf20Sopenharmony_ci { LSM303AGR_ACCEL_DEV_NAME }, 1368c2ecf20Sopenharmony_ci { LIS2DH12_ACCEL_DEV_NAME }, 1378c2ecf20Sopenharmony_ci { LIS3L02DQ_ACCEL_DEV_NAME }, 1388c2ecf20Sopenharmony_ci { LNG2DM_ACCEL_DEV_NAME }, 1398c2ecf20Sopenharmony_ci { H3LIS331DL_ACCEL_DEV_NAME }, 1408c2ecf20Sopenharmony_ci { LIS331DL_ACCEL_DEV_NAME }, 1418c2ecf20Sopenharmony_ci { LIS3LV02DL_ACCEL_DEV_NAME }, 1428c2ecf20Sopenharmony_ci { LIS2DW12_ACCEL_DEV_NAME }, 1438c2ecf20Sopenharmony_ci { LIS3DE_ACCEL_DEV_NAME }, 1448c2ecf20Sopenharmony_ci { LIS2DE12_ACCEL_DEV_NAME }, 1458c2ecf20Sopenharmony_ci { LIS2HH12_ACCEL_DEV_NAME }, 1468c2ecf20Sopenharmony_ci {}, 1478c2ecf20Sopenharmony_ci}; 1488c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, st_accel_id_table); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic int st_accel_i2c_probe(struct i2c_client *client) 1518c2ecf20Sopenharmony_ci{ 1528c2ecf20Sopenharmony_ci const struct st_sensor_settings *settings; 1538c2ecf20Sopenharmony_ci struct st_sensor_data *adata; 1548c2ecf20Sopenharmony_ci struct iio_dev *indio_dev; 1558c2ecf20Sopenharmony_ci int ret; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name)); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci settings = st_accel_get_settings(client->name); 1608c2ecf20Sopenharmony_ci if (!settings) { 1618c2ecf20Sopenharmony_ci dev_err(&client->dev, "device name %s not recognized.\n", 1628c2ecf20Sopenharmony_ci client->name); 1638c2ecf20Sopenharmony_ci return -ENODEV; 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata)); 1678c2ecf20Sopenharmony_ci if (!indio_dev) 1688c2ecf20Sopenharmony_ci return -ENOMEM; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci adata = iio_priv(indio_dev); 1718c2ecf20Sopenharmony_ci adata->sensor_settings = (struct st_sensor_settings *)settings; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci ret = st_sensors_i2c_configure(indio_dev, client); 1748c2ecf20Sopenharmony_ci if (ret < 0) 1758c2ecf20Sopenharmony_ci return ret; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci ret = st_sensors_power_enable(indio_dev); 1788c2ecf20Sopenharmony_ci if (ret) 1798c2ecf20Sopenharmony_ci return ret; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci ret = st_accel_common_probe(indio_dev); 1828c2ecf20Sopenharmony_ci if (ret < 0) 1838c2ecf20Sopenharmony_ci goto st_accel_power_off; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci return 0; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cist_accel_power_off: 1888c2ecf20Sopenharmony_ci st_sensors_power_disable(indio_dev); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci return ret; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic int st_accel_i2c_remove(struct i2c_client *client) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct iio_dev *indio_dev = i2c_get_clientdata(client); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci st_accel_common_remove(indio_dev); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci st_sensors_power_disable(indio_dev); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci return 0; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic struct i2c_driver st_accel_driver = { 2058c2ecf20Sopenharmony_ci .driver = { 2068c2ecf20Sopenharmony_ci .name = "st-accel-i2c", 2078c2ecf20Sopenharmony_ci .of_match_table = st_accel_of_match, 2088c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(st_accel_acpi_match), 2098c2ecf20Sopenharmony_ci }, 2108c2ecf20Sopenharmony_ci .probe_new = st_accel_i2c_probe, 2118c2ecf20Sopenharmony_ci .remove = st_accel_i2c_remove, 2128c2ecf20Sopenharmony_ci .id_table = st_accel_id_table, 2138c2ecf20Sopenharmony_ci}; 2148c2ecf20Sopenharmony_cimodule_i2c_driver(st_accel_driver); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ciMODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 2178c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver"); 2188c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 219