0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/mod_devicetable.h>
0013 #include <linux/acpi.h>
0014 #include <linux/i2c.h>
0015 #include <linux/iio/iio.h>
0016
0017 #include <linux/iio/common/st_sensors_i2c.h>
0018 #include "st_accel.h"
0019
0020 static const struct of_device_id st_accel_of_match[] = {
0021 {
0022
0023 .compatible = "st,lis3lv02d",
0024 .data = LIS3LV02DL_ACCEL_DEV_NAME,
0025 },
0026 {
0027 .compatible = "st,lis3lv02dl-accel",
0028 .data = LIS3LV02DL_ACCEL_DEV_NAME,
0029 },
0030 {
0031 .compatible = "st,lsm303dlh-accel",
0032 .data = LSM303DLH_ACCEL_DEV_NAME,
0033 },
0034 {
0035 .compatible = "st,lsm303dlhc-accel",
0036 .data = LSM303DLHC_ACCEL_DEV_NAME,
0037 },
0038 {
0039 .compatible = "st,lis3dh-accel",
0040 .data = LIS3DH_ACCEL_DEV_NAME,
0041 },
0042 {
0043 .compatible = "st,lsm330d-accel",
0044 .data = LSM330D_ACCEL_DEV_NAME,
0045 },
0046 {
0047 .compatible = "st,lsm330dl-accel",
0048 .data = LSM330DL_ACCEL_DEV_NAME,
0049 },
0050 {
0051 .compatible = "st,lsm330dlc-accel",
0052 .data = LSM330DLC_ACCEL_DEV_NAME,
0053 },
0054 {
0055 .compatible = "st,lis331dl-accel",
0056 .data = LIS331DL_ACCEL_DEV_NAME,
0057 },
0058 {
0059 .compatible = "st,lis331dlh-accel",
0060 .data = LIS331DLH_ACCEL_DEV_NAME,
0061 },
0062 {
0063 .compatible = "st,lsm303dl-accel",
0064 .data = LSM303DL_ACCEL_DEV_NAME,
0065 },
0066 {
0067 .compatible = "st,lsm303dlm-accel",
0068 .data = LSM303DLM_ACCEL_DEV_NAME,
0069 },
0070 {
0071 .compatible = "st,lsm330-accel",
0072 .data = LSM330_ACCEL_DEV_NAME,
0073 },
0074 {
0075 .compatible = "st,lsm303agr-accel",
0076 .data = LSM303AGR_ACCEL_DEV_NAME,
0077 },
0078 {
0079 .compatible = "st,lis2dh12-accel",
0080 .data = LIS2DH12_ACCEL_DEV_NAME,
0081 },
0082 {
0083 .compatible = "st,h3lis331dl-accel",
0084 .data = H3LIS331DL_ACCEL_DEV_NAME,
0085 },
0086 {
0087 .compatible = "st,lis3l02dq",
0088 .data = LIS3L02DQ_ACCEL_DEV_NAME,
0089 },
0090 {
0091 .compatible = "st,lng2dm-accel",
0092 .data = LNG2DM_ACCEL_DEV_NAME,
0093 },
0094 {
0095 .compatible = "st,lis2dw12",
0096 .data = LIS2DW12_ACCEL_DEV_NAME,
0097 },
0098 {
0099 .compatible = "st,lis3de",
0100 .data = LIS3DE_ACCEL_DEV_NAME,
0101 },
0102 {
0103 .compatible = "st,lis2de12",
0104 .data = LIS2DE12_ACCEL_DEV_NAME,
0105 },
0106 {
0107 .compatible = "st,lis2hh12",
0108 .data = LIS2HH12_ACCEL_DEV_NAME,
0109 },
0110 {
0111 .compatible = "st,lis302dl",
0112 .data = LIS302DL_ACCEL_DEV_NAME,
0113 },
0114 {
0115 .compatible = "silan,sc7a20",
0116 .data = SC7A20_ACCEL_DEV_NAME,
0117 },
0118 {},
0119 };
0120 MODULE_DEVICE_TABLE(of, st_accel_of_match);
0121
0122 #ifdef CONFIG_ACPI
0123 static const struct acpi_device_id st_accel_acpi_match[] = {
0124 {"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME},
0125 {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME},
0126 { },
0127 };
0128 MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match);
0129 #endif
0130
0131 static const struct i2c_device_id st_accel_id_table[] = {
0132 { LSM303DLH_ACCEL_DEV_NAME },
0133 { LSM303DLHC_ACCEL_DEV_NAME },
0134 { LIS3DH_ACCEL_DEV_NAME },
0135 { LSM330D_ACCEL_DEV_NAME },
0136 { LSM330DL_ACCEL_DEV_NAME },
0137 { LSM330DLC_ACCEL_DEV_NAME },
0138 { LIS331DLH_ACCEL_DEV_NAME },
0139 { LSM303DL_ACCEL_DEV_NAME },
0140 { LSM303DLM_ACCEL_DEV_NAME },
0141 { LSM330_ACCEL_DEV_NAME },
0142 { LSM303AGR_ACCEL_DEV_NAME },
0143 { LIS2DH12_ACCEL_DEV_NAME },
0144 { LIS3L02DQ_ACCEL_DEV_NAME },
0145 { LNG2DM_ACCEL_DEV_NAME },
0146 { H3LIS331DL_ACCEL_DEV_NAME },
0147 { LIS331DL_ACCEL_DEV_NAME },
0148 { LIS3LV02DL_ACCEL_DEV_NAME },
0149 { LIS2DW12_ACCEL_DEV_NAME },
0150 { LIS3DE_ACCEL_DEV_NAME },
0151 { LIS2DE12_ACCEL_DEV_NAME },
0152 { LIS2HH12_ACCEL_DEV_NAME },
0153 { LIS302DL_ACCEL_DEV_NAME },
0154 { SC7A20_ACCEL_DEV_NAME },
0155 {},
0156 };
0157 MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
0158
0159 static int st_accel_i2c_probe(struct i2c_client *client)
0160 {
0161 const struct st_sensor_settings *settings;
0162 struct st_sensor_data *adata;
0163 struct iio_dev *indio_dev;
0164 int ret;
0165
0166 st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name));
0167
0168 settings = st_accel_get_settings(client->name);
0169 if (!settings) {
0170 dev_err(&client->dev, "device name %s not recognized.\n",
0171 client->name);
0172 return -ENODEV;
0173 }
0174
0175 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));
0176 if (!indio_dev)
0177 return -ENOMEM;
0178
0179 adata = iio_priv(indio_dev);
0180 adata->sensor_settings = (struct st_sensor_settings *)settings;
0181
0182 ret = st_sensors_i2c_configure(indio_dev, client);
0183 if (ret < 0)
0184 return ret;
0185
0186 ret = st_sensors_power_enable(indio_dev);
0187 if (ret)
0188 return ret;
0189
0190 return st_accel_common_probe(indio_dev);
0191 }
0192
0193 static struct i2c_driver st_accel_driver = {
0194 .driver = {
0195 .name = "st-accel-i2c",
0196 .of_match_table = st_accel_of_match,
0197 .acpi_match_table = ACPI_PTR(st_accel_acpi_match),
0198 },
0199 .probe_new = st_accel_i2c_probe,
0200 .id_table = st_accel_id_table,
0201 };
0202 module_i2c_driver(st_accel_driver);
0203
0204 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
0205 MODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver");
0206 MODULE_LICENSE("GPL v2");
0207 MODULE_IMPORT_NS(IIO_ST_SENSORS);