Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / iio / accel / st_accel_spi.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * STMicroelectronics accelerometers driver
4  *
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/slab.h>
13 #include <linux/spi/spi.h>
14 #include <linux/iio/iio.h>
15
16 #include <linux/iio/common/st_sensors.h>
17 #include <linux/iio/common/st_sensors_spi.h>
18 #include "st_accel.h"
19
20 #ifdef CONFIG_OF
21 /*
22  * For new single-chip sensors use <device_name> as compatible string.
23  * For old single-chip devices keep <device_name>-accel to maintain
24  * compatibility
25  */
26 static const struct of_device_id st_accel_of_match[] = {
27         {
28                 /* An older compatible */
29                 .compatible = "st,lis302dl-spi",
30                 .data = LIS3LV02DL_ACCEL_DEV_NAME,
31         },
32         {
33                 .compatible = "st,lis3lv02dl-accel",
34                 .data = LIS3LV02DL_ACCEL_DEV_NAME,
35         },
36         {
37                 .compatible = "st,lis3dh-accel",
38                 .data = LIS3DH_ACCEL_DEV_NAME,
39         },
40         {
41                 .compatible = "st,lsm330d-accel",
42                 .data = LSM330D_ACCEL_DEV_NAME,
43         },
44         {
45                 .compatible = "st,lsm330dl-accel",
46                 .data = LSM330DL_ACCEL_DEV_NAME,
47         },
48         {
49                 .compatible = "st,lsm330dlc-accel",
50                 .data = LSM330DLC_ACCEL_DEV_NAME,
51         },
52         {
53                 .compatible = "st,lis331dlh-accel",
54                 .data = LIS331DLH_ACCEL_DEV_NAME,
55         },
56         {
57                 .compatible = "st,lsm330-accel",
58                 .data = LSM330_ACCEL_DEV_NAME,
59         },
60         {
61                 .compatible = "st,lsm303agr-accel",
62                 .data = LSM303AGR_ACCEL_DEV_NAME,
63         },
64         {
65                 .compatible = "st,lis2dh12-accel",
66                 .data = LIS2DH12_ACCEL_DEV_NAME,
67         },
68         {
69                 .compatible = "st,lis3l02dq",
70                 .data = LIS3L02DQ_ACCEL_DEV_NAME,
71         },
72         {
73                 .compatible = "st,lng2dm-accel",
74                 .data = LNG2DM_ACCEL_DEV_NAME,
75         },
76         {
77                 .compatible = "st,h3lis331dl-accel",
78                 .data = H3LIS331DL_ACCEL_DEV_NAME,
79         },
80         {
81                 .compatible = "st,lis331dl-accel",
82                 .data = LIS331DL_ACCEL_DEV_NAME,
83         },
84         {
85                 .compatible = "st,lis2dw12",
86                 .data = LIS2DW12_ACCEL_DEV_NAME,
87         },
88         {
89                 .compatible = "st,lis3dhh",
90                 .data = LIS3DHH_ACCEL_DEV_NAME,
91         },
92         {
93                 .compatible = "st,lis3de",
94                 .data = LIS3DE_ACCEL_DEV_NAME,
95         },
96         {}
97 };
98 MODULE_DEVICE_TABLE(of, st_accel_of_match);
99 #else
100 #define st_accel_of_match       NULL
101 #endif
102
103 static int st_accel_spi_probe(struct spi_device *spi)
104 {
105         struct iio_dev *indio_dev;
106         struct st_sensor_data *adata;
107         int err;
108
109         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adata));
110         if (!indio_dev)
111                 return -ENOMEM;
112
113         adata = iio_priv(indio_dev);
114
115         st_sensors_of_name_probe(&spi->dev, st_accel_of_match,
116                                  spi->modalias, sizeof(spi->modalias));
117         st_sensors_spi_configure(indio_dev, spi, adata);
118
119         err = st_accel_common_probe(indio_dev);
120         if (err < 0)
121                 return err;
122
123         return 0;
124 }
125
126 static int st_accel_spi_remove(struct spi_device *spi)
127 {
128         st_accel_common_remove(spi_get_drvdata(spi));
129
130         return 0;
131 }
132
133 static const struct spi_device_id st_accel_id_table[] = {
134         { LIS3DH_ACCEL_DEV_NAME },
135         { LSM330D_ACCEL_DEV_NAME },
136         { LSM330DL_ACCEL_DEV_NAME },
137         { LSM330DLC_ACCEL_DEV_NAME },
138         { LIS331DLH_ACCEL_DEV_NAME },
139         { LSM330_ACCEL_DEV_NAME },
140         { LSM303AGR_ACCEL_DEV_NAME },
141         { LIS2DH12_ACCEL_DEV_NAME },
142         { LIS3L02DQ_ACCEL_DEV_NAME },
143         { LNG2DM_ACCEL_DEV_NAME },
144         { H3LIS331DL_ACCEL_DEV_NAME },
145         { LIS331DL_ACCEL_DEV_NAME },
146         { LIS3LV02DL_ACCEL_DEV_NAME },
147         { LIS2DW12_ACCEL_DEV_NAME },
148         { LIS3DHH_ACCEL_DEV_NAME },
149         { LIS3DE_ACCEL_DEV_NAME },
150         {},
151 };
152 MODULE_DEVICE_TABLE(spi, st_accel_id_table);
153
154 static struct spi_driver st_accel_driver = {
155         .driver = {
156                 .name = "st-accel-spi",
157                 .of_match_table = of_match_ptr(st_accel_of_match),
158         },
159         .probe = st_accel_spi_probe,
160         .remove = st_accel_spi_remove,
161         .id_table = st_accel_id_table,
162 };
163 module_spi_driver(st_accel_driver);
164
165 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
166 MODULE_DESCRIPTION("STMicroelectronics accelerometers spi driver");
167 MODULE_LICENSE("GPL v2");