220 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * STMicroelectronics accelerometers driver4 *5 * Copyright 2012-2013 STMicroelectronics Inc.6 *7 * Denis Ciocca <denis.ciocca@st.com>8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/mod_devicetable.h>13#include <linux/i2c.h>14#include <linux/iio/iio.h>15 16#include <linux/iio/common/st_sensors_i2c.h>17#include "st_accel.h"18 19static const struct of_device_id st_accel_of_match[] = {20 {21 /* An older compatible */22 .compatible = "st,lis3lv02d",23 .data = LIS3LV02DL_ACCEL_DEV_NAME,24 },25 {26 .compatible = "st,lis3lv02dl-accel",27 .data = LIS3LV02DL_ACCEL_DEV_NAME,28 },29 {30 .compatible = "st,lsm303dlh-accel",31 .data = LSM303DLH_ACCEL_DEV_NAME,32 },33 {34 .compatible = "st,lsm303dlhc-accel",35 .data = LSM303DLHC_ACCEL_DEV_NAME,36 },37 {38 .compatible = "st,lis3dh-accel",39 .data = LIS3DH_ACCEL_DEV_NAME,40 },41 {42 .compatible = "st,lsm330d-accel",43 .data = LSM330D_ACCEL_DEV_NAME,44 },45 {46 .compatible = "st,lsm330dl-accel",47 .data = LSM330DL_ACCEL_DEV_NAME,48 },49 {50 .compatible = "st,lsm330dlc-accel",51 .data = LSM330DLC_ACCEL_DEV_NAME,52 },53 {54 .compatible = "st,lis331dl-accel",55 .data = LIS331DL_ACCEL_DEV_NAME,56 },57 {58 .compatible = "st,lis331dlh-accel",59 .data = LIS331DLH_ACCEL_DEV_NAME,60 },61 {62 .compatible = "st,lsm303dl-accel",63 .data = LSM303DL_ACCEL_DEV_NAME,64 },65 {66 .compatible = "st,lsm303dlm-accel",67 .data = LSM303DLM_ACCEL_DEV_NAME,68 },69 {70 .compatible = "st,lsm330-accel",71 .data = LSM330_ACCEL_DEV_NAME,72 },73 {74 .compatible = "st,lsm303agr-accel",75 .data = LSM303AGR_ACCEL_DEV_NAME,76 },77 {78 .compatible = "st,lis2dh12-accel",79 .data = LIS2DH12_ACCEL_DEV_NAME,80 },81 {82 .compatible = "st,h3lis331dl-accel",83 .data = H3LIS331DL_ACCEL_DEV_NAME,84 },85 {86 .compatible = "st,lis3l02dq",87 .data = LIS3L02DQ_ACCEL_DEV_NAME,88 },89 {90 .compatible = "st,lng2dm-accel",91 .data = LNG2DM_ACCEL_DEV_NAME,92 },93 {94 .compatible = "st,lis2dw12",95 .data = LIS2DW12_ACCEL_DEV_NAME,96 },97 {98 .compatible = "st,lis3de",99 .data = LIS3DE_ACCEL_DEV_NAME,100 },101 {102 .compatible = "st,lis2de12",103 .data = LIS2DE12_ACCEL_DEV_NAME,104 },105 {106 .compatible = "st,lis2ds12",107 .data = LIS2DS12_ACCEL_DEV_NAME,108 },109 {110 .compatible = "st,lis2hh12",111 .data = LIS2HH12_ACCEL_DEV_NAME,112 },113 {114 .compatible = "st,lis302dl",115 .data = LIS302DL_ACCEL_DEV_NAME,116 },117 {118 .compatible = "st,lsm303c-accel",119 .data = LSM303C_ACCEL_DEV_NAME,120 },121 {122 .compatible = "silan,sc7a20",123 .data = SC7A20_ACCEL_DEV_NAME,124 },125 {126 .compatible = "st,iis328dq",127 .data = IIS328DQ_ACCEL_DEV_NAME,128 },129 {},130};131MODULE_DEVICE_TABLE(of, st_accel_of_match);132 133static const struct acpi_device_id st_accel_acpi_match[] = {134 {"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME},135 {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME},136 { },137};138MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match);139 140static const struct i2c_device_id st_accel_id_table[] = {141 { LSM303DLH_ACCEL_DEV_NAME },142 { LSM303DLHC_ACCEL_DEV_NAME },143 { LIS3DH_ACCEL_DEV_NAME },144 { LSM330D_ACCEL_DEV_NAME },145 { LSM330DL_ACCEL_DEV_NAME },146 { LSM330DLC_ACCEL_DEV_NAME },147 { LIS331DLH_ACCEL_DEV_NAME },148 { LSM303DL_ACCEL_DEV_NAME },149 { LSM303DLM_ACCEL_DEV_NAME },150 { LSM330_ACCEL_DEV_NAME },151 { LSM303AGR_ACCEL_DEV_NAME },152 { LIS2DH12_ACCEL_DEV_NAME },153 { LIS3L02DQ_ACCEL_DEV_NAME },154 { LNG2DM_ACCEL_DEV_NAME },155 { H3LIS331DL_ACCEL_DEV_NAME },156 { LIS331DL_ACCEL_DEV_NAME },157 { LIS3LV02DL_ACCEL_DEV_NAME },158 { LIS2DW12_ACCEL_DEV_NAME },159 { LIS3DE_ACCEL_DEV_NAME },160 { LIS2DE12_ACCEL_DEV_NAME },161 { LIS2DS12_ACCEL_DEV_NAME },162 { LIS2HH12_ACCEL_DEV_NAME },163 { LIS302DL_ACCEL_DEV_NAME },164 { LSM303C_ACCEL_DEV_NAME },165 { SC7A20_ACCEL_DEV_NAME },166 { IIS328DQ_ACCEL_DEV_NAME },167 {},168};169MODULE_DEVICE_TABLE(i2c, st_accel_id_table);170 171static int st_accel_i2c_probe(struct i2c_client *client)172{173 const struct st_sensor_settings *settings;174 struct st_sensor_data *adata;175 struct iio_dev *indio_dev;176 int ret;177 178 st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name));179 180 settings = st_accel_get_settings(client->name);181 if (!settings) {182 dev_err(&client->dev, "device name %s not recognized.\n",183 client->name);184 return -ENODEV;185 }186 187 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));188 if (!indio_dev)189 return -ENOMEM;190 191 adata = iio_priv(indio_dev);192 adata->sensor_settings = (struct st_sensor_settings *)settings;193 194 ret = st_sensors_i2c_configure(indio_dev, client);195 if (ret < 0)196 return ret;197 198 ret = st_sensors_power_enable(indio_dev);199 if (ret)200 return ret;201 202 return st_accel_common_probe(indio_dev);203}204 205static struct i2c_driver st_accel_driver = {206 .driver = {207 .name = "st-accel-i2c",208 .of_match_table = st_accel_of_match,209 .acpi_match_table = st_accel_acpi_match,210 },211 .probe = st_accel_i2c_probe,212 .id_table = st_accel_id_table,213};214module_i2c_driver(st_accel_driver);215 216MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");217MODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver");218MODULE_LICENSE("GPL v2");219MODULE_IMPORT_NS(IIO_ST_SENSORS);220