1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * STMicroelectronics st_lsm6dsx i2c driver |
4 | * |
5 | * Copyright 2016 STMicroelectronics Inc. |
6 | * |
7 | * Lorenzo Bianconi <lorenzo.bianconi@st.com> |
8 | * Denis Ciocca <denis.ciocca@st.com> |
9 | */ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/i2c.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/regmap.h> |
16 | |
17 | #include "st_lsm6dsx.h" |
18 | |
19 | static const struct regmap_config st_lsm6dsx_i2c_regmap_config = { |
20 | .reg_bits = 8, |
21 | .val_bits = 8, |
22 | }; |
23 | |
24 | static int st_lsm6dsx_i2c_probe(struct i2c_client *client) |
25 | { |
26 | int hw_id; |
27 | struct regmap *regmap; |
28 | |
29 | hw_id = (kernel_ulong_t)device_get_match_data(dev: &client->dev); |
30 | if (!hw_id) |
31 | hw_id = i2c_client_get_device_id(client)->driver_data; |
32 | if (!hw_id) |
33 | return -EINVAL; |
34 | |
35 | regmap = devm_regmap_init_i2c(client, &st_lsm6dsx_i2c_regmap_config); |
36 | if (IS_ERR(ptr: regmap)) { |
37 | dev_err(&client->dev, "Failed to register i2c regmap %ld\n" , PTR_ERR(regmap)); |
38 | return PTR_ERR(ptr: regmap); |
39 | } |
40 | |
41 | return st_lsm6dsx_probe(dev: &client->dev, irq: client->irq, hw_id, regmap); |
42 | } |
43 | |
44 | static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { |
45 | { |
46 | .compatible = "st,lsm6ds3" , |
47 | .data = (void *)ST_LSM6DS3_ID, |
48 | }, |
49 | { |
50 | .compatible = "st,lsm6ds3h" , |
51 | .data = (void *)ST_LSM6DS3H_ID, |
52 | }, |
53 | { |
54 | .compatible = "st,lsm6dsl" , |
55 | .data = (void *)ST_LSM6DSL_ID, |
56 | }, |
57 | { |
58 | .compatible = "st,lsm6dsm" , |
59 | .data = (void *)ST_LSM6DSM_ID, |
60 | }, |
61 | { |
62 | .compatible = "st,ism330dlc" , |
63 | .data = (void *)ST_ISM330DLC_ID, |
64 | }, |
65 | { |
66 | .compatible = "st,lsm6dso" , |
67 | .data = (void *)ST_LSM6DSO_ID, |
68 | }, |
69 | { |
70 | .compatible = "st,asm330lhh" , |
71 | .data = (void *)ST_ASM330LHH_ID, |
72 | }, |
73 | { |
74 | .compatible = "st,lsm6dsox" , |
75 | .data = (void *)ST_LSM6DSOX_ID, |
76 | }, |
77 | { |
78 | .compatible = "st,lsm6dsr" , |
79 | .data = (void *)ST_LSM6DSR_ID, |
80 | }, |
81 | { |
82 | .compatible = "st,lsm6ds3tr-c" , |
83 | .data = (void *)ST_LSM6DS3TRC_ID, |
84 | }, |
85 | { |
86 | .compatible = "st,ism330dhcx" , |
87 | .data = (void *)ST_ISM330DHCX_ID, |
88 | }, |
89 | { |
90 | .compatible = "st,lsm9ds1-imu" , |
91 | .data = (void *)ST_LSM9DS1_ID, |
92 | }, |
93 | { |
94 | .compatible = "st,lsm6ds0" , |
95 | .data = (void *)ST_LSM6DS0_ID, |
96 | }, |
97 | { |
98 | .compatible = "st,lsm6dsrx" , |
99 | .data = (void *)ST_LSM6DSRX_ID, |
100 | }, |
101 | { |
102 | .compatible = "st,lsm6dst" , |
103 | .data = (void *)ST_LSM6DST_ID, |
104 | }, |
105 | { |
106 | .compatible = "st,lsm6dsop" , |
107 | .data = (void *)ST_LSM6DSOP_ID, |
108 | }, |
109 | { |
110 | .compatible = "st,asm330lhhx" , |
111 | .data = (void *)ST_ASM330LHHX_ID, |
112 | }, |
113 | { |
114 | .compatible = "st,lsm6dstx" , |
115 | .data = (void *)ST_LSM6DSTX_ID, |
116 | }, |
117 | { |
118 | .compatible = "st,lsm6dsv" , |
119 | .data = (void *)ST_LSM6DSV_ID, |
120 | }, |
121 | { |
122 | .compatible = "st,lsm6dsv16x" , |
123 | .data = (void *)ST_LSM6DSV16X_ID, |
124 | }, |
125 | { |
126 | .compatible = "st,lsm6dso16is" , |
127 | .data = (void *)ST_LSM6DSO16IS_ID, |
128 | }, |
129 | { |
130 | .compatible = "st,ism330is" , |
131 | .data = (void *)ST_ISM330IS_ID, |
132 | }, |
133 | { |
134 | .compatible = "st,asm330lhb" , |
135 | .data = (void *)ST_ASM330LHB_ID, |
136 | }, |
137 | { |
138 | .compatible = "st,asm330lhhxg1" , |
139 | .data = (void *)ST_ASM330LHHXG1_ID, |
140 | }, |
141 | {}, |
142 | }; |
143 | MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); |
144 | |
145 | static const struct acpi_device_id st_lsm6dsx_i2c_acpi_match[] = { |
146 | { "SMO8B30" , ST_LSM6DS3TRC_ID, }, |
147 | {} |
148 | }; |
149 | MODULE_DEVICE_TABLE(acpi, st_lsm6dsx_i2c_acpi_match); |
150 | |
151 | static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { |
152 | { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID }, |
153 | { ST_LSM6DS3H_DEV_NAME, ST_LSM6DS3H_ID }, |
154 | { ST_LSM6DSL_DEV_NAME, ST_LSM6DSL_ID }, |
155 | { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID }, |
156 | { ST_ISM330DLC_DEV_NAME, ST_ISM330DLC_ID }, |
157 | { ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID }, |
158 | { ST_ASM330LHH_DEV_NAME, ST_ASM330LHH_ID }, |
159 | { ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID }, |
160 | { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID }, |
161 | { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID }, |
162 | { ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID }, |
163 | { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID }, |
164 | { ST_LSM6DS0_DEV_NAME, ST_LSM6DS0_ID }, |
165 | { ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID }, |
166 | { ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID }, |
167 | { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, |
168 | { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, |
169 | { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, |
170 | { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, |
171 | { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, |
172 | { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, |
173 | { ST_ISM330IS_DEV_NAME, ST_ISM330IS_ID }, |
174 | { ST_ASM330LHB_DEV_NAME, ST_ASM330LHB_ID }, |
175 | { ST_ASM330LHHXG1_DEV_NAME, ST_ASM330LHHXG1_ID }, |
176 | {}, |
177 | }; |
178 | MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); |
179 | |
180 | static struct i2c_driver st_lsm6dsx_driver = { |
181 | .driver = { |
182 | .name = "st_lsm6dsx_i2c" , |
183 | .pm = pm_sleep_ptr(&st_lsm6dsx_pm_ops), |
184 | .of_match_table = st_lsm6dsx_i2c_of_match, |
185 | .acpi_match_table = st_lsm6dsx_i2c_acpi_match, |
186 | }, |
187 | .probe = st_lsm6dsx_i2c_probe, |
188 | .id_table = st_lsm6dsx_i2c_id_table, |
189 | }; |
190 | module_i2c_driver(st_lsm6dsx_driver); |
191 | |
192 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>" ); |
193 | MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>" ); |
194 | MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx i2c driver" ); |
195 | MODULE_LICENSE("GPL v2" ); |
196 | MODULE_IMPORT_NS(IIO_LSM6DSX); |
197 | |